diff --git a/.bowerrc b/.bowerrc deleted file mode 100644 index c2587b247fc..00000000000 --- a/.bowerrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "directory": "./static/bower_components" -} diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000000..4bb1e696f5a --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,14 @@ +module.exports = { + "plugins": [ ], + "extends": [ + "eslint:recommended" + ], + "parser": "babel-eslint", + "env": { + "browser": true, + "commonjs": true, + "es6": true, + "node": true, + "jquery": true + } + }; \ No newline at end of file diff --git a/.jsbeautifyrc b/.jsbeautifyrc new file mode 100644 index 00000000000..1c15d3872ce --- /dev/null +++ b/.jsbeautifyrc @@ -0,0 +1,16 @@ +{ + "indent_size": 2 + , "indent_char": " " + , "comma_first": true + , "keep-array-indentation": true + , "space_after_named_function": true + , "space_after_anon_function": true + , "end_with_newline": true + , "brace_style": "collapse,preserve-inline" + , "space_in_brace": true + , "space-in-paren": false + , "break-chained-methods": false + , "max-preserve-newlines": 2 + , "space-after-anon-function": false + , "indent-empty-lines": false +} diff --git a/.nvmrc b/.nvmrc index c6b7980b681..89da89da65c 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -8.x +10.16.0 \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 421eae39990..724fb96b659 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,24 +1,32 @@ -language: node_js -node_js: - - "10" - - "8" -os: - - osx -before_install: - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi - # https://github.com/Homebrew/homebrew-core/issues/26358 - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew unlink python; fi - # "brew install" can succeed but return 1 if it has "caveats". - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install mongodb || true; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew services start mongodb; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install docker || true; fi +sudo: required +dist: xenial + +node_js-steps: &node_js-steps + language: node_js + before_install: + - if [[ `npm --version` != "6.4.1" ]]; then npm install -g npm@latest; npm --version; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi + # https://github.com/Homebrew/homebrew-core/issues/26358 + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew unlink python; fi + # "brew install" can succeed but return 1 if it has "caveats". + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install mongodb || true; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew services start mongodb; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install docker || true; fi + script: make travis + after_success: + - nvm version + - if [[ ! -z "$DOCKER_USER" ]]; then docker login -u ${DOCKER_USER} -p ${DOCKER_PASS} && git checkout -- . && git clean -fd . && make docker_release; fi + after_script: make report + services: + - mongodb + - docker matrix: - fast_finish: true -services: - - mongodb - - docker -script: make travis -after_success: - - nvm version - - if [[ ! -z "$DOCKER_USER" ]]; then docker login -u ${DOCKER_USER} -p ${DOCKER_PASS} && git checkout -- . && git clean -fd . && make docker_release; fi -after_script: make report + allow_failures: + node_js: "node" + include: + - node_js: "8" + <<: *node_js-steps + - node_js: "10" + <<: *node_js-steps + - node_js: "node" # Latest Node is not supported, and recommend, but we'll test it to know incompatibility issues + <<: *node_js-steps diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4e248b4f963..ede1c7e88c8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,11 +3,12 @@ **Table of Contents** - [Contributing to cgm-remote-monitor](#contributing-to-cgm-remote-monitor) - - [Design](#design) + - [Design & new features](#design--new-features) - [Develop on `dev`](#develop-on-dev) - [Style Guide](#style-guide) - [Create a prototype](#create-a-prototype) - [Submit a pull request](#submit-a-pull-request) + - [Bug fixing](#bug-fixing) - [Comments and issues](#comments-and-issues) - [Co-ordination](#co-ordination) - [Other Dev Tips](#other-dev-tips) @@ -19,7 +20,6 @@ - # Contributing to cgm-remote-monitor [![Build Status][build-img]][build-url] @@ -41,11 +41,17 @@ [waffle]: https://waffle.io/nightscout/cgm-remote-monitor [progress-img]: https://badge.waffle.io/nightscout/cgm-remote-monitor.svg?label=in+progress&title=In+Progress -## Design & new features +## Installation for development -If you intend to add a new feature, please allow the community to participate in the design process by creating an issue to discuss your design. For new features, the issue should describe what use cases the new feature intends to solve, or which existing use cases are being improved. +Nightscout is a Node.js application. The basic installation of the software for local purposes is: -Note Nighscout has a plugin architecture for adding new features. We expect most code for new features live inside a Plugin, so the code retains a clear separation of concerns. If the Plugin API doesn't implement all features you need to implement your feature, please discuss with us on adding those features to the API. Note new features should under almost no circumstances require changes to the existing plugins. +1. Clone the software to your local machine using git +2. Install Node from https://nodejs.org/en/download/ +2. Use `npm` to install Nightscout dependencies by invokin `npm install` in the project directory. Note the + dependency installation has to be done usign a non-root user - _do not use root_ for development and hosting + the software! +3. Get a Mongo database by either installing Mongo locally, or get a free cloud account from mLab or Mongodb Atlas. +4. Configure nightscout by copying `my.env.template` to `my.env` and run it - see the next chapter in the instructions ## Develop on `dev` @@ -53,6 +59,29 @@ We develop on the `dev` branch. All new pull requests should be targeted to `dev You can get the dev branch checked out using `git checkout dev`. +Once checked out, install the dependencies using `npm install`, then copy the included `my.env.template`file to `my.env` and edit the file to include your settings (like the Mongo URL). Leave the `NODE_ENV=development` line intact. Once set, run the site using `npm run dev`. This will start Nigthscout in the development mode, with different code packaging rules and automatic restarting of the server using nodemon, when you save changed files on disk. The client also hot-reloads new code in, but it's recommended to reload the the website after changes due to the way the plugin sandbox works. + +Note the template sets `INSECURE_USE_HTTP` to `true` to enable the site to work over HTTP in local development. + +If you want to additionaly test the site in production mode, create a file called `my.prod.env` that's a copy of the dev file but with `NODE_ENV=production` and start the site using `npm run prod`. + +## REST API + +Nightscout implements a REST API for data syncronization. The API is documented using Swagger. To access the documentation +for the API, run Nightscout locally and load the documentation from /api-docs (or read the associated swagger.json and swagger.yaml +files locally). + +Note all dates used to access the API and dates stored in the objects are expected to comply with the ISO-8601 format and +be deserializable by the Javascript Date class. Of note here is the dates can contain a plus sign which has a special meaning in +URL encoding, so when issuing requests that place dates to the URL, take special care to ensure the data is properly URL +encoded. + +## Design & new features + +If you intend to add a new feature, please allow the community to participate in the design process by creating an issue to discuss your design. For new features, the issue should describe what use cases the new feature intends to solve, or which existing use cases are being improved. + +Note Nighscout has a plugin architecture for adding new features. We expect most code for new features live inside a Plugin, so the code retains a clear separation of concerns. If the Plugin API doesn't implement all features you need to implement your feature, please discuss with us on adding those features to the API. Note new features should under almost no circumstances require changes to the existing plugins. + ## Style Guide Some simple rules that will make it easier to maintain our codebase: @@ -76,15 +105,7 @@ If in doubt, format your code with `js-beautify --indent-size 2 --comma-first - ## Create a prototype -<<<<<<< HEAD -Fork cgm-remote-monitor and create a branch. -You can create a branch using `git checkout -b wip/add-my-widget`. -This creates a new branch called `wip/add-my-widget`. The `wip` -stands for work in progress and is a common prefix so that we know -what to expect when reviewing many branches. -======= Fork cgm-remote-monitor and create a branch. You can create a branch using `git checkout -b wip/add-my-widget`. This creates a new branch called `wip/add-my-widget`. The `wip` stands for work in progress and is a common prefix so that when know what to expect when reviewing many branches. ->>>>>>> master ## Submit a pull request @@ -95,8 +116,6 @@ This can be done by checking your code `git commit -avm 'my improvements are her Now that the commits are available on github, you can click on the compare buttons on your fork to create a pull request. Make sure to select [Nightscout's `dev` branch](https://github.com/nightscout/cgm-remote-monitor/tree/dev). We assume all new Pull Requests are at least smoke tested by the author and all code in the PR actually works. -<<<<<<< HEAD - Please include a description of what the features do and rationalize why the changes are needed. If you add any new NPM module dependencies, you have to rationalize why there are needed - we prefer pull requests that reduce dependencies, not add them. @@ -106,26 +125,13 @@ When adding new features that add confugration options, please ensure the `READM ## Bug fixing If you've fixed a bug, please consider adding a unit test to the `/tests` folder that reproduces the original bug without the change. + Try to identify the root cause of the issue and fix the issue. Pull requests that simply add null checks to hide issues are unlikely to be accepted. This can be done by committing your code `git commit -avm 'my improvements are here'`, and pushing it to the branch you created on your own fork. This will probably look something like `git push -u origin wip/add-my-widget`. -======= - -Please include a description of what the features do and rationalize why the changes are needed. - -If you add any new NPM module dependencies, you have to rationalize why there are needed - we prefer pull requests that reduce dependencies, not add them. - -When adding new features that add confugration options, please ensure the `README` document is amended with information on the new configuration. - -## Bug fixing - -If you've fixed a bug, please consider adding a unit test to the `/tests` folder that reproduces the original bug without the change. - -Try to identify the root cause of the issue and fix the issue. Pull requests that simply add null checks to hide issues are unlikely to be accepted. ->>>>>>> master Please include instructions how to test the changes. @@ -137,25 +143,11 @@ We encourage liberal use of the comments, including images where appropriate. Most cgm-remote-monitor hackers use github's ticketing system, along with Facebook cgm-in-the-cloud, and gitter. -<<<<<<< HEAD -We use [git-flow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow), with `master` as our production, stable branch, and -`dev` is used to queue changes for upcoming releases. Everything else is -done on branches, hopefully with names that indicate what to expect. - -Once `dev` has been reviewed and people feel it's time to release, we -follow the git-flow release process, which creates a new tag and bumps -the version correctly. See [sem-ver](https://semver.org/) for versioning strategy. - -Every commit is tested by Travis CI. We encourage adding tests to -validate your design. We encourage discussing your use cases to help -everyone get a better understanding of your design. -======= We use git-flow, with `master` as our production, stable branch, and `dev` is used to queue up for upcoming releases. Everything else is done on branches, hopefully with names that indicate what to expect. Once `dev` has been reviewed and people feel it's time to release, we follow the git-flow release process, which creates a new tag and bumps the version correctly. See sem-ver for versioning strategy. Every commit is tested by travis. We encourage adding tests to validate your design. We encourage discussing your use cases to help everyone get a better understanding of your design. ->>>>>>> master ## Other Dev Tips @@ -177,8 +169,10 @@ Also if you can't code, it's possible to contribute by improving the documentati [@apanasef]: https://github.com/apanasef [@bewest]: https://github.com/bewest [@danamlewis]: https://github.com/danamlewis +[@diabetlum]: https://github.com/diabetlum [@herzogmedia]: https://github.com/herzogmedia [@jamieowendexcom ]: https://github.com/jamieowendexcom +[@janrpn]: https://github.com/janrpn [@jasoncalabrese]: https://github.com/jasoncalabrese [@jizhongwen]: https://github.com/jizhongwen [@jpcunningh]: https://github.com/jpcunningh @@ -197,6 +191,7 @@ Also if you can't code, it's possible to contribute by improving the documentati [@tynbendad]: https://github.com/tynbendad [@unsoluble]: https://github.com/unsoluble [@viderehh]: https://github.com/viderehh +[@OpossumGit]: https://github.com/OpossumGit | Contribution area | List of contributors | | ------------------------------------- | ---------------------------------- | @@ -255,14 +250,14 @@ Languages with less than 90% coverage will be removed in a future Nightscout ver | Български (`bg`) |Please volunteer| OK | | Čeština (`cs`) |Please volunteer|OK | | Deutsch (`de`) |[@viderehh] [@herzogmedia] |OK | -| Dansk (`dk`) |Please volunteer|OK | +| Dansk (`dk`) | [@janrpn] |OK | | Ελληνικά `(el`)|Please volunteer|Needs attention: 68.5%| | English (`en`)|Please volunteer|OK| | Español (`es`) |Please volunteer|OK| | Suomi (`fi`)|[@sulkaharo] |OK| | Français (`fr`)|Please volunteer|OK| | עברית (`he`)|Please volunteer|OK| -| Hrvatski (`hr`)|Please volunteer|Needs attention: 47.8%| +| Hrvatski (`hr`)|[@OpossumGit]|Needs attention: 47.8% - committed 100% to dev| | Italiano (`it`)|Please volunteer|OK| | 日本語 (`ja`)|[@LuminaryXion]|Working on this| | 한국어 (`ko`)|Please volunteer|Needs attention: 80.6%| @@ -274,6 +269,7 @@ Languages with less than 90% coverage will be removed in a future Nightscout ver | Русский (`ru`)|[@apanasef]|OK| | Slovenčina (`sk`)|Please volunteer|OK| | Svenska (`sv`)|Please volunteer|OK| +| Türkçe (`tr`)|[@diabetlum]|OK| | 中文(简体) (`zh_cn`) | [@jizhongwen]|OK| | 中文(繁體) (`zh_tw`) | [@jizhongwen]|Needs attention: 25.0% | 日本語 (`ja_jp`) | [@LuminaryXion]| @@ -284,5 +280,5 @@ Languages with less than 90% coverage will be removed in a future Nightscout ver | ------------------------------------- | -------------------- | | All active developers: | [@jasoncalabrese] [@jpcunningh] [@jweismann] [@komarserjio] [@mdomox] [@MilosKozak] [@PieterGit] [@rickfriele] [@sulkaharo] | All active testers/documentors: | [@danamlewis] [@jamieowendexcom] [@mcdafydd] [@oteroos] [@rarneson] [@tynbendad] [@unsoluble] -| All active translators: | [@apanasef] [@jizhongwen] [@viderehh] [@herzogmedia] [@LuminaryXion] +| All active translators: | [@apanasef] [@jizhongwen] [@viderehh] [@herzogmedia] [@LuminaryXion] [@OpossumGit] diff --git a/Dockerfile.example b/Dockerfile.example index d4c13c0ecd9..89a43f43c15 100644 --- a/Dockerfile.example +++ b/Dockerfile.example @@ -1,17 +1,17 @@ -FROM node:8.9.1 +FROM node:10-alpine MAINTAINER Nightscout Contributors -RUN apt-get update && \ - apt-get -y dist-upgrade - RUN mkdir -p /opt/app ADD . /opt/app WORKDIR /opt/app +RUN chown -R node:node /opt/app +USER node RUN npm install && \ npm run postinstall && \ - npm run env + npm run env && \ + npm audit fix EXPOSE 1337 diff --git a/README.md b/README.md index 2b39524b4b8..fd85b987107 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,11 @@ Community maintained fork of the **Table of Contents** - [Install](#install) + - [Supported configurations:](#supported-configurations) + - [Minimum browser requirements for viewing the site:](#minimum-browser-requirements-for-viewing-the-site) + - [Windows installation software requirements:](#windows-installation-software-requirements) + - [Installation notes for users with nginx or Apache reverse proxy for SSL/TLS offloading:](#installation-notes-for-users-with-nginx-or-apache-reverse-proxy-for-ssltls-offloading) + - [Installation notes for Microsoft Azure, Windows:](#installation-notes-for-microsoft-azure-windows) - [Usage](#usage) - [Updating my version?](#updating-my-version) - [What is my mongo string?](#what-is-my-mongo-string) @@ -60,7 +65,7 @@ Community maintained fork of the - [Alarms](#alarms) - [Core](#core) - [Predefined values for your browser settings (optional)](#predefined-values-for-your-browser-settings-optional) - - [Views](#views) + - [Predefined values for your server settings (optional)](#predefined-values-for-your-server-settings-optional) - [Plugins](#plugins) - [Default Plugins](#default-plugins) - [`delta` (BG Delta)](#delta-bg-delta) @@ -91,6 +96,7 @@ Community maintained fork of the - [`pump` (Pump Monitoring)](#pump-pump-monitoring) - [`openaps` (OpenAPS)](#openaps-openaps) - [`loop` (Loop)](#loop-loop) + - [`override` (Override Mode)](#override-override-mode) - [`xdrip-js` (xDrip-js)](#xdrip-js-xdrip-js) - [`alexa` (Amazon Alexa)](#alexa-amazon-alexa) - [`speech` (Speech)](#speech-speech) @@ -108,7 +114,7 @@ Community maintained fork of the # Install -Supported configurations: +## Supported configurations: If you plan to use Nightscout, we recommend using [Heroku](http://www.nightscout.info/wiki/welcome/set-up-nightscout-using-heroku), as Nightscout can reach the usage limits of the free Azure plan and cause it to shut down for hours or days. If you end up needing a paid tier, the $7/mo Heroku plan is also much cheaper than the first paid tier of Azure. Currently, the only added benefit to choosing the $7/mo Heroku plan vs the free Heroku plan is a section showing site use metrics for performance (such as response time). This has limited benefit to the average Nightscout user. In short, Heroku is the free and best option for Nightscout hosting. @@ -118,20 +124,20 @@ If you plan to use Nightscout, we recommend using [Heroku](http://www.nightscout - Linux based install (Debian, Ubuntu, Raspbian) install with own Node.JS and MongoDB install (see software requirements below) - Windows based install with own Node.JS and MongoDB install (see software requirements below) -Minimum browser requirements for viewing the site: +## Minimum browser requirements for viewing the site: - Android 4 - Chrome 68 -- Edge 15 +- Edge 17 - Firefox 61 -- Internet Explorer: not supported, ie8 is known not to work -- iOS 9 -- Safari 11 -- Opera: 54 +- Internet Explorer: not supported +- iOS 11 +- Opera 54 +- Safari 10 (macOS 10.12) -Windows installation software requirements: +## Windows installation software requirements: -- [Node.js](http://nodejs.org/) Latest Node 8 LTS (Node 8.15.0 or later) or Node 10 LTS (Node 10.15.1 or later; Node 10.14.1 works for Azure). Use [Install instructions for Node](https://nodejs.org/en/download/package-manager/) or use `setup.sh`) +- [Node.js](http://nodejs.org/) Latest Node 8 LTS (Node 8.15.1 or later) or Node 10 LTS (Node 10.16.0 or later; Node 10.15.2 works for Azure). Node versions that do not have the latest security patches will not work. Use [Install instructions for Node](https://nodejs.org/en/download/package-manager/) or use `setup.sh`) - [MongoDB](https://www.mongodb.com/download-center?jmp=nav#community) 3.x or later. MongoDB 2.4 is only supported for Raspberry Pi. As a non-root user clone this repo then install dependencies into the root of the project: @@ -140,16 +146,27 @@ As a non-root user clone this repo then install dependencies into the root of th $ npm install ``` -Installation notes for Microsoft Azure, Windows: +## Installation notes for users with nginx or Apache reverse proxy for SSL/TLS offloading: -- If deploying the software to Microsoft Azure, you must set ** in the app settings for *WEBSITE_NODE_DEFAULT_VERSION* and *SCM_COMMAND_IDLE_TIMEOUT* **before** you deploy the latest Nightscout or the site deployment will likely fail. Other hosting environments do not require this setting. Please use: +- Your site redirects insecure connections to `https` by default. If you use a reverse proxy like nginx or Apache to handle the connection security for you, make sure it sets the `X-Forwarded-Proto` header. Otherwise nightscout will be unable to know if it was called through a secure connection and will try to redirect you to the https version. If you're unable to set this Header, you can change the `INSECURE_USE_HTTP` setting in nightscout to true in order to allow insecure connections without being redirected. +- In case you use a proxy. Do not use an external network interfaces for hosting Nightscout. Make sure the unsecure port is not available from a remote network connection +- HTTP Strict Transport Security (HSTS) headers are enabled by default, use settings `SECURE_HSTS_HEADER` and `SECURE_HSTS_HEADER_*` +- See [Predefined values for your server settings](#predefined-values-for-your-server-settings-optional) for more details + +## Installation notes for Microsoft Azure, Windows: + +- If deploying the software to Microsoft Azure, you must set ** in the app settings for *WEBSITE_NODE_DEFAULT_VERSION* and *SCM_COMMAND_IDLE_TIMEOUT* **before** you deploy the latest Nightscout or the site deployment will likely fail. Other hosting environments do not require this setting. Additionally, if using the Azure free hosting tier, the installation might fail due to resource constraints imposed by Azure on the free hosting. Please set the following settings to the environment in Azure: ``` -WEBSITE_NODE_DEFAULT_VERSION=10.14.1 +WEBSITE_NODE_DEFAULT_VERSION=10.15.2 SCM_COMMAND_IDLE_TIMEOUT=300 ``` - See [install MongoDB, Node.js, and Nightscouton a single Windows system](https://github.com/jaylagorio/Nightscout-on-Windows-Server). if you want to host your Nightscout outside of the cloud. Although the instructions are intended for Windows Server the procedure is compatible with client versions of Windows such as Windows 7 and Windows 10. - If you deploy to Windows and want to develop or test you need to install [Cygwin](https://www.cygwin.com/) (use [setup-x86_64.exe](https://www.cygwin.com/setup-x86_64.exe) and make sure to install `build-essential` package. Test your configuration by executing `make` and check if all tests are ok. +# Development + +Wanna help with development, or just see how Nigthscout works? Great! See [CONTRIBUTING.md](CONTRIBUTING.md) for development related documentation. + # Usage The data being uploaded from the server to the client is from a @@ -174,7 +191,6 @@ mongo string. You can copy and paste the text in the gray box into your Use the [autoconfigure tool][autoconfigure] to sync an uploader to your config. - ## Nightscout API The Nightscout API enables direct access to your DData without the need for direct Mongo access. @@ -184,6 +200,8 @@ The server status and settings are available from `/api/v1/status.json`. By default the `/entries` and `/treatments` APIs limit results to the the most recent 10 values from the last 2 days. You can get many more results, by using the `count`, `date`, `dateString`, and `created_at` parameters, depending on the type of data you're looking for. +Once you've installed Nightscout, you can access API documentation by loading `/api-docs` URL in your instance. + #### Example Queries (replace `http://localhost:1337` with your base url, YOUR-SITE) @@ -197,7 +215,6 @@ You can get many more results, by using the `count`, `date`, `dateString`, and ` The API is Swagger enabled, so you can generate client code to make working with the API easy. To learn more about the Nightscout API, visit https://YOUR-SITE.com/api-docs.html or review [swagger.yaml](swagger.yaml). - ## Environment `VARIABLE` (default) - description @@ -219,7 +236,6 @@ To learn more about the Nightscout API, visit https://YOUR-SITE.com/api-docs.htm * `IMPORT_CONFIG` - Used to import settings and extended settings from a url such as a gist. Structure of file should be something like: `{"settings": {"theme": "colors"}, "extendedSettings": {"upbat": {"enableAlerts": true}}}` * `TREATMENTS_AUTH` (`on`) - possible values `on` or `off`. Deprecated, if set to `off` the `careportal` role will be added to `AUTH_DEFAULT_ROLES` - ### Alarms These alarm setting effect all delivery methods (browser, pushover, maker, etc), some settings can be overridden per client (web browser) @@ -256,6 +272,7 @@ To learn more about the Nightscout API, visit https://YOUR-SITE.com/api-docs.htm * `SSL_CA` - Path to your ssl ca file, so that ssl(https) can be enabled directly in node.js. If using Let's Encrypt, make this variable the path to chain.pem file (chain). * `HEARTBEAT` (`60`) - Number of seconds to wait in between database checks * `DEBUG_MINIFY` (`true`) - Debug option, setting to `false` will disable bundle minification to help tracking down error and speed up development + * `DE_NORMALIZE_DATES`(`true`) - The Nightscout REST API normalizes all entered dates to UTC zone. Some Nightscout clients have broken date deserialization logic and expect to received back dates in zoned formats. Setting this variable to `true` causes the REST API to serialize dates sent to Nightscout in zoned format back to zoned format when served to clients over REST. ### Predefined values for your browser settings (optional) @@ -279,18 +296,20 @@ To learn more about the Nightscout API, visit https://YOUR-SITE.com/api-docs.htm * `EDIT_MODE` (`on`) - possible values `on` or `off`. Enable or disable icon allowing enter treatments edit mode ### Predefined values for your server settings (optional) - * `INSECURE_USE_HTTP` (`false`) - Redirect http url's to https. Possible values `false`, or `true`. + * `INSECURE_USE_HTTP` (`false`) - Redirect unsafe http traffic to https. Possible values `false`, or `true`. Your site redirects to `https` by default. If you don't want that from Nightscout, but want to implement that with a Nginx or Apache proxy, set `INSECURE_USE_HTTP` to `true`. Note: This will allow (unsafe) http traffic to your Nightscout instance and is not recommended. * `SECURE_HSTS_HEADER` (`true`) - Add HTTP Strict Transport Security (HSTS) header. Possible values `false`, or `true`. * `SECURE_HSTS_HEADER_INCLUDESUBDOMAINS` (`false`) - includeSubdomains options for HSTS. Possible values `false`, or `true`. * `SECURE_HSTS_HEADER_PRELOAD` (`false`) - ask for preload in browsers for HSTS. Possible values `false`, or `true`. - * `SECURE_CSP` (`false`) - Add Content Security Policy headers. Possible values `false`, or `true`. Currently Nightscout is not yet compatible with CSP. - - ### Views + * `SECURE_CSP` (`false`) - Add Content Security Policy headers. Possible values `false`, or `true`. + * `SECURE_CSP_REPORT_ONLY` (`false`) - If set to `true` allows to experiment with policies by monitoring (but not enforcing) their effects. Possible values `false`, or `true`. + +### Views - There are a few alternate web views available that display a simplified BG stream. Append any of these to your Nightscout URL: - * `/clock.html` - Shows current BG. Grey text on a black background. - * `/bgclock.html` - Shows current BG, trend arrow, and time of day. Grey text on a black background. - * `/clock-color.html` - Shows current BG and trend arrow. White text on a background that changes color to indicate current BG threshold (green = in range; blue = below range; yellow = above range; red = urgent below/above). + There are a few alternate web views available from the main menu that display a simplified BG stream. (If you launch one of these in a fullscreen view in iOS, you can use a left-to-right swipe gesture to exit the view.) + * `Clock` - Shows current BG, trend arrow, and time of day. Grey text on a black background. + * `Color` - Shows current BG and trend arrow. White text on a background that changes color to indicate current BG threshold (green = in range; blue = below range; yellow = above range; red = urgent below/above). + * `Simple` - Shows current BG. Grey text on a black background. + * Optional configuration: set `SHOW_CLOCK_CLOSEBUTTON` to `false` to never show the small X button in clock views. For bookmarking a clock view without the close box but have it appear when navigating to a clock from the Nightscout menu, don't change the settng, but remove the `showClockClosebutton=true` parameter from the clock view URL. ### Plugins @@ -434,6 +453,7 @@ To learn more about the Nightscout API, visit https://YOUR-SITE.com/api-docs.htm * `MMCONNECT_SGV_LIMIT` (`24`) - Maximum number of recent sensor glucose values to send to Nightscout on each request. * `MMCONNECT_VERBOSE` - Set this to "true" to log CareLink request information to the console. * `MMCONNECT_STORE_RAW_DATA` - Set this to "true" to store raw data returned from CareLink as `type: "carelink_raw"` database entries (useful for development). + * `MMCONNECT_SERVER` - Set this to `EU` if you're using the European Medtronic services ##### `pump` (Pump Monitoring) Generic Pump Monitoring for OpenAPS, MiniMed Connect, RileyLink, t:slim, with more on the way @@ -459,6 +479,13 @@ To learn more about the Nightscout API, visit https://YOUR-SITE.com/api-docs.htm * `OPENAPS_URGENT` (`60`) - The number of minutes since the last loop that needs to be exceed before an urgent alarm is triggered * `OPENAPS_FIELDS` (`status-symbol status-label iob meal-assist rssi`) - The fields to display by default. Any of the following fields: `status-symbol`, `status-label`, `iob`, `meal-assist`, `freq`, and `rssi` * `OPENAPS_RETRO_FIELDS` (`status-symbol status-label iob meal-assist rssi`) - The fields to display in retro mode. Any of the above fields. + * `OPENAPS_PRED_IOB_COLOR` (`#1e88e5`) - The color to use for IOB prediction lines. Colors can be in either `#RRGGBB` or `#RRGGBBAA` format. + * `OPENAPS_PRED_COB_COLOR` (`#FB8C00FF`) - The color to use for COB prediction lines. Same format as above. + * `OPENAPS_PRED_ACOB_COLOR` (`#FB8C0080`) - The color to use for ACOB prediction lines. Same format as above. + * `OPENAPS_PRED_ZT_COLOR` (`#00d2d2`) - The color to use for ZT prediction lines. Same format as above. + * `OPENAPS_PRED_UAM_COLOR` (`#c9bd60`) - The color to use for UAM prediction lines. Same format as above. + * `OPENAPS_COLOR_PREDICTION_LINES` (`true`) - Enables / disables the colored lines vs the classic purple color. + Also see [Pushover](#pushover) and [IFTTT Maker](#ifttt-maker). @@ -470,6 +497,10 @@ To learn more about the Nightscout API, visit https://YOUR-SITE.com/api-docs.htm * `LOOP_URGENT` (`60`) - The number of minutes since the last loop that needs to be exceeded before an urgent alarm is triggered * Add `loop` to `SHOW_FORECAST` to show forecasted BG. +##### `override` (Override Mode) + Additional monitoring for DIY automated insulin delivery systems to display real-time overrides such as Eating Soon or Exercise Mode: + * Requires `DEVICESTATUS_ADVANCED="true"` to be set + ##### `xdrip-js` (xDrip-js) Integrated xDrip-js monitoring, uses these extended settings: * Requires `DEVICESTATUS_ADVANCED="true"` to be set @@ -478,7 +509,7 @@ To learn more about the Nightscout API, visit https://YOUR-SITE.com/api-docs.htm * `XDRIP-JS_WARN_BAT_V` (`300`) - The voltage of either transmitter battery, a warning will be triggered when dropping below this threshold. ##### `alexa` (Amazon Alexa) - Integration with Amazon Alexa, [detailed setup instructions](lib/plugins/alexa-plugin.md) + Integration with Amazon Alexa, [detailed setup instructions](docs/plugins/alexa-plugin.md) ##### `speech` (Speech) Speech synthesis plugin. When enabled, speaks out the blood glucose values, IOB and alarms. Note you have to set the LANGUAGE setting on the server to get all translated alarms. diff --git a/app.js b/app.js index f6143f1834b..05f1d8ff694 100644 --- a/app.js +++ b/app.js @@ -1,243 +1,293 @@ 'use strict'; -var _get = require('lodash/get'); -var express = require('express'); -var compression = require('compression'); -var bodyParser = require('body-parser'); -var prettyjson = require('prettyjson'); - -var path = require('path'); -var fs = require('fs'); - -function create(env, ctx) { - var app = express(); - var appInfo = env.name + ' ' + env.version; - app.set('title', appInfo); - app.enable('trust proxy'); // Allows req.secure test on heroku https connections. - var insecureUseHttp = env.insecureUseHttp; - var secureHstsHeader = env.secureHstsHeader; - console.info('Security settings: INSECURE_USE_HTTP=',insecureUseHttp,', SECURE_HSTS_HEADER=',secureHstsHeader); - if (!insecureUseHttp) { - app.use((req, res, next) => { - if (req.header('x-forwarded-proto') !== 'https') - res.redirect(`https://${req.header('host')}${req.url}`); - else - next() - }) - if (secureHstsHeader) { // Add HSTS (HTTP Strict Transport Security) header - const helmet = require('helmet'); - var includeSubDomainsValue = env.secureHstsHeaderIncludeSubdomains; - var preloadValue = env.secureHstsHeaderPreload; - app.use(helmet({ - hsts: { - maxAge: 31536000, - includeSubDomains: includeSubDomainsValue, - preload: preloadValue - } - })) - if (env.secureCsp) { - app.use(helmet.contentSecurityPolicy({ //TODO make NS work without 'unsafe-inline' - directives: { - defaultSrc: ["'self'"], - styleSrc: ["'self'", 'https://fonts.googleapis.com/',"'unsafe-inline'"], - scriptSrc: ["'self'", "'unsafe-inline'"], - fontSrc: [ "'self'", 'https://fonts.gstatic.com/'] - } - })); - } +const _get = require('lodash/get'); +const express = require('express'); +const compression = require('compression'); +const bodyParser = require('body-parser'); + +const path = require('path'); +const fs = require('fs'); + +function create (env, ctx) { + var app = express(); + var appInfo = env.name + ' ' + env.version; + app.set('title', appInfo); + app.enable('trust proxy'); // Allows req.secure test on heroku https connections. + var insecureUseHttp = env.insecureUseHttp; + var secureHstsHeader = env.secureHstsHeader; + if (!insecureUseHttp) { + console.info('Redirecting http traffic to https because INSECURE_USE_HTTP=', insecureUseHttp); + app.use((req, res, next) => { + if (req.header('x-forwarded-proto') == 'https' || req.secure) { + next(); + } else { + res.redirect(307, `https://${req.header('host')}${req.url}`); + } + }) + if (secureHstsHeader) { // Add HSTS (HTTP Strict Transport Security) header + console.info('Enabled SECURE_HSTS_HEADER (HTTP Strict Transport Security)'); + const helmet = require('helmet'); + var includeSubDomainsValue = env.secureHstsHeaderIncludeSubdomains; + var preloadValue = env.secureHstsHeaderPreload; + app.use(helmet({ + hsts: { + maxAge: 31536000 + , includeSubDomains: includeSubDomainsValue + , preload: preloadValue } - } - - app.set('view engine', 'ejs'); - // this allows you to render .html files as templates in addition to .ejs - app.engine('html', require('ejs').renderFile); - app.engine('appcache', require('ejs').renderFile); - app.set("views", path.join(__dirname, "views/")); - - app.locals.cachebuster = fs.readFileSync(process.cwd() + '/tmp/cacheBusterToken').toString().trim(); - - if (ctx.bootErrors && ctx.bootErrors.length > 0) { - app.get('*', require('./lib/server/booterror')(ctx)); - return app; + , frameguard: false + })); + if (env.secureCsp) { + var secureCspReportOnly = env.secureCspReportOnly; + if (secureCspReportOnly) { + console.info('Enabled SECURE_CSP (Content Security Policy header). Not enforcing. Report only.'); + } else { + console.info('Enabled SECURE_CSP (Content Security Policy header). Enforcing.'); + } + app.use(helmet.contentSecurityPolicy({ //TODO make NS work without 'unsafe-inline' + directives: { + defaultSrc: ["'self'"] + , styleSrc: ["'self'", 'https://fonts.googleapis.com/', "'unsafe-inline'"] + , scriptSrc: ["'self'", "'unsafe-inline'"] + , fontSrc: ["'self'", 'https://fonts.gstatic.com/', 'data:'] + , imgSrc: ["'self'", 'data:'] + , objectSrc: ["'none'"], // Restricts , , and elements + reportUri: '/report-violation' + , frameAncestors: ["'none'"], // Clickjacking protection, using frame-ancestors + baseUri: ["'none'"], // Restricts use of the tag + formAction: ["'self'"], // Restricts where
contents may be submitted + } + , reportOnly: secureCspReportOnly + })); + app.use(helmet.referrerPolicy({ policy: 'no-referrer' })); + app.use(helmet.featurePolicy({ features: { payment: ["'none'"], } })); + app.use(bodyParser.json({ type: ['json', 'application/csp-report'] })) + app.post('/report-violation', (req, res) => { + if (req.body) { + console.log('CSP Violation: ', req.body) + } else { + console.log('CSP Violation: No data received!') + } + res.status(204).end() + }) + } } - - if (env.settings.isEnabled('cors')) { - var allowOrigin = _get(env, 'extendedSettings.cors.allowOrigin') || '*'; - console.info('Enabled CORS, allow-origin:', allowOrigin); - app.use(function allowCrossDomain(req, res, next) { - res.header('Access-Control-Allow-Origin', allowOrigin); - res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS'); - res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With'); - - // intercept OPTIONS method - if ('OPTIONS' === req.method) { - res.send(200); - } else { - next(); - } - }); + } else { + console.info('Security settings: INSECURE_USE_HTTP=', insecureUseHttp, ', SECURE_HSTS_HEADER=', secureHstsHeader); + } + + app.set('view engine', 'ejs'); + // this allows you to render .html files as templates in addition to .ejs + app.engine('html', require('ejs').renderFile); + app.engine('appcache', require('ejs').renderFile); + app.set("views", path.join(__dirname, "views/")); + + let cacheBuster = 'developmentMode'; + if (process.env.NODE_ENV !== 'development') { + cacheBuster = fs.readFileSync(process.cwd() + '/tmp/cacheBusterToken').toString().trim(); + } + app.locals.cachebuster = cacheBuster; + + if (ctx.bootErrors && ctx.bootErrors.length > 0) { + app.get('*', require('./lib/server/booterror')(ctx)); + return app; + } + + if (env.settings.isEnabled('cors')) { + var allowOrigin = _get(env, 'extendedSettings.cors.allowOrigin') || '*'; + console.info('Enabled CORS, allow-origin:', allowOrigin); + app.use(function allowCrossDomain (req, res, next) { + res.header('Access-Control-Allow-Origin', allowOrigin); + res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS'); + res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With'); + + // intercept OPTIONS method + if ('OPTIONS' === req.method) { + res.send(200); + } else { + next(); + } + }); + } + + /////////////////////////////////////////////////// + // api and json object variables + /////////////////////////////////////////////////// + var api = require('./lib/api/')(env, ctx); + var ddata = require('./lib/data/endpoints')(env, ctx); + + app.use(compression({ + filter: function shouldCompress (req, res) { + //TODO: return false here if we find a condition where we don't want to compress + // fallback to standard filter function + return compression.filter(req, res); } + })); - /////////////////////////////////////////////////// - // api and json object variables - /////////////////////////////////////////////////// - var api = require('./lib/api/')(env, ctx); - var ddata = require('./lib/data/endpoints')(env, ctx); - - app.use(compression({ - filter: function shouldCompress(req, res) { - //TODO: return false here if we find a condition where we don't want to compress - // fallback to standard filter function - return compression.filter(req, res); - } - })); + const clockviews = require('./lib/server/clocks.js')(env, ctx); + clockviews.setLocals(app.locals); - app.get("/", (req, res) => { - res.render("index.html", { - locals: app.locals - }); - }); + app.use("/clock", clockviews); - var appPages = { - "/clock-color.html":"clock-color.html", - "/admin":"adminindex.html", - "/profile":"profileindex.html", - "/food":"foodindex.html", - "/bgclock.html":"bgclock.html", - "/report":"reportindex.html", - "/translations":"translationsindex.html", - "/clock.html":"clock.html" - }; - - Object.keys(appPages).forEach(function(page) { - app.get(page, (req, res) => { - res.render(appPages[page], { - locals: app.locals - }); - }); - }); - - app.get("/appcache/*", (req, res) => { - res.render("nightscout.appcache", { - locals: app.locals - }); + app.get("/", (req, res) => { + res.render("index.html", { + locals: app.locals }); - - app.use('/api/v1', bodyParser({ - limit: 1048576 * 50 - }), api); - - app.use('/api/v2/properties', ctx.properties); - app.use('/api/v2/authorization', ctx.authorization.endpoints); - app.use('/api/v2/ddata', ddata); - - // pebble data - app.get('/pebble', ctx.pebble); - - // expose swagger.json - app.get('/swagger.json', function(req, res) { - res.sendFile(__dirname + '/swagger.json'); + }); + + var appPages = { + "/clock-color.html": "clock-color.html" + , "/admin": "adminindex.html" + , "/profile": "profileindex.html" + , "/food": "foodindex.html" + , "/bgclock.html": "bgclock.html" + , "/report": "reportindex.html" + , "/translations": "translationsindex.html" + , "/clock.html": "clock.html" + }; + + Object.keys(appPages).forEach(function(page) { + app.get(page, (req, res) => { + res.render(appPages[page], { + locals: app.locals + }); }); + }); -/* - if (env.settings.isEnabled('dumps')) { - var heapdump = require('heapdump'); - app.get('/api/v2/dumps/start', function(req, res) { - var path = new Date().toISOString() + '.heapsnapshot'; - path = path.replace(/:/g, '-'); - console.info('writing dump to', path); - heapdump.writeSnapshot(path); - res.send('wrote dump to ' + path); - }); - } -*/ - - //app.get('/package.json', software); - - // Allow static resources to be cached for week - var maxAge = 7 * 24 * 60 * 60 * 1000; - - if (process.env.NODE_ENV === 'development') { - maxAge = 10; - console.log('Development environment detected, setting static file cache age to 10 seconds'); - - app.get('/nightscout.appcache', function(req, res) { - res.sendStatus(404); - }); - } - - //TODO: JC - changed cache to 1 hour from 30d ays to bypass cache hell until we have a real solution - var staticFiles = express.static(env.static_files, { - maxAge: maxAge + app.get("/appcache/*", (req, res) => { + res.render("nightscout.appcache", { + locals: app.locals }); + }); + + app.use('/api/v1', bodyParser({ + limit: 1048576 * 50 + }), api); + + app.use('/api/v2/properties', ctx.properties); + app.use('/api/v2/authorization', ctx.authorization.endpoints); + app.use('/api/v2/ddata', ddata); + + // pebble data + app.get('/pebble', ctx.pebble); + + // expose swagger.json + app.get('/swagger.json', function(req, res) { + res.sendFile(__dirname + '/swagger.json'); + }); + + // expose swagger.yaml + app.get('/swagger.yaml', function(req, res) { + res.sendFile(__dirname + '/swagger.yaml'); + }); + + if (env.settings.isEnabled('dumps')) { + var heapdump = require('heapdump'); + app.get('/api/v2/dumps/start', function(req, res) { + var path = new Date().toISOString() + '.heapsnapshot'; + path = path.replace(/:/g, '-'); + console.info('writing dump to', path); + heapdump.writeSnapshot(path); + res.send('wrote dump to ' + path); + }); + } - // serve the static content - app.use(staticFiles); + // app.get('/package.json', software); - const swaggerUiAssetPath = require("swagger-ui-dist").getAbsoluteFSPath(); - var swaggerFiles = express.static(swaggerUiAssetPath, { - maxAge: maxAge - }); + // Allow static resources to be cached for week + var maxAge = 7 * 24 * 60 * 60 * 1000; - // serve the static content - app.use('/swagger-ui-dist', swaggerFiles); + if (process.env.NODE_ENV === 'development') { + maxAge = 1; + console.log('Development environment detected, setting static file cache age to 1 second'); - var tmpFiles = express.static('tmp', { - maxAge: maxAge + app.get('/nightscout.appcache', function(req, res) { + res.sendStatus(404); }); + } - // serve the static content - app.use(tmpFiles); + var staticFiles = express.static(env.static_files, { + maxAge + }); - if (process.env.NODE_ENV !== 'development') { + // serve the static content + app.use(staticFiles); - console.log('Production environment detected, enabling Minify'); + // API docs - var minify = require('express-minify'); - var myCssmin = require('cssmin'); - - app.use(minify({ - js_match: /\.js/, - css_match: /\.css/, - sass_match: /scss/, - less_match: /less/, - stylus_match: /stylus/, - coffee_match: /coffeescript/, - json_match: /json/, - cssmin: myCssmin, - cache: __dirname + '/tmp', - onerror: undefined, - })); + const swaggerUi = require('swagger-ui-express'); + const swaggerDocument = require('./swagger.json'); - } + app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument)); - // if this is dev environment, package scripts on the fly - // if production, rely on postinstall script to run packaging for us + app.use('/swagger-ui-dist', (req, res, next) => { + res.redirect(307, '/api-docs'); + }); - if (process.env.NODE_ENV === 'development') { + // if this is dev environment, package scripts on the fly + // if production, rely on postinstall script to run packaging for us - var webpack = require("webpack"); - var webpack_conf = require('./webpack.config'); + app.locals.bundle = '/bundle'; - webpack(webpack_conf, function(err, stats) { + if (process.env.NODE_ENV === 'development') { - var json = stats.toJson() // => webpack --json + console.log('Development mode'); - var options = { - noColor: true - }; + app.locals.bundle = '/devbundle'; - console.log(prettyjson.render(json.errors, options)); - console.log(prettyjson.render(json.assets, options)); + const webpack = require('webpack'); + var webpack_conf = require('./webpack.config'); + const middleware = require('webpack-dev-middleware'); + const compiler = webpack(webpack_conf); - }); - } + app.use( + middleware(compiler, { + // webpack-dev-middleware options + publicPath: webpack_conf.output.publicPath + , lazy: false + }) + ); - // Handle errors with express's errorhandler, to display more readable error messages. - var errorhandler = require('errorhandler'); - //if (process.env.NODE_ENV === 'development') { - app.use(errorhandler()); - //} - return app; + app.use(require("webpack-hot-middleware")(compiler, { + heartbeat: 1000 + })); + } + + // Production bundling + var tmpFiles = express.static('tmp', { + maxAge: maxAge + }); + + // serve the static content + app.use('/bundle', tmpFiles); + + if (process.env.NODE_ENV !== 'development') { + + console.log('Production environment detected, enabling Minify'); + + var minify = require('express-minify'); + var myCssmin = require('cssmin'); + + app.use(minify({ + js_match: /\.js/ + , css_match: /\.css/ + , sass_match: /scss/ + , less_match: /less/ + , stylus_match: /stylus/ + , coffee_match: /coffeescript/ + , json_match: /json/ + , cssmin: myCssmin + , cache: __dirname + '/tmp' + , onerror: undefined + , })); + + } + + // Handle errors with express's errorhandler, to display more readable error messages. + var errorhandler = require('errorhandler'); + //if (process.env.NODE_ENV === 'development') { + app.use(errorhandler()); + //} + return app; } module.exports = create; diff --git a/app.json b/app.json index 4ee2e183495..8fea5103f88 100644 --- a/app.json +++ b/app.json @@ -95,7 +95,7 @@ "DISPLAY_UNITS": { "description": "Preferred BG units for the site:'mg/dl' or 'mmol'. (Note that it is *not* 'mmol/L')", "value": "mg/dl", - "required": false + "required": true }, "ENABLE": { "description": "Plugins to enable for your site. Must be a space-delimited, lower-case list. Include the word 'bridge' here if you are receiving data from the Dexcom Share service. Include 'mmconnect' if you are bridging from the MiniMed CareLink service.", diff --git a/bundle/bundle.clocks.source.js b/bundle/bundle.clocks.source.js new file mode 100644 index 00000000000..a200f467330 --- /dev/null +++ b/bundle/bundle.clocks.source.js @@ -0,0 +1,9 @@ + +$ = require("jquery"); + +window.Nightscout = { + client: require('../lib/client/clock-client'), + units: require('../lib/units')(), +}; + +console.info('Nightscout clock bundle ready'); \ No newline at end of file diff --git a/bundle/bundle.reports.source.js b/bundle/bundle.reports.source.js new file mode 100644 index 00000000000..c07368543b4 --- /dev/null +++ b/bundle/bundle.reports.source.js @@ -0,0 +1,10 @@ +import './bundle.source'; + +window.Nightscout.report_plugins = require('../lib/report_plugins/')(); + +console.info('Nightscout report bundle ready'); + +// Needed for Hot Module Replacement +if(typeof(module.hot) !== 'undefined') { + module.hot.accept() // eslint-disable-line no-undef + } diff --git a/bundle/bundle.source.js b/bundle/bundle.source.js index ea7cc924414..d554744e6e4 100644 --- a/bundle/bundle.source.js +++ b/bundle/bundle.source.js @@ -2,7 +2,6 @@ import '../static/css/drawer.css'; import '../static/css/dropdown.css'; import '../static/css/sgv.css'; - $ = require("jquery"); require('jquery-ui-bundle'); @@ -26,8 +25,12 @@ window.Nightscout = window.Nightscout || {}; window.Nightscout = { client: require('../lib/client'), units: require('../lib/units')(), - report_plugins: require('../lib/report_plugins/')(), admin_plugins: require('../lib/admin_plugins/')() }; -console.info('Nightscout bundle ready'); \ No newline at end of file +console.info('Nightscout bundle ready'); + +// Needed for Hot Module Replacement +if(typeof(module.hot) !== 'undefined') { + module.hot.accept() // eslint-disable-line no-undef + } diff --git a/docs/plugins/maker-setup.md b/docs/plugins/maker-setup.md index 831e9e05c4d..f40c94f161c 100644 --- a/docs/plugins/maker-setup.md +++ b/docs/plugins/maker-setup.md @@ -1,3 +1,24 @@ + + +**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* + +- [Nightscout/IFTTT Maker](#nightscoutifttt-maker) + - [Overview](#overview) + - [Note: There have been some recent reports of the IFTTT service delaying Nightscout alarms. Be sure to test your implementation before relying solely on its alerts. Pushover is an alternate push notification service that might be worth considering as well.](#note-there-have-been-some-recent-reports-of-the-ifttt-service-delaying-nightscout-alarms-be-sure-to-test-your-implementation-before-relying-solely-on-its-alerts-pushover-is-an-alternate-push-notification-service-that-might-be-worth-considering-as-well) + - [Events](#events) + - [Creating an Applet](#creating-an-applet) + - [1. Choose a Service](#1-choose-a-service) + - [2. Choose a Trigger](#2-choose-a-trigger) + - [3. Complete the Trigger field](#3-complete-the-trigger-field) + - [4. Create an Action](#4-create-an-action) + - [5. Complete Action Fields](#5-complete-action-fields) + - [6. Review and Finish](#6-review-and-finish) + - [7. Get your Maker Key](#7-get-your-maker-key) + - [8. Configure your Nightscout site](#8-configure-your-nightscout-site) + - [9. Configure the IFTTT mobile app](#9-configure-the-ifttt-mobile-app) + + + **Table of Contents** - [Nightscout/IFTTT Maker](#nightscoutifttt-maker) diff --git a/env.js b/env.js index 808b18fd9ff..9114e7297fc 100644 --- a/env.js +++ b/env.js @@ -21,6 +21,17 @@ function config ( ) { * See README.md for info about all the supported ENV VARs */ env.DISPLAY_UNITS = readENV('DISPLAY_UNITS', 'mg/dl'); + + // be lenient at accepting the mmol input + if (env.DISPLAY_UNITS.toLowerCase().includes('mmol')) { + env.DISPLAY_UNITS = 'mmol'; + } else { + // also ensure the mg/dl is set with expected case + env.DISPLAY_UNITS = 'mg/dl'; + } + + console.log('Units set to', env.DISPLAY_UNITS ); + env.PORT = readENV('PORT', 1337); env.HOSTNAME = readENV('HOSTNAME', null); env.IMPORT_CONFIG = readENV('IMPORT_CONFIG', null); @@ -61,7 +72,7 @@ function setSSL() { env.secureHstsHeaderIncludeSubdomains = readENVTruthy("SECURE_HSTS_HEADER_INCLUDESUBDOMAINS", false); env.secureHstsHeaderPreload= readENVTruthy("SECURE_HSTS_HEADER_PRELOAD", false); env.secureCsp = readENVTruthy("SECURE_CSP", false); - + env.secureCspReportOnly = readENVTruthy("SECURE_CSP_REPORT_ONLY", false); } // A little ugly, but we don't want to read the secret into a var diff --git a/lib/admin_plugins/cleanstatusdb.js b/lib/admin_plugins/cleanstatusdb.js index b3e3032c8fe..29fb99bae16 100644 --- a/lib/admin_plugins/cleanstatusdb.js +++ b/lib/admin_plugins/cleanstatusdb.js @@ -8,60 +8,60 @@ var cleanstatusdb = { , pluginType: 'admin' }; -function init() { +function init () { return cleanstatusdb; } module.exports = init; cleanstatusdb.actions = [ - { - name: 'Delete all documents from devicestatus collection' - , description: 'This task removes all documents from devicestatus collection. Useful when uploader battery status is not properly updated.' - , buttonLabel: 'Delete all documents' - , confirmText: 'Delete all documents from devicestatus collection?' + { + name: 'Delete all documents from devicestatus collection' + , description: 'This task removes all documents from devicestatus collection. Useful when uploader battery status is not properly updated.' + , buttonLabel: 'Delete all documents' + , confirmText: 'Delete all documents from devicestatus collection?' } - , { - name: 'Delete all documents from devicestatus collection older than 30 days' - , description: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' - , buttonLabel: 'Delete old documents' - , confirmText: 'Delete old documents from devicestatus collection?' - , preventClose: true + , { + name: 'Delete all documents from devicestatus collection older than 30 days' + , description: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' + , buttonLabel: 'Delete old documents' + , confirmText: 'Delete old documents from devicestatus collection?' + , preventClose: true } ]; -cleanstatusdb.actions[0].init = function init(client, callback) { +cleanstatusdb.actions[0].init = function init (client, callback) { var translate = client.translate; var $status = $('#admin_' + cleanstatusdb.name + '_0_status'); - + $status.hide().text(translate('Loading database ...')).fadeIn('slow'); $.ajax('/api/v1/devicestatus.json?count=500', { headers: client.headers() - , success: function (records) { + , success: function(records) { var recs = (records.length === 500 ? '500+' : records.length); - $status.hide().text(translate('Database contains %1 records',{ params: [recs] })).fadeIn('slow'); + $status.hide().text(translate('Database contains %1 records', { params: [recs] })).fadeIn('slow'); } - , error: function () { + , error: function() { $status.hide().text(translate('Error loading database')).fadeIn('slow'); } - }).done(function () { if (callback) { callback(); } }); + }).done(function() { if (callback) { callback(); } }); }; -cleanstatusdb.actions[0].code = function deleteRecords(client, callback) { +cleanstatusdb.actions[0].code = function deleteRecords (client, callback) { var translate = client.translate; var $status = $('#admin_' + cleanstatusdb.name + '_0_status'); - + if (!client.hashauth.isAuthenticated()) { alert(translate('Your device is not authenticated yet')); if (callback) { callback(); } return; - }; + } $status.hide().text(translate('Deleting records ...')).fadeIn('slow'); $.ajax({ - method: 'DELETE' + method: 'DELETE' , url: '/api/v1/devicestatus/*' , headers: client.headers() }).done(function success () { @@ -69,7 +69,7 @@ cleanstatusdb.actions[0].code = function deleteRecords(client, callback) { if (callback) { callback(); } - }).fail(function fail() { + }).fail(function fail () { $status.hide().text(translate('Error')).fadeIn('slow'); if (callback) { callback(); @@ -77,24 +77,24 @@ cleanstatusdb.actions[0].code = function deleteRecords(client, callback) { }); }; -cleanstatusdb.actions[1].init = function init(client, callback) { +cleanstatusdb.actions[1].init = function init (client, callback) { var translate = client.translate; var $status = $('#admin_' + cleanstatusdb.name + '_1_status'); $status.hide(); - var numDays = '
' - + ''; + var numDays = '
' + + ''; $('#admin_' + cleanstatusdb.name + '_1_html').html(numDays); if (callback) { callback(); } }; -cleanstatusdb.actions[1].code = function deleteOldRecords(client, callback) { +cleanstatusdb.actions[1].code = function deleteOldRecords (client, callback) { var translate = client.translate; var $status = $('#admin_' + cleanstatusdb.name + '_1_status'); var numDays = Number($('#admin_devicestatus_days').val()); @@ -117,17 +117,17 @@ cleanstatusdb.actions[1].code = function deleteOldRecords(client, callback) { $status.hide().text(translate('Deleting records ...')).fadeIn('slow'); $.ajax('/api/v1/devicestatus/?find[created_at][$lte]=' + dateStr, { - method: 'DELETE' + method: 'DELETE' , headers: client.headers() - , success: function (retVal) { - $status.text(translate('%1 records deleted',{ params: [retVal.n] })); + , success: function(retVal) { + $status.text(translate('%1 records deleted', { params: [retVal.n] })); } - , error: function () { + , error: function() { $status.hide().text(translate('Error')).fadeIn('slow'); } }).done(function success () { if (callback) { callback(); } - }).fail(function fail() { + }).fail(function fail () { if (callback) { callback(); } }); }; diff --git a/lib/admin_plugins/futureitems.js b/lib/admin_plugins/futureitems.js index 3d5acc23099..4ea613a53c2 100644 --- a/lib/admin_plugins/futureitems.js +++ b/lib/admin_plugins/futureitems.js @@ -6,164 +6,164 @@ var futureitems = { , pluginType: 'admin' }; -function init() { +function init () { return futureitems; } module.exports = init; futureitems.actions = [ - { - name: 'Find and remove treatments in the future' - , description: 'This task find and remove treatments in the future.' - , buttonLabel: 'Remove treatments in the future' + { + name: 'Find and remove treatments in the future' + , description: 'This task find and remove treatments in the future.' + , buttonLabel: 'Remove treatments in the future' } - , { - name: 'Find and remove entries in the future' - , description: 'This task find and remove CGM data in the future created by uploader with wrong date/time.' - , buttonLabel: 'Remove entries in the future' + + , { + name: 'Find and remove entries in the future' + , description: 'This task find and remove CGM data in the future created by uploader with wrong date/time.' + , buttonLabel: 'Remove entries in the future' } ]; -futureitems.actions[0].init = function init(client, callback) { +futureitems.actions[0].init = function init (client, callback) { var translate = client.translate; var $status = $('#admin_' + futureitems.name + '_0_status'); - + function valueOrEmpty (value) { return value ? value : ''; } - + function showOneTreatment (tr, table) { - table.append($('').css('background-color','#0f0f0f') - .append($('').attr('width','20%').append(new Date(tr.created_at).toLocaleString().replace(/([\d]+:[\d]{2})(:[\d]{2})(.*)/, '$1$3'))) - .append($('').attr('width','20%').append(tr.eventType ? translate(client.careportal.resolveEventName(tr.eventType)) : '')) - .append($('').attr('width','10%').attr('align','center').append(tr.glucose ? tr.glucose + ' ('+translate(tr.glucoseType)+')' : '')) - .append($('').attr('width','10%').attr('align','center').append(valueOrEmpty(tr.insulin))) - .append($('').attr('width','10%').attr('align','center').append(valueOrEmpty(tr.carbs))) - .append($('').attr('width','10%').append(valueOrEmpty(tr.enteredBy))) - .append($('').attr('width','20%').append(valueOrEmpty(tr.notes))) + table.append($('').css('background-color', '#0f0f0f') + .append($('').attr('width', '20%').append(new Date(tr.created_at).toLocaleString().replace(/([\d]+:[\d]{2})(:[\d]{2})(.*)/, '$1$3'))) + .append($('').attr('width', '20%').append(tr.eventType ? translate(client.careportal.resolveEventName(tr.eventType)) : '')) + .append($('').attr('width', '10%').attr('align', 'center').append(tr.glucose ? tr.glucose + ' (' + translate(tr.glucoseType) + ')' : '')) + .append($('').attr('width', '10%').attr('align', 'center').append(valueOrEmpty(tr.insulin))) + .append($('').attr('width', '10%').attr('align', 'center').append(valueOrEmpty(tr.carbs))) + .append($('').attr('width', '10%').append(valueOrEmpty(tr.enteredBy))) + .append($('').attr('width', '20%').append(valueOrEmpty(tr.notes))) ); } - - function showTreatments(treatments, table) { - table.append($('').css('background','#040404') - .append($('').css('width','80px').attr('align','left').append(translate('Time'))) - .append($('').css('width','150px').attr('align','left').append(translate('Event Type'))) - .append($('').css('width','150px').attr('align','left').append(translate('Blood Glucose'))) - .append($('').css('width','50px').attr('align','left').append(translate('Insulin'))) - .append($('').css('width','50px').attr('align','left').append(translate('Carbs'))) - .append($('').css('width','150px').attr('align','left').append(translate('Entered By'))) - .append($('').css('width','300px').attr('align','left').append(translate('Notes'))) + + function showTreatments (treatments, table) { + table.append($('').css('background', '#040404') + .append($('').css('width', '80px').attr('align', 'left').append(translate('Time'))) + .append($('').css('width', '150px').attr('align', 'left').append(translate('Event Type'))) + .append($('').css('width', '150px').attr('align', 'left').append(translate('Blood Glucose'))) + .append($('').css('width', '50px').attr('align', 'left').append(translate('Insulin'))) + .append($('').css('width', '50px').attr('align', 'left').append(translate('Carbs'))) + .append($('').css('width', '150px').attr('align', 'left').append(translate('Entered By'))) + .append($('').css('width', '300px').attr('align', 'left').append(translate('Notes'))) ); - for (var t=0; t').css('margin-top','10px'); + $status.hide().text(translate('Database contains %1 future records', { params: [records.length] })).fadeIn('slow'); + var table = $('').css('margin-top', '10px'); $('#admin_' + futureitems.name + '_0_html').append(table); showTreatments(records, table); futureitems.actions[0].confirmText = translate('Remove %1 selected records?', { params: [records.length] }); } - , error: function () { + , error: function() { $status.hide().text(translate('Error loading database')).fadeIn('slow'); futureitems.treatmentrecords = []; } - }).done(function () { if (callback) { callback(); } }); + }).done(function() { if (callback) { callback(); } }); }; -futureitems.actions[0].code = function deleteRecords(client, callback) { +futureitems.actions[0].code = function deleteRecords (client, callback) { var translate = client.translate; var $status = $('#admin_' + futureitems.name + '_0_status'); - + if (!client.hashauth.isAuthenticated()) { alert(translate('Your device is not authenticated yet')); if (callback) { callback(); } return; - }; + } function deleteRecordById (_id) { $.ajax({ - method: 'DELETE' + method: 'DELETE' , url: '/api/v1/treatments/' + _id , headers: client.headers() }).done(function success () { $status.text(translate('Record %1 removed ...', { params: [_id] })); - }).fail(function fail() { - $status.text(translate('Error removing record %1', { params: [_id] })); + }).fail(function fail () { + $status.text(translate('Error removing record %1', { params: [_id] })); }); } - + $status.hide().text(translate('Deleting records ...')).fadeIn('slow'); for (var i = 0; i < futureitems.treatmentrecords.length; i++) { deleteRecordById(futureitems.treatmentrecords[i]._id); } $('#admin_' + futureitems.name + '_0_html').html(''); - + if (callback) { callback(); } }; -futureitems.actions[1].init = function init(client, callback) { +futureitems.actions[1].init = function init (client, callback) { var translate = client.translate; var $status = $('#admin_' + futureitems.name + '_1_status'); - + $status.hide().text(translate('Loading database ...')).fadeIn('slow'); var now = new Date().getTime(); $.ajax('/api/v1/entries.json?&find[date][$gte]=' + now + '&count=288', { headers: client.headers() - , success: function (records) { + , success: function(records) { futureitems.entriesrecords = records; - $status.hide().text(translate('Database contains %1 future records',{ params: [records.length] })).fadeIn('slow'); + $status.hide().text(translate('Database contains %1 future records', { params: [records.length] })).fadeIn('slow'); futureitems.actions[1].confirmText = translate('Remove %1 selected records?', { params: [records.length] }); } - , error: function () { + , error: function() { $status.hide().text(translate('Error loading database')).fadeIn('slow'); futureitems.entriesrecords = []; } - }).done(function () { if (callback) { callback(); } }); + }).done(function() { if (callback) { callback(); } }); }; -futureitems.actions[1].code = function deleteRecords(client, callback) { +futureitems.actions[1].code = function deleteRecords (client, callback) { var translate = client.translate; var $status = $('#admin_' + futureitems.name + '_1_status'); - + if (!client.hashauth.isAuthenticated()) { alert(translate('Your device is not authenticated yet')); if (callback) { callback(); } return; - }; - + } + function deteleteRecordById (_id) { $.ajax({ - method: 'DELETE' + method: 'DELETE' , url: '/api/v1/entries/' + _id , headers: client.headers() }).done(function success () { $status.text(translate('Record %1 removed ...', { params: [_id] })); - }).fail(function fail() { - $status.text(translate('Error removing record %1', { params: [_id] })); + }).fail(function fail () { + $status.text(translate('Error removing record %1', { params: [_id] })); }); } - $status.hide().text(translate('Deleting records ...')).fadeIn('slow'); for (var i = 0; i < futureitems.entriesrecords.length; i++) { deteleteRecordById(futureitems.entriesrecords[i]._id); } - + if (callback) { callback(); } diff --git a/lib/admin_plugins/roles.js b/lib/admin_plugins/roles.js index 42191751c4b..f99c4344449 100644 --- a/lib/admin_plugins/roles.js +++ b/lib/admin_plugins/roles.js @@ -1,12 +1,14 @@ 'use strict'; +const _ = require('lodash'); + var roles = { name: 'roles' , label: 'Roles - Groups of People, Devices, etc' , pluginType: 'admin' }; -function init() { +function init () { return roles; } @@ -20,13 +22,13 @@ roles.actions = [{ , init: function init (client, callback) { $status = $('#admin_' + roles.name + '_0_status'); $status.hide().text(client.translate('Loading database ...')).fadeIn('slow'); - var table = $('
').css('margin-top','10px'); + var table = $('
').css('margin-top', '10px'); $('#admin_' + roles.name + '_0_html').append(table).append(genDialog(client)); reload(client, callback); } , preventClose: true , code: function createNewRole (client, callback) { - var role = { }; + var role = {}; openDialog(role, client, callback); } }]; @@ -40,9 +42,9 @@ function createOrSaveRole (role, client, callback) { , url: '/api/v2/authorization/roles/' , headers: client.headers() , data: role - }).done(function success() { + }).done(function success () { reload(client, callback); - }).fail(function fail(err) { + }).fail(function fail (err) { console.error('Unable to ' + method + ' Role', err.responseText); window.alert(client.translate('Unable to %1 Role', { params: [method] })); if (callback) { @@ -56,9 +58,9 @@ function deleteRole (role, client, callback) { method: 'DELETE' , url: '/api/v2/authorization/roles/' + role._id , headers: client.headers() - }).done(function success() { + }).done(function success () { reload(client, callback); - }).fail(function fail(err) { + }).fail(function fail (err) { console.error('Unable to delete Role', err.responseText); window.alert(client.translate('Unable to delete Role')); if (callback) { @@ -70,16 +72,16 @@ function deleteRole (role, client, callback) { function reload (client, callback) { $.ajax({ method: 'GET' - , url:'/api/v2/authorization/roles' + , url: '/api/v2/authorization/roles' , headers: client.headers() }).done(function success (records) { roles.records = records; - $status.hide().text(client.translate('Database contains %1 roles',{ params: [records.length] })).fadeIn('slow'); + $status.hide().text(client.translate('Database contains %1 roles', { params: [records.length] })).fadeIn('slow'); showRoles(records, client); if (callback) { callback(); } - }).fail(function fail(err) { + }).fail(function fail (err) { $status.hide().text(client.translate('Error loading database')).fadeIn('slow'); roles.records = []; if (callback) { @@ -90,56 +92,57 @@ function reload (client, callback) { function genDialog (client) { var ret = - '' - ; + ''; return $(ret); } function openDialog (role, client) { - $( '#editroledialog' ).dialog({ + $('#editroledialog').dialog({ width: 360 , height: 360 - , buttons: [ - { text: client.translate('Save'), - class: 'leftButton', - click: function() { + , buttons: [ + { + text: client.translate('Save') + , class: 'leftButton' + , click: function() { role.name = $('#edrole_name').val(); role.permissions = _.chain($('#edrole_permissions').val().toLowerCase().split(/[;, ]/)) - .map(_.trim) - .reject(_.isEmpty) - .sort() - .value(); + .map(_.trim) + .reject(_.isEmpty) + .sort() + .value(); role.notes = $('#edrole_notes').val(); var self = this; delete role.autoGenerated; createOrSaveRole(role, client, function callback () { - $( self ).dialog('close'); + $(self).dialog('close'); }); } - }, - { text: client.translate('Cancel'), - click: function () { $( this ).dialog('close'); } + } + , { + text: client.translate('Cancel') + , click: function() { $(this).dialog('close'); } } ] - , open : function() { + , open: function() { $(this).parent().css('box-shadow', '20px 20px 20px 0px black'); - $(this).parent().find('.ui-dialog-buttonset' ).css({'width':'100%','text-align':'right'}); - $(this).parent().find('button:contains("'+client.translate('Save')+'")').css({'float':'left'}); + $(this).parent().find('.ui-dialog-buttonset').css({ 'width': '100%', 'text-align': 'right' }); + $(this).parent().find('button:contains("' + client.translate('Save') + '")').css({ 'float': 'left' }); $('#edrole_name').val(role.name || '').focus(); $('#edrole_permissions').val(role.permissions ? role.permissions.join(' ') : ''); $('#edrole_notes').val(role.notes || ''); @@ -151,14 +154,14 @@ function openDialog (role, client) { function showRole (role, table, client) { var editIcon = $(''); - editIcon.click(function clicked ( ) { + editIcon.click(function clicked () { openDialog(role, client); }); var deleteIcon = ''; if (role._id) { deleteIcon = $(''); - deleteIcon.click(function clicked() { + deleteIcon.click(function clicked () { var ok = window.confirm(client.translate('Are you sure you want to delete: ') + role.name); if (ok) { deleteRole(role, client); @@ -166,21 +169,21 @@ function showRole (role, table, client) { }); } - table.append($('').css('background-color','#0f0f0f') - .append($('').css('background-color', '#0f0f0f') + .append($('').css('background','#040404') - .append($('').css('background', '#040404') + .append($('').appendTo(table); var totalDailyInsulin = bolusInsulin + baseBasalInsulin + positiveTemps + negativeTemps; $('').appendTo(table); + + $('').appendTo(table); + $('').appendTo(table); + $('').appendTo(table); + $('').appendTo(table); $('#daytodaystatchart-' + day).append(table); var chartData = [ { - label: translate('Basal'), - count: totalBasalInsulin, - pct: (totalBasalInsulin / totalDailyInsulin * 100).toFixed(0) - }, - {label: translate('Bolus'), count: bolusInsulin, pct: (bolusInsulin / totalDailyInsulin * 100).toFixed(0)} + label: translate('Basal') + , count: totalBasalInsulin + , pct: (totalBasalInsulin / totalDailyInsulin * 100).toFixed(0) + } + , { label: translate('Bolus'), count: bolusInsulin, pct: (bolusInsulin / totalDailyInsulin * 100).toFixed(0) } ]; // Insulin distribution chart @@ -918,102 +935,104 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) var color = d3.scale.ordinal().range([basalcolor, boluscolor]); var labelArc = d3.svg.arc() - .outerRadius(radius / 2) - .innerRadius(radius / 2); + .outerRadius(radius / 2) + .innerRadius(radius / 2); var svg = d3.select('#daytodaystatinsulinpiechart-' + day) - .append('svg') - .attr('width', width) - .attr('height', height) - .append('g') - .attr('transform', 'translate(' + (width / 2) + - ',' + (height / 2) + ')'); + .append('svg') + .attr('width', width) + .attr('height', height) + .append('g') + .attr('transform', 'translate(' + (width / 2) + + ',' + (height / 2) + ')'); var arc = d3.svg.arc() - .outerRadius(radius); + .outerRadius(radius); var pie = d3.layout.pie() - .value(function (d) { - return d.count; - }) - .sort(null); + .value(function(d) { + return d.count; + }) + .sort(null); var insulg = svg.selectAll('.insulinarc') - .data(pie(chartData)) - .enter() - .append('g') - .attr('class', 'insulinarc'); + .data(pie(chartData)) + .enter() + .append('g') + .attr('class', 'insulinarc'); insulg.append('path') - .attr('d', arc) - .attr('opacity', '0.5') - .attr('fill', function (d) { - return color(d.data.label); - }); + .attr('d', arc) + .attr('opacity', '0.5') + .attr('fill', function(d) { + return color(d.data.label); + }); insulg.append('text') - .attr('transform', function (d) { - return 'translate(' + labelArc.centroid(d) + ')'; - }) - .attr('dy', '.15em') - .style('font-weight', 'bold') - .attr('text-anchor', 'middle') - .text(function (d) { - return d.data.pct + '%'; - }); + .attr('transform', function(d) { + return 'translate(' + labelArc.centroid(d) + ')'; + }) + .attr('dy', '.15em') + .style('font-weight', 'bold') + .attr('text-anchor', 'middle') + .text(function(d) { + return d.data.pct + '%'; + }); // Carbs pie chart var carbscolor = d3.scale.ordinal().range(['red']); var carbsData = [ - {label: translate('Carbs'), count: data.dailyCarbs} + { label: translate('Carbs'), count: data.dailyCarbs } ]; var carbssvg = d3.select('#daytodaystatcarbspiechart-' + day) - .append('svg') - .attr('width', width) - .attr('height', height) - .append('g') - .attr('transform', 'translate(' + (width / 2) + - ',' + (height / 2) + ')'); + .append('svg') + .attr('width', width) + .attr('height', height) + .append('g') + .attr('transform', 'translate(' + (width / 2) + + ',' + (height / 2) + ')'); var carbsarc = d3.svg.arc() - .outerRadius(radius * data.dailyCarbs / options.maxDailyCarbsValue); + .outerRadius(radius * data.dailyCarbs / options.maxDailyCarbsValue); var carbspie = d3.layout.pie() - .value(function (d) { - return d.count; - }) - .sort(null); + .value(function(d) { + return d.count; + }) + .sort(null); var carbsg = carbssvg.selectAll('.carbsarc') - .data(carbspie(carbsData)) - .enter() - .append('g') - .attr('class', 'carbsarc'); + .data(carbspie(carbsData)) + .enter() + .append('g') + .attr('class', 'carbsarc'); carbsg.append('path') - .attr('d', carbsarc) - .attr('opacity', '0.5') - .attr('fill', function (d) { - return carbscolor(d.data.label); - }); + .attr('d', carbsarc) + .attr('opacity', '0.5') + .attr('fill', function(d) { + return carbscolor(d.data.label); + }); carbsg.append('text') - .attr('transform', function () { - return 'translate(0,0)'; - }) - .attr('dy', '.15em') - .style('font-weight', 'bold') - .attr('text-anchor', 'middle') - .text(function (d) { - return d.data.count + 'g'; - }); + .attr('transform', function() { + return 'translate(0,0)'; + }) + .attr('dy', '.15em') + .style('font-weight', 'bold') + .attr('text-anchor', 'middle') + .text(function(d) { + return d.data.count + 'g'; + }); } tddSum += totalDailyInsulin; carbsSum += data.dailyCarbs; + proteinSum += data.dailyProtein; + fatSum += data.dailyFat; appendProfileSwitch(context, { //eventType: 'Profile Switch' @@ -1022,15 +1041,15 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) , first: true }); - function appendProfileSwitch(context, treatment) { - + function appendProfileSwitch (context, treatment) { + if (!treatment.cutting && !treatment.profile) { return; } - + var sign = treatment.first ? '▲▲▲' : '▬▬▬'; var text; if (treatment.cutting) { text = sign + ' ' + client.profilefunctions.profileSwitchName(treatment.cutting) + ' ' + '►►►' + ' ' + client.profilefunctions.profileSwitchName(treatment.profile) + ' ' + sign; - } else { + } else { text = sign + ' ' + client.profilefunctions.profileSwitchName(treatment.profile) + ' ' + sign; } context.append('text') @@ -1039,7 +1058,7 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) .attr('fill', '#0099ff') .attr('text-anchor', 'start') .attr('dy', '.35em') - .attr('transform', 'rotate(-90 ' + (xScale2(treatment.mills) + padding.left) + ',' + (yScaleBasals(0) + padding.top - 10) + ') ' + + .attr('transform', 'rotate(-90 ' + (xScale2(treatment.mills) + padding.left) + ',' + (yScaleBasals(0) + padding.top - 10) + ') ' + 'translate(' + (xScale2(treatment.mills) + padding.left) + ',' + (yScaleBasals(0) + padding.top - 10) + ')') .text(text); } @@ -1047,7 +1066,7 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) console.log("Rendering " + day, new Date().getTime() - timestart.getTime(), "msecs"); } - function hideTooltip ( ) { + function hideTooltip () { client.tooltip.transition() .duration(TOOLTIP_TRANS_MS) .style('opacity', 0); diff --git a/lib/report_plugins/glucosedistribution.js b/lib/report_plugins/glucosedistribution.js index e16ad104d77..4a5e7dd31fb 100644 --- a/lib/report_plugins/glucosedistribution.js +++ b/lib/report_plugins/glucosedistribution.js @@ -1,489 +1,474 @@ 'use strict'; var glucosedistribution = { - name: 'glucosedistribution', - label: 'Distribution', - pluginType: 'report' + name: 'glucosedistribution' + , label: 'Distribution' + , pluginType: 'report' }; -function init() { - return glucosedistribution; +function init () { + return glucosedistribution; } module.exports = init; -glucosedistribution.html = function html(client) { - var translate = client.translate; - var ret = - '

' + - translate('Glucose distribution') + - ' (' + - ' ' + - ' )' + - '

' + - '
').attr('width','20%').append(editIcon).append(deleteIcon).append(role.name)) - .append($('').attr('width','20%').append(_.isEmpty(role.permissions) ? '[none]' : role.permissions.join(' '))) - .append($('').attr('width','10%').append(role._id ? (role.notes ? role.notes : '') : '[system default]')) + table.append($('
').attr('width', '20%').append(editIcon).append(deleteIcon).append(role.name)) + .append($('').attr('width', '20%').append(_.isEmpty(role.permissions) ? '[none]' : role.permissions.join(' '))) + .append($('').attr('width', '10%').append(role._id ? (role.notes ? role.notes : '') : '[system default]')) ); } function showRoles (roles, client) { var table = $('#admin_roles_table'); - table.empty().append($('
').css('width','100px').attr('align','left').append(client.translate('Name'))) - .append($('').css('width','150px').attr('align','left').append(client.translate('Permissions'))) - .append($('').css('width','150px').attr('align','left').append(client.translate('Notes'))) + table.empty().append($('
').css('width', '100px').attr('align', 'left').append(client.translate('Name'))) + .append($('').css('width', '150px').attr('align', 'left').append(client.translate('Permissions'))) + .append($('').css('width', '150px').attr('align', 'left').append(client.translate('Notes'))) ); - for (var t=0; t').css('margin-top','10px'); + var table = $('').css('margin-top', '10px'); $('#admin_' + subjects.name + '_0_html').append(table).append(genDialog(client)); reload(client, callback); } @@ -39,9 +41,9 @@ function createOrSaveSubject (subject, client, callback) { , url: '/api/v2/authorization/subjects/' , headers: client.headers() , data: subject - }).done(function success() { + }).done(function success () { reload(client, callback); - }).fail(function fail(err) { + }).fail(function fail (err) { console.error('Unable to ' + method + ' Subject', err.responseText); window.alert(client.translate('Unable to ' + method + ' Subject')); if (callback) { @@ -55,9 +57,9 @@ function deleteSubject (subject, client, callback) { method: 'DELETE' , url: '/api/v2/authorization/subjects/' + subject._id , headers: client.headers() - }).done(function success() { + }).done(function success () { reload(client, callback); - }).fail(function fail(err) { + }).fail(function fail (err) { console.error('Unable to delete Subject', err.responseText); window.alert(client.translate('Unable to delete Subject')); if (callback) { @@ -69,16 +71,16 @@ function deleteSubject (subject, client, callback) { function reload (client, callback) { $.ajax({ method: 'GET' - , url:'/api/v2/authorization/subjects' + , url: '/api/v2/authorization/subjects' , headers: client.headers() }).done(function success (records) { subjects.records = records; - $status.hide().text(client.translate('Database contains %1 subjects',{ params: [records.length] })).fadeIn('slow'); + $status.hide().text(client.translate('Database contains %1 subjects', { params: [records.length] })).fadeIn('slow'); showSubjects(records, client); if (callback) { callback(); } - }).fail(function fail(err) { + }).fail(function fail (err) { $status.hide().text(client.translate('Error loading database')).fadeIn('slow'); subjects.records = []; if (callback) { @@ -89,56 +91,57 @@ function reload (client, callback) { function genDialog (client) { var ret = - '' - ; + ''; return $(ret); } function openDialog (subject, client) { - $( '#editsubjectdialog' ).dialog({ + $('#editsubjectdialog').dialog({ width: 360 , height: 300 - , buttons: [ - { text: client.translate('Save'), - class: 'leftButton', - click: function() { + , buttons: [ + { + text: client.translate('Save') + , class: 'leftButton' + , click: function() { subject.name = $('#edsub_name').val(); subject.roles = _.chain($('#edsub_roles').val().toLowerCase().split(/[;, ]/)) - .map(_.trim) - .reject(_.isEmpty) - .sort() - .value(); + .map(_.trim) + .reject(_.isEmpty) + .sort() + .value(); subject.notes = $('#edsub_notes').val(); var self = this; - createOrSaveSubject(subject, client, function callback ( ) { - $( self ).dialog('close'); + createOrSaveSubject(subject, client, function callback () { + $(self).dialog('close'); }); } - }, - { text: client.translate('Cancel'), - click: function () { $( this ).dialog('close'); } + } + , { + text: client.translate('Cancel') + , click: function() { $(this).dialog('close'); } } ] - , open : function() { + , open: function() { $(this).parent().css('box-shadow', '20px 20px 20px 0px black'); - $(this).parent().find('.ui-dialog-buttonset' ).css({'width':'100%','text-align':'right'}); - $(this).parent().find('button:contains("'+client.translate('Save')+'")').css({'float':'left'}); + $(this).parent().find('.ui-dialog-buttonset').css({ 'width': '100%', 'text-align': 'right' }); + $(this).parent().find('button:contains("' + client.translate('Save') + '")').css({ 'float': 'left' }); $('#edsub_name').val(subject.name || '').focus(); $('#edsub_roles').val(subject.roles ? subject.roles.join(', ') : ''); $('#edsub_notes').val(subject.notes || ''); @@ -150,33 +153,33 @@ function openDialog (subject, client) { function showSubject (subject, table, client) { var editIcon = $(''); - editIcon.click(function clicked ( ) { + editIcon.click(function clicked () { openDialog(subject, client); }); var deleteIcon = $(''); - deleteIcon.click(function clicked ( ) { + deleteIcon.click(function clicked () { var ok = window.confirm(client.translate('Are you sure you want to delete: ') + subject.name); if (ok) { deleteSubject(subject, client); } }); - table.append($('').css('background-color','#0f0f0f') - .append($('').css('background-color', '#0f0f0f') + .append($('').css('background','#040404') - .append($('').css('background', '#040404') + .append($(''); $('').appendTo(thead); - $('').appendTo(thead); - $('').appendTo(thead); - $('').appendTo(thead); - $('').appendTo(thead); - $('').appendTo(thead); - $('').appendTo(thead); - $('').appendTo(thead); - $('').appendTo(thead); - $('').appendTo(thead); - $('').appendTo(thead); - $('').appendTo(thead); - $('').appendTo(thead); + $('').appendTo(thead); + $('').appendTo(thead); + $('').appendTo(thead); + $('').appendTo(thead); + $('').appendTo(thead); + $('').appendTo(thead); + $('').appendTo(thead); + $('').appendTo(thead); + $('').appendTo(thead); + $('').appendTo(thead); + $('').appendTo(thead); + $('').appendTo(thead); thead.appendTo(table); - sorteddaystoshow.forEach(function (day) { + sorteddaystoshow.forEach(function(day) { var tr = $(''); var daysRecords = datastorage[day].statsrecords; - + if (daysRecords.length === 0) { $('').appendTo(tr); - $('').appendTo(tr); + $('').appendTo(tr); + $('').appendTo(tr); table.append(tr); - return;; + return; } minForDay = daysRecords[0].sgv; @@ -101,53 +99,52 @@ dailystats.report = function report_dailystats(datastorage,sorteddaystoshow,opti sum += record.sgv; return out; }, { - lows: 0, - normal: 0, - highs: 0 + lows: 0 + , normal: 0 + , highs: 0 }); var average = sum / daysRecords.length; var bgValues = daysRecords.map(function(r) { return r.sgv; }); - $('').appendTo(tr); - - $('').appendTo(tr); - $('').appendTo(tr); - $('').appendTo(tr); - $('').appendTo(tr); - $('').appendTo(tr); - $('').appendTo(tr); - $('').appendTo(tr); - $('').appendTo(tr); - $('').appendTo(tr); - $('').appendTo(tr); - $('').appendTo(tr); - $('').appendTo(tr); + $('').appendTo(tr); + + $('').appendTo(tr); + $('').appendTo(tr); + $('').appendTo(tr); + $('').appendTo(tr); + $('').appendTo(tr); + $('').appendTo(tr); + $('').appendTo(tr); + $('').appendTo(tr); + $('').appendTo(tr); + $('').appendTo(tr); + $('').appendTo(tr); + $('').appendTo(tr); table.append(tr); var inrange = [ { - label: translate('Low'), - data: Math.round(stats.lows * 1000 / daysRecords.length) / 10 - }, - { - label: translate('In Range'), - data: Math.round(stats.normal * 1000 / daysRecords.length) / 10 - }, - { - label: translate('High'), - data: Math.round(stats.highs * 1000 / daysRecords.length) / 10 + label: translate('Low') + , data: Math.round(stats.lows * 1000 / daysRecords.length) / 10 + } + , { + label: translate('In Range') + , data: Math.round(stats.normal * 1000 / daysRecords.length) / 10 + } + , { + label: translate('High') + , data: Math.round(stats.highs * 1000 / daysRecords.length) / 10 } ]; $.plot( - '#dailystat-chart-' + day.toString(), - inrange, - { + '#dailystat-chart-' + day.toString() + , inrange, { series: { pie: { show: true } - }, - colors: ['#f88', '#8f8', '#ff8'] + } + , colors: ['#f88', '#8f8', '#ff8'] } ); }); diff --git a/lib/report_plugins/daytoday.js b/lib/report_plugins/daytoday.js index b071706899b..3445973402c 100644 --- a/lib/report_plugins/daytoday.js +++ b/lib/report_plugins/daytoday.js @@ -11,100 +11,107 @@ var daytoday = { , pluginType: 'report' }; -function init() { +function init () { return daytoday; } module.exports = init; -daytoday.html = function html(client) { +daytoday.html = function html (client) { var translate = client.translate; var ret = - '

' + translate('Day to day') + '

' - + '' + translate('To see this report, press SHOW while in this view') + '
' - + translate('Display') + ': ' - + ''+translate('Insulin')+'' - + ''+translate('Carbs')+'' - + ''+translate('Basal rate')+'' - + ''+translate('Notes') - + ''+translate('Food') - + ''+translate('Raw')+'' - + ''+translate('IOB')+'' - + ''+translate('COB')+'' - + ''+translate('Predictions')+'' - + ''+translate('OpenAPS')+'' - + ''+translate('Insulin distribution')+'' - + ' '+translate('Size') - + ' ' - + '
' - + translate('Scale') + ': ' - + '' - + translate('Linear') - + '' - + translate('Logarithmic') - + '' - + '
' - + '
' - + '
' - ; - return ret; + '

' + translate('Day to day') + '

' + + '' + translate('To see this report, press SHOW while in this view') + '
' + + translate('Display') + ': ' + + '' + translate('Insulin') + '' + + '' + translate('Carbs') + '' + + '' + translate('Basal rate') + '' + + '' + translate('Notes') + + '' + translate('Food') + + '' + translate('Raw') + '' + + '' + translate('IOB') + '' + + '' + translate('COB') + '' + + '' + translate('Predictions') + '' + + '' + translate('OpenAPS') + '' + + '' + translate('Insulin distribution') + '' + + ' ' + translate('Size') + + ' ' + + '
' + + translate('Scale') + ': ' + + '' + + translate('Linear') + + '' + + translate('Logarithmic') + + '' + + '
' + + '
' + + '
'; + return ret; }; -daytoday.prepareHtml = function daytodayPrepareHtml(sorteddaystoshow) { +daytoday.prepareHtml = function daytodayPrepareHtml (sorteddaystoshow) { $('#daytodaycharts').html(''); - sorteddaystoshow.forEach(function eachDay(d) { + sorteddaystoshow.forEach(function eachDay (d) { $('#daytodaycharts').append($('
').attr('width','20%').append(editIcon).append(deleteIcon).append(subject.name)) - .append($('').attr('width','20%').append(subject.roles ? subject.roles.join(', ') : '[none]')) - .append($('').attr('width','20%').append('' + subject.accessToken + '')) - .append($('').attr('width','10%').append(subject.notes ? subject.notes : '')) + table.append($('
').attr('width', '20%').append(editIcon).append(deleteIcon).append(subject.name)) + .append($('').attr('width', '20%').append(subject.roles ? subject.roles.join(', ') : '[none]')) + .append($('').attr('width', '20%').append('' + subject.accessToken + '')) + .append($('').attr('width', '10%').append(subject.notes ? subject.notes : '')) ); } function showSubjects (subjects, client) { var table = $('#admin_subjects_table'); - table.empty().append($('
').css('width','100px').attr('align','left').append(client.translate('Name'))) - .append($('').css('width','150px').attr('align','left').append(client.translate('Roles'))) - .append($('').css('width','150px').attr('align','left').append(client.translate('Access Token'))) - .append($('').css('width','150px').attr('align','left').append(client.translate('Notes'))) + table.empty().append($('
').css('width', '100px').attr('align', 'left').append(client.translate('Name'))) + .append($('').css('width', '150px').attr('align', 'left').append(client.translate('Roles'))) + .append($('').css('width', '150px').attr('align', 'left').append(client.translate('Access Token'))) + .append($('').css('width', '150px').attr('align', 'left').append(client.translate('Notes'))) ); - for (var t=0; t' + p + ''); }); $('#bc_profileLabel').toggle(isProfileEnabled(profiles)); - $('#bc_usebg').prop('checked','checked'); - $('#bc_usecarbs').prop('checked','checked'); - $('#bc_usecob').prop('checked',''); - $('#bc_useiob').prop('checked','checked'); - $('#bc_bgfromsensor').prop('checked','checked'); + $('#bc_usebg').prop('checked', 'checked'); + $('#bc_usecarbs').prop('checked', 'checked'); + $('#bc_usecob').prop('checked', ''); + $('#bc_useiob').prop('checked', 'checked'); + $('#bc_bgfromsensor').prop('checked', 'checked'); $('#bc_carbs').val(''); $('#bc_quickpick').val(-1); $('#bc_preBolus').val(0); @@ -189,9 +188,9 @@ function init(client, $) { boluscalc.calculateInsulin = function calculateInsulin (event) { maybePrevent(event); - boluscalc.gatherBoluscalcData( ); + boluscalc.gatherBoluscalcData(); boluscalc.updateGui(boluscalc.record); - return boluscalc.record; + return boluscalc.record; }; boluscalc.updateGui = function updateGui (record) { @@ -236,11 +235,11 @@ function init(client, $) { $('#bc_bg').css('background-color', ''); } $('#bc_inzulinbg').text(record.insulinbg.toFixed(2)); - $('#bc_inzulinbg').attr('title', - 'Target BG range: '+targetBGLow + ' - ' + targetBGHigh + - '\nISF: ' + isf + - '\nBG diff: ' + record.bgdiff.toFixed(1) - ); + $('#bc_inzulinbg').attr('title' + , 'Target BG range: ' + targetBGLow + ' - ' + targetBGHigh + + '\nISF: ' + isf + + '\nBG diff: ' + record.bgdiff.toFixed(1) + ); } else { $('#bc_inzulinbgtd').css('background-color', ''); $('#bc_bg').css('background-color', ''); @@ -252,51 +251,51 @@ function init(client, $) { if (record.foods.length) { var html = ''; var carbs = 0; - for (var fi=0; fi'; + html += ''; } html += ''; - html += ''; - html += ''; - html += ''; + html += ''; + html += ''; + html += ''; html += ''; } html += '
'+ f.name + ''+ (f.portion*f.portions).toFixed(1) + ' ' + translate(f.unit) + '('+ (f.carbs*f.portions).toFixed(1) + ' g)' + f.name + '' + (f.portion * f.portions).toFixed(1) + ' ' + translate(f.unit) + '(' + (f.carbs * f.portions).toFixed(1) + ' g)
'; $('#bc_food').html(html); $('.deleteFoodRecord').click(deleteFoodRecord); $('#bc_carbs').val(carbs.toFixed(0)); - $('#bc_carbs').attr('disabled',true); - $('#bc_gi').css('display','none'); - $('#bc_gicalculated').css('display',''); + $('#bc_carbs').attr('disabled', true); + $('#bc_gi').css('display', 'none'); + $('#bc_gicalculated').css('display', ''); $('#bc_gicalculated').text(record.gi); } else { $('#bc_food').html(''); - $('#bc_carbs').attr('disabled',false); - $('#bc_gi').css('display',''); - $('#bc_gicalculated').css('display','none'); + $('#bc_carbs').attr('disabled', false); + $('#bc_gi').css('display', ''); + $('#bc_gicalculated').css('display', 'none'); $('#bc_gicalculated').text(''); } // Show Carbs if ($('#bc_usecarbs').is(':checked')) { if ($('#bc_carbs').val() === '') { - $('#bc_carbs').css('background-color',''); - } else if (isNaN(parseInt($('#bc_carbs').val().replace(',','.')))) { - $('#bc_carbs').css('background-color','red'); + $('#bc_carbs').css('background-color', ''); + } else if (isNaN(parseInt($('#bc_carbs').val().replace(',', '.')))) { + $('#bc_carbs').css('background-color', 'red'); } else { - $('#bc_carbs').css('background-color',''); + $('#bc_carbs').css('background-color', ''); } $('#bc_inzulincarbs').text(record.insulincarbs.toFixed(2)); - $('#bc_inzulincarbs').attr('title','IC: ' + ic); + $('#bc_inzulincarbs').attr('title', 'IC: ' + ic); } else { - $('#bc_carbs').css('background-color',''); + $('#bc_carbs').css('background-color', ''); $('#bc_inzulincarbs').text(''); - $('#bc_inzulincarbs').attr('title',''); + $('#bc_inzulincarbs').attr('title', ''); $('#bc_carbs').text(''); } @@ -309,21 +308,21 @@ function init(client, $) { if (record.othercorrection === 0 && record.carbs === 0 && record.cob === 0 && record.bg > 0 && outcome > targetBGLow && outcome < targetBGHigh) { $('#bc_carbsneeded').text(''); $('#bc_insulinover').text(''); - $('#bc_carbsneededtr').css('display','none'); - $('#bc_insulinneededtr').css('display','none'); - $('#bc_calculationintarget').css('display',''); - } else if (record.insulin<0) { - $('#bc_carbsneeded').text(record.carbsneeded+' g'); + $('#bc_carbsneededtr').css('display', 'none'); + $('#bc_insulinneededtr').css('display', 'none'); + $('#bc_calculationintarget').css('display', ''); + } else if (record.insulin < 0) { + $('#bc_carbsneeded').text(record.carbsneeded + ' g'); $('#bc_insulinover').text(record.insulin.toFixed(2)); - $('#bc_carbsneededtr').css('display',''); - $('#bc_insulinneededtr').css('display','none'); - $('#bc_calculationintarget').css('display','none'); + $('#bc_carbsneededtr').css('display', ''); + $('#bc_insulinneededtr').css('display', 'none'); + $('#bc_calculationintarget').css('display', 'none'); } else { $('#bc_carbsneeded').text(''); $('#bc_insulinover').text(''); - $('#bc_carbsneededtr').css('display','none'); - $('#bc_insulinneededtr').css('display',''); - $('#bc_calculationintarget').css('display','none'); + $('#bc_carbsneededtr').css('display', 'none'); + $('#bc_insulinneededtr').css('display', ''); + $('#bc_calculationintarget').css('display', 'none'); } // Show basal rate @@ -335,7 +334,7 @@ function init(client, $) { $('#bc_basal').text(tempMark + basal.totalbasal.toFixed(3)); }; - boluscalc.gatherBoluscalcData = function gatherBoluscalcData() { + boluscalc.gatherBoluscalcData = function gatherBoluscalcData () { boluscalc.record = {}; var record = boluscalc.record; @@ -351,7 +350,6 @@ function init(client, $) { return; } - // Calculate event time from date & time record.eventTime = new Date(); if ($('#bc_othertime').is(':checked')) { @@ -373,19 +371,19 @@ function init(client, $) { record.ic = ic; if (targetBGLow === 0 || targetBGHigh === 0 || isf === 0 || ic === 0) { - $('#bc_inzulinbgtd').css('background-color','red'); + $('#bc_inzulinbgtd').css('background-color', 'red'); boluscalc.record = {}; return; } else { - $('#bc_inzulinbgtd').css('background-color',''); + $('#bc_inzulinbgtd').css('background-color', ''); } if (ic === 0) { - $('#bc_inzulincarbstd').css('background-color','red'); + $('#bc_inzulincarbstd').css('background-color', 'red'); boluscalc.record = {}; return; } else { - $('#bc_inzulincarbstd').css('background-color',''); + $('#bc_inzulincarbstd').css('background-color', ''); } // Load IOB @@ -407,7 +405,7 @@ function init(client, $) { record.insulinbg = 0; record.bgdiff = 0; if ($('#bc_usebg').is(':checked')) { - record.bg = parseFloat($('#bc_bg').val().replace(',','.')); + record.bg = parseFloat($('#bc_bg').val().replace(',', '.')); if (isNaN(record.bg)) { record.bg = 0; } @@ -417,7 +415,7 @@ function init(client, $) { record.bgdiff = record.bg - targetBGHigh; } record.bgdiff = roundTo(record.bgdiff, 0.1); - if (record.bg !== 0){ + if (record.bg !== 0) { record.insulinbg = roundTo(record.bgdiff / isf, 0.01); } } @@ -427,7 +425,7 @@ function init(client, $) { record.foods = _.cloneDeep(foods); if (record.foods.length) { var gisum = 0; - for (var fi=0; fi= 0) { @@ -613,16 +612,16 @@ function init(client, $) { var foodlist = []; var databaseloaded = false; var filter = { - category: '' + category: '' , subcategory: '' , name: '' }; - boluscalc.loadFoodDatabase = function loadFoodDatabase(event, callback) { + boluscalc.loadFoodDatabase = function loadFoodDatabase (event, callback) { categories = []; foodlist = []; var records = client.sbx.data.food || []; - records.forEach(function (r) { + records.forEach(function(r) { if (r.type == 'food') { foodlist.push(r); if (r.category && !categories[r.category]) { @@ -640,77 +639,77 @@ function init(client, $) { if (callback) { callback(); } }; - boluscalc.loadFoodQuickpicks = function loadFoodQuickpicks( ) { + boluscalc.loadFoodQuickpicks = function loadFoodQuickpicks () { // Load quickpicks quickpicks = []; var records = client.sbx.data.food || []; - records.forEach(function (r) { + records.forEach(function(r) { if (r.type == 'quickpick') { quickpicks.push(r); } }); $('#bc_quickpick').empty().append(''); - for (var i=0; i' + r.name + ' (' + r.carbs + ' g)'); - }; + $('#bc_quickpick').append(''); + } $('#bc_quickpick').val(-1); $('#bc_quickpick').change(quickpickChange); }; - function fillForm(event) { + function fillForm (event) { $('#bc_filter_category').empty().append(''); - Object.keys(categories).forEach( function eachCategory(s) { - $('#bc_filter_category').append(''); + Object.keys(categories).forEach(function eachCategory (s) { + $('#bc_filter_category').append(''); }); filter.category = ''; fillSubcategories(); $('#bc_filter_category').change(fillSubcategories); $('#bc_filter_subcategory').change(doFilter); - $('#bc_filter_name').on('input',doFilter); + $('#bc_filter_name').on('input', doFilter); maybePrevent(event); return false; } - function fillSubcategories(event) { + function fillSubcategories (event) { maybePrevent(event); filter.category = $('#bc_filter_category').val(); filter.subcategory = ''; $('#bc_filter_subcategory').empty().append(''); if (filter.category !== '') { - Object.keys(categories[filter.category]).forEach( function eachSubcategory(s) { - $('#bc_filter_subcategory').append(''); + Object.keys(categories[filter.category]).forEach(function eachSubcategory (s) { + $('#bc_filter_subcategory').append(''); }); } doFilter(); } - function doFilter(event) { + function doFilter (event) { if (event) { filter.category = $('#bc_filter_category').val(); filter.subcategory = $('#bc_filter_subcategory').val(); filter.name = $('#bc_filter_name').val(); } $('#bc_data').empty(); - for (var i=0; i' + o + ''); + o += 'Carbs: ' + foodlist[i].carbs + ' g'; + $('#bc_data').append(''); } $('#bc_addportions').val('1'); maybePrevent(event); } - function addFoodFromDatabase(event) { + function addFoodFromDatabase (event) { if (!databaseloaded) { boluscalc.loadFoodDatabase(event, addFoodFromDatabase); return; @@ -718,30 +717,32 @@ function init(client, $) { $('#bc_addportions').val('1'); $('#bc_addfooddialog').dialog({ - width: 640 + width: 640 , height: 400 - , buttons: [ - { text: translate('Add'), - click: function() { - var index = $('#bc_data').val(); - var portions = parseFloat($('#bc_addportions').val().replace(',','.')); - if (index !== null && !isNaN(portions) && portions >0) { - foodlist[index].portions = portions; - foods.push(_.cloneDeep(foodlist[index])); - $( this ).dialog( 'close' ); - boluscalc.calculateInsulin(); + , buttons: [ + { + text: translate('Add') + , click: function() { + var index = $('#bc_data').val(); + var portions = parseFloat($('#bc_addportions').val().replace(',', '.')); + if (index !== null && !isNaN(portions) && portions > 0) { + foodlist[index].portions = portions; + foods.push(_.cloneDeep(foodlist[index])); + $(this).dialog('close'); + boluscalc.calculateInsulin(); + } } - } - }, - { text: translate('Reload database'), - class: 'leftButton', - click: boluscalc.loadFoodDatabase + } + , { + text: translate('Reload database') + , class: 'leftButton' + , click: boluscalc.loadFoodDatabase } ] - , open : function() { + , open: function() { $(this).parent().css('box-shadow', '20px 20px 20px 0px black'); - $(this).parent().find('.ui-dialog-buttonset' ).css({'width':'100%','text-align':'right'}); - $(this).parent().find('button:contains("'+translate('Add')+'")').css({'float':'left'}); + $(this).parent().find('.ui-dialog-buttonset').css({ 'width': '100%', 'text-align': 'right' }); + $(this).parent().find('button:contains("' + translate('Add') + '")').css({ 'float': 'left' }); $('#bc_filter_name').focus(); } @@ -750,7 +751,7 @@ function init(client, $) { return false; } - function findClosestSGVToPastTime(time) { + function findClosestSGVToPastTime (time) { var nowData = client.entries.filter(function(d) { return d.type === 'sgv' && d.mills <= time.getTime(); }); @@ -766,12 +767,12 @@ function init(client, $) { // Make it faster on mobile devices $('.insulincalculationpart').change(boluscalc.calculateInsulin); } else { - $('.insulincalculationpart').on('input',boluscalc.calculateInsulin); + $('.insulincalculationpart').on('input', boluscalc.calculateInsulin); $('input:checkbox.insulincalculationpart').change(boluscalc.calculateInsulin); } $('#bc_bgfrommeter').change(boluscalc.calculateInsulin); $('#bc_addfromdatabase').click(addFoodFromDatabase); - $('#bc_bgfromsensor').change(function bc_bgfromsensor_click(event) { + $('#bc_bgfromsensor').change(function bc_bgfromsensor_click (event) { boluscalc.updateVisualisations(client.sbx); boluscalc.calculateInsulin(); maybePrevent(event); diff --git a/lib/client/browser-settings.js b/lib/client/browser-settings.js index bfac4df8067..d7782170b2a 100644 --- a/lib/client/browser-settings.js +++ b/lib/client/browser-settings.js @@ -8,18 +8,18 @@ var Storages = require('js-storage'); function init (client, serverSettings, $) { - serverSettings = serverSettings || {settings: {}}; + serverSettings = serverSettings || { settings: {} }; var storage = Storages.localStorage; var settings = require('../settings')(); - function loadForm ( ) { + function loadForm () { var utils = client.utils; var language = require('../language')(); language.set(settings.language); var translate = language.translate; - function appendThresholdValue(threshold) { + function appendThresholdValue (threshold) { return settings.alarmTypes.indexOf('simple') === -1 ? '' : ' (' + utils.scaleMgdl(threshold) + ')'; } @@ -61,8 +61,8 @@ function init (client, serverSettings, $) { var langSelect = $('#language'); - _.each(language.languages, function eachLanguage(lang) { - langSelect.append(''); + _.each(language.languages, function eachLanguage (lang) { + langSelect.append(''); }); langSelect.val(settings.language); @@ -79,7 +79,10 @@ function init (client, serverSettings, $) { var showPluginsSettings = $('#show-plugins'); var hasPluginsToShow = false; - client.plugins.eachEnabledPlugin(function each(plugin) { + + const pluginPrefs = []; + + client.plugins.eachEnabledPlugin(function each (plugin) { if (client.plugins.specialPlugins.indexOf(plugin.name) > -1) { //ignore these, they are always on for now } else { @@ -89,15 +92,53 @@ function init (client, serverSettings, $) { dd.find('input').prop('checked', settings.showPlugins.indexOf(plugin.name) > -1); hasPluginsToShow = true; } + + if (plugin.getClientPrefs) { + const prefs = plugin.getClientPrefs(); + pluginPrefs.push({ + plugin + , prefs + }) + } }); showPluginsSettings.toggle(hasPluginsToShow); + const bs = $('.browserSettings'); + const toggleCheckboxes = []; + + if (pluginPrefs.length > 0) { + pluginPrefs.forEach(function(e) { + // Only show settings if plugin is visible + if (settings.showPlugins.indexOf(e.plugin.name) > -1) { + const label = e.plugin.label; + const dl = $('
'); + dl.append(`
${label}
`); + e.prefs.forEach(function(p) { + const id = e.plugin.name + "-" + p.id; + const label = p.label; + if (p.type == 'boolean') { + const html = $(`
`); + dl.append(html); + if (storage.get(id) == true) { + toggleCheckboxes.push(id); + } + } + }); + bs.append(dl); + } + }); + } + + toggleCheckboxes.forEach(function(cb) { + $('#' + cb).prop('checked', true); + }); + $('#editprofilelink').toggle(settings.isEnabled('iob') || settings.isEnabled('cob') || settings.isEnabled('bwp') || settings.isEnabled('basal')); } - function wireForm ( ) { + function wireForm () { $('#useDefaults').click(function(event) { settings.eachSetting(function clearEachSetting (name) { storage.remove(name); @@ -108,43 +149,55 @@ function init (client, serverSettings, $) { }); $('#save').click(function(event) { - function checkedPluginNames() { + function checkedPluginNames () { var checkedPlugins = []; - $('#show-plugins input:checked').each(function eachPluginCheckbox(index, checkbox) { + $('#show-plugins input:checked').each(function eachPluginCheckbox (index, checkbox) { checkedPlugins.push($(checkbox).val()); }); return checkedPlugins.join(' '); } - function storeInBrowser(data) { - for (var k in data) { - if (data.hasOwnProperty(k)) { - storage.set(k, data[k]); - } + client.plugins.eachEnabledPlugin(function each (plugin) { + if (plugin.getClientPrefs) { + const prefs = plugin.getClientPrefs(); + + prefs.forEach(function(p) { + const id = plugin.name + "-" + p.id; + if (p.type == 'boolean') { + const val = $("#" + id).prop('checked'); + storage.set(id, val); + } + }); } + }); + + function storeInBrowser (data) { + Object.keys(data).forEach(k => { + storage.set(k, data[k]); + }); } storeInBrowser({ - units: $('input:radio[name=units-browser]:checked').val(), - alarmUrgentHigh: $('#alarm-urgenthigh-browser').prop('checked'), - alarmHigh: $('#alarm-high-browser').prop('checked'), - alarmLow: $('#alarm-low-browser').prop('checked'), - alarmUrgentLow: $('#alarm-urgentlow-browser').prop('checked'), - alarmTimeagoWarn: $('#alarm-timeagowarn-browser').prop('checked'), - alarmTimeagoWarnMins: parseInt($('#alarm-timeagowarnmins-browser').val()) || 15, - alarmTimeagoUrgent: $('#alarm-timeagourgent-browser').prop('checked'), - alarmTimeagoUrgentMins: parseInt($('#alarm-timeagourgentmins-browser').val()) || 30, - nightMode: $('#nightmode-browser').prop('checked'), - editMode: $('#editmode-browser').prop('checked'), - showRawbg: $('input:radio[name=show-rawbg]:checked').val(), - customTitle: $('input#customTitle').prop('value'), - theme: $('input:radio[name=theme-browser]:checked').val(), - timeFormat: parseInt($('input:radio[name=timeformat-browser]:checked').val()), - language: $('#language').val(), - scaleY: $('#scaleY').val(), - basalrender: $('#basalrender').val(), - showPlugins: checkedPluginNames(), - storageVersion: STORAGE_VERSION + units: $('input:radio[name=units-browser]:checked').val() + , alarmUrgentHigh: $('#alarm-urgenthigh-browser').prop('checked') + , alarmHigh: $('#alarm-high-browser').prop('checked') + , alarmLow: $('#alarm-low-browser').prop('checked') + , alarmUrgentLow: $('#alarm-urgentlow-browser').prop('checked') + , alarmTimeagoWarn: $('#alarm-timeagowarn-browser').prop('checked') + , alarmTimeagoWarnMins: parseInt($('#alarm-timeagowarnmins-browser').val()) || 15 + , alarmTimeagoUrgent: $('#alarm-timeagourgent-browser').prop('checked') + , alarmTimeagoUrgentMins: parseInt($('#alarm-timeagourgentmins-browser').val()) || 30 + , nightMode: $('#nightmode-browser').prop('checked') + , editMode: $('#editmode-browser').prop('checked') + , showRawbg: $('input:radio[name=show-rawbg]:checked').val() + , customTitle: $('input#customTitle').prop('value') + , theme: $('input:radio[name=theme-browser]:checked').val() + , timeFormat: parseInt($('input:radio[name=timeformat-browser]:checked').val()) + , language: $('#language').val() + , scaleY: $('#scaleY').val() + , basalrender: $('#basalrender').val() + , showPlugins: checkedPluginNames() + , storageVersion: STORAGE_VERSION }); event.preventDefault(); @@ -152,13 +205,13 @@ function init (client, serverSettings, $) { }); } - function showLocalstorageError ( ) { + function showLocalstorageError () { var msg = 'Settings are disabled.

Please enable cookies so you may customize your Nightscout site.'; - $('.browserSettings').html('Settings'+msg+''); + $('.browserSettings').html('Settings' + msg + ''); $('#save').hide(); } - function handleStorageVersions ( ) { + function handleStorageVersions () { var previousVersion = parseInt(storage.get('storageVersion')); //un-versioned settings @@ -174,7 +227,7 @@ function init (client, serverSettings, $) { } } - settings.extendedSettings = serverSettings.extendedSettings || {settings: {}}; + settings.extendedSettings = serverSettings.extendedSettings || { settings: {} }; try { settings.eachSetting(function setEach (name) { @@ -200,18 +253,42 @@ function init (client, serverSettings, $) { var stored = storage.get('basalrender'); settings.extendedSettings.basal.render = stored !== null ? stored : settings.extendedSettings.basal.render; - } catch(err) { + + } catch (err) { console.error(err); showLocalstorageError(); } - init.loadAndWireForm = function loadAndWireForm ( ) { + init.loadAndWireForm = function loadAndWireForm () { loadForm(); wireForm(); }; + init.loadPluginSettings = function loadPluginSettings (client) { + + client.plugins.eachEnabledPlugin(function each (plugin) { + if (plugin.getClientPrefs) { + const prefs = plugin.getClientPrefs(); + + if (!settings.extendedSettings[plugin.name]) { + settings.extendedSettings[plugin.name] = {}; + } + + const settingsBase = settings.extendedSettings[plugin.name]; + + prefs.forEach(function(p) { + const id = plugin.name + "-" + p.id; + const stored = storage.get(id); + if (stored !== null) { + settingsBase[p.id] = stored; + } + }); + } + }); + + } + return settings; } - module.exports = init; diff --git a/lib/client/browser-utils.js b/lib/client/browser-utils.js index fc9a983d0e0..4f920588f80 100644 --- a/lib/client/browser-utils.js +++ b/lib/client/browser-utils.js @@ -13,9 +13,9 @@ function init ($) { $('#drawer').find('.tip').tooltip(); } $.fn.tooltip.defaults = { - fade: true, - gravity: 'n', - opacity: 0.75 + fade: true + , gravity: 'n' + , opacity: 0.75 }; var querystring = queryParms(); @@ -38,31 +38,30 @@ function init ($) { event.preventDefault(); }); - $('.navigation a').click(function navigationClick ( ) { + $('.navigation a').click(function navigationClick () { closeDrawer('#drawer'); }); - function reload() { + function reload () { //strip '#' so form submission does not fail var url = window.location.href; url = url.replace(/#$/, ''); window.location.href = url; } - - function queryParms() { + function queryParms () { var params = {}; if (location.search) { location.search.substr(1).split('&').forEach(function(item) { + // eslint-disable-next-line no-useless-escape params[item.split('=')[0]] = item.split('=')[1].replace(/[_\+]/g, ' '); }); } return params; } - function isTouch() { - try { document.createEvent('TouchEvent'); return true; } - catch (e) { return false; } + function isTouch () { + try { document.createEvent('TouchEvent'); return true; } catch (e) { return false; } } function closeLastOpenedDrawer (callback) { @@ -73,15 +72,15 @@ function init ($) { } } - function closeDrawer(id, callback) { + function closeDrawer (id, callback) { lastOpenedDrawer = null; $('html, body').css({ scrollTop: 0 }); - $(id).css({display: 'none', right: '-300px'}); + $(id).css({ display: 'none', right: '-300px' }); if (callback) { callback(); } } - function openDrawer(id, prepare) { - function closeOpenDraw(callback) { + function openDrawer (id, prepare) { + function closeOpenDraw (callback) { if (lastOpenedDrawer) { closeDrawer(lastOpenedDrawer, callback); } else { @@ -89,11 +88,11 @@ function init ($) { } } - closeOpenDraw(function () { + closeOpenDraw(function() { lastOpenedDrawer = id; if (prepare) { prepare(); } - var style = {display:'block', right: '0'}; + var style = { display: 'block', right: '0' }; var windowWidth = $(window).width(); var windowHeight = $(window).height(); @@ -114,13 +113,12 @@ function init ($) { style.width = '350px'; } - $(id).css(style); }); } - function toggleDrawer(id, openPrepare, closeCallback) { + function toggleDrawer (id, openPrepare, closeCallback) { if (lastOpenedDrawer === id) { closeDrawer(id, closeCallback); } else { @@ -128,13 +126,13 @@ function init ($) { } } - function closeNotification() { + function closeNotification () { var notify = $('#notification'); notify.hide(); notify.find('span').html(''); } - function showNotification(note, type) { + function showNotification (note, type) { var notify = $('#notification'); notify.hide(); @@ -150,10 +148,10 @@ function init ($) { notify.show(); } - function getLastOpenedDrawer() { + function getLastOpenedDrawer () { return lastOpenedDrawer; } - + return { reload: reload , queryParms: queryParms diff --git a/lib/client/careportal.js b/lib/client/careportal.js index f6c73c2abb3..7b39ce6d2c4 100644 --- a/lib/client/careportal.js +++ b/lib/client/careportal.js @@ -7,7 +7,7 @@ var times = require('../times'); var Storages = require('js-storage'); function init (client, $) { - var careportal = { }; + var careportal = {}; var translate = client.translate; var storage = Storages.localStorage; @@ -18,7 +18,7 @@ function init (client, $) { careportal.events = _.map(careportal.allEventTypes, function each (event) { return _.pick(event, ['val', 'name']); }); - + var eventTime = $('#eventTimeValue'); var eventDate = $('#eventDateValue'); @@ -28,11 +28,11 @@ function init (client, $) { eventDate.val(time.format('YYYY-MM-DD')); } - function mergeDateAndTime ( ) { + function mergeDateAndTime () { return client.utils.mergeInputTime(eventTime.val(), eventDate.val()); } - function updateTime(ele, time) { + function updateTime (ele, time) { ele.attr('oldminutes', time.minutes()); ele.attr('oldhours', time.hours()); } @@ -46,12 +46,12 @@ function init (client, $) { var inputMatrix = {}; _.forEach(careportal.allEventTypes, function each (event) { - inputMatrix[event.val] = _.pick(event, ['bg', 'insulin', 'carbs', 'prebolus', 'duration', 'percent', 'absolute', 'profile', 'split', 'reasons', 'targets']); + inputMatrix[event.val] = _.pick(event, ['bg', 'insulin', 'carbs', 'protein', 'fat', 'prebolus', 'duration', 'percent', 'absolute', 'profile', 'split', 'reasons', 'targets']); }); - careportal.filterInputs = function filterInputs ( event ) { + careportal.filterInputs = function filterInputs (event) { var eventType = $('#eventType').val(); - + function displayType (enabled) { if (enabled) { return ''; @@ -59,26 +59,28 @@ function init (client, $) { return 'none'; } } - - function resetIfHidden(visible, id) { + + function resetIfHidden (visible, id) { if (!visible) { $(id).val(''); } } var reasons = inputMatrix[eventType]['reasons']; - $('#reasonLabel').css('display',displayType(reasons && reasons.length > 0)); - $('#targets').css('display',displayType(inputMatrix[eventType]['targets'])); - - $('#bg').css('display',displayType(inputMatrix[eventType]['bg'])); - $('#insulinGivenLabel').css('display',displayType(inputMatrix[eventType]['insulin'])); - $('#carbsGivenLabel').css('display',displayType(inputMatrix[eventType]['carbs'])); - $('#durationLabel').css('display',displayType(inputMatrix[eventType]['duration'])); - $('#percentLabel').css('display',displayType(inputMatrix[eventType]['percent'] && $('#absolute').val() === '')); - $('#absoluteLabel').css('display',displayType(inputMatrix[eventType]['absolute'] && $('#percent').val() === '')); - $('#profileLabel').css('display',displayType(inputMatrix[eventType]['profile'])); - $('#preBolusLabel').css('display',displayType(inputMatrix[eventType]['prebolus'])); - $('#insulinSplitLabel').css('display',displayType(inputMatrix[eventType]['split'])); + $('#reasonLabel').css('display', displayType(reasons && reasons.length > 0)); + $('#targets').css('display', displayType(inputMatrix[eventType]['targets'])); + + $('#bg').css('display', displayType(inputMatrix[eventType]['bg'])); + $('#insulinGivenLabel').css('display', displayType(inputMatrix[eventType]['insulin'])); + $('#carbsGivenLabel').css('display', displayType(inputMatrix[eventType]['carbs'])); + $('#proteinGivenLabel').css('display', displayType(inputMatrix[eventType]['protein'])); + $('#fatGivenLabel').css('display', displayType(inputMatrix[eventType]['fat'])); + $('#durationLabel').css('display', displayType(inputMatrix[eventType]['duration'])); + $('#percentLabel').css('display', displayType(inputMatrix[eventType]['percent'] && $('#absolute').val() === '')); + $('#absoluteLabel').css('display', displayType(inputMatrix[eventType]['absolute'] && $('#percent').val() === '')); + $('#profileLabel').css('display', displayType(inputMatrix[eventType]['profile'])); + $('#preBolusLabel').css('display', displayType(inputMatrix[eventType]['prebolus'])); + $('#insulinSplitLabel').css('display', displayType(inputMatrix[eventType]['split'])); $('#reason').empty(); _.each(reasons, function eachReason (reason) { @@ -89,6 +91,8 @@ function init (client, $) { resetIfHidden(inputMatrix[eventType]['insulin'], '#insulinGiven'); resetIfHidden(inputMatrix[eventType]['carbs'], '#carbsGiven'); + resetIfHidden(inputMatrix[eventType]['protein'], '#proteinGiven'); + resetIfHidden(inputMatrix[eventType]['fat'], '#fatGiven'); resetIfHidden(inputMatrix[eventType]['duration'], '#duration'); resetIfHidden(inputMatrix[eventType]['absolute'], '#absolute'); resetIfHidden(inputMatrix[eventType]['percent'], '#percent'); @@ -99,7 +103,7 @@ function init (client, $) { maybePrevent(event); }; - careportal.reasonable = function reasonable ( ) { + careportal.reasonable = function reasonable () { var eventType = $('#eventType').val(); var reasons = inputMatrix[eventType]['reasons']; var selected = $('#reason').val(); @@ -129,10 +133,10 @@ function init (client, $) { } }; - careportal.prepareEvents = function prepareEvents ( ) { + careportal.prepareEvents = function prepareEvents () { $('#eventType').empty(); - _.each(careportal.events, function eachEvent(event) { - $('#eventType').append(''); + _.each(careportal.events, function eachEvent (event) { + $('#eventType').append(''); }); $('#eventType').change(careportal.filterInputs); $('#reason').change(careportal.reasonable); @@ -144,7 +148,7 @@ function init (client, $) { careportal.adjustSplit(); }; - careportal.adjustSplit = function adjustSplit(event) { + careportal.adjustSplit = function adjustSplit (event) { if ($(this).attr('id') === 'insulinSplitNow') { var nowval = parseInt($('#insulinSplitNow').val()) || 0; $('#insulinSplitExt').val(100 - nowval); @@ -154,12 +158,12 @@ function init (client, $) { $('#insulinSplitNow').val(100 - extval); $('#insulinSplitExt').val(extval); } - + maybePrevent(event); }; - - careportal.resolveEventName = function resolveEventName(value) { - _.each(careportal.events, function eachEvent(e) { + + careportal.resolveEventName = function resolveEventName (value) { + _.each(careportal.events, function eachEvent (e) { if (e.val === value) { value = e.name; } @@ -167,9 +171,9 @@ function init (client, $) { return value; }; - careportal.prepare = function prepare ( ) { + careportal.prepare = function prepare () { $('#profile').empty(); - client.profilefunctions.listBasalProfiles().forEach(function (p) { + client.profilefunctions.listBasalProfiles().forEach(function(p) { $('#profile').append(''); }); careportal.prepareEvents(); @@ -177,6 +181,8 @@ function init (client, $) { $('#glucoseValue').val('').attr('placeholder', translate('Value in') + ' ' + client.settings.units); $('#meter').prop('checked', true); $('#carbsGiven').val(''); + $('#proteinGiven').val(''); + $('#fatGiven').val(''); $('#insulinGiven').val(''); $('#duration').val(''); $('#percent').val(''); @@ -189,29 +195,31 @@ function init (client, $) { setDateAndTime(); }; - function gatherData ( ) { + function gatherData () { var data = { enteredBy: $('#enteredBy').val() - , eventType: $('#eventType').val() - , glucose: $('#glucoseValue').val().replace(',','.') - , reason: $('#reason').val() - , targetTop: $('#targetTop').val().replace(',','.') - , targetBottom: $('#targetBottom').val().replace(',','.') - , glucoseType: $('#treatment-form').find('input[name=glucoseType]:checked').val() - , carbs: $('#carbsGiven').val() - , insulin: $('#insulinGiven').val() - , duration: times.msecs(parse_duration($('#duration').val())).mins < 1 ? $('#duration').val() : times.msecs(parse_duration($('#duration').val())).mins - , percent: $('#percent').val() - , profile: $('#profile').val() - , preBolus: parseInt($('#preBolus').val()) - , notes: $('#notes').val() - , units: client.settings.units + , eventType: $('#eventType').val() + , glucose: $('#glucoseValue').val().replace(',', '.') + , reason: $('#reason').val() + , targetTop: $('#targetTop').val().replace(',', '.') + , targetBottom: $('#targetBottom').val().replace(',', '.') + , glucoseType: $('#treatment-form').find('input[name=glucoseType]:checked').val() + , carbs: $('#carbsGiven').val() + , protein: $('#proteinGiven').val() + , fat: $('#fatGiven').val() + , insulin: $('#insulinGiven').val() + , duration: times.msecs(parse_duration($('#duration').val())).mins < 1 ? $('#duration').val() : times.msecs(parse_duration($('#duration').val())).mins + , percent: $('#percent').val() + , profile: $('#profile').val() + , preBolus: parseInt($('#preBolus').val()) + , notes: $('#notes').val() + , units: client.settings.units }; - if (units == "mmol") { - data.targetTop = data.targetTop * 18; - data.targetBottom = data.targetBottom * 18; - } + if (units == "mmol") { + data.targetTop = data.targetTop * 18; + data.targetBottom = data.targetBottom * 18; + } //special handling for absolute to support temp to 0 var absolute = $('#absolute').val(); @@ -222,7 +230,7 @@ function init (client, $) { if ($('#othertime').is(':checked')) { data.eventTime = mergeDateAndTime().toDate(); } - + if (!inputMatrix[data.eventType].profile) { delete data.profile; } @@ -250,7 +258,59 @@ function init (client, $) { maybePrevent(event); }; - function buildConfirmText(data) { + function validateData (data) { + + let allOk = true; + let messages = []; + + console.log('Validating careportal entry: ', data.eventType); + + if (data.eventType == 'Temporary Target') { + if (isNaN(data.targetTop) || isNaN(data.targetBottom) || !data.targetBottom || !data.targetTop) { + console.log('Bottom or Top target missing'); + allOk = false; + messages.push("Please enter a valid value for both top and bottom target to save a Temporary Target"); + } else { + + let targetTop = data.targetTop; + let targetBottom = data.targetBottom; + + let minTarget = 4 * 18; + let maxTarget = 18 * 18; + + if (units == "mmol") { + targetTop = Math.round(targetTop / 18.0 * 10) / 10; + targetBottom = Math.round(targetBottom / 18.0 * 10) / 10; + minTarget = Math.round(minTarget / 18.0 * 10) / 10; + maxTarget = Math.round(maxTarget / 18.0 * 10) / 10; + } + + if (targetTop > maxTarget) { + allOk = false; + messages.push("Temporary target high is too high"); + } + + if (targetBottom < minTarget) { + allOk = false; + messages.push("Temporary target low is too low"); + } + + if (targetTop < targetBottom || targetBottom > targetTop) { + allOk = false; + messages.push("The low target must be lower than the high target and high target must be higher than the low target."); + } + + } + } + + return { + allOk + , messages + }; + + } + + function buildConfirmText (data) { var text = [ translate('Please verify that the data entered is correct') + ': ' , translate('Event Type') + ': ' + translate(careportal.resolveEventName(data.eventType)) @@ -263,26 +323,28 @@ function init (client, $) { } if (data.duration === 0 && data.eventType === 'Temporary Target') { - text[text.length - 1] += ' ' + translate('Cancel'); + text[text.length - 1] += ' ' + translate('Cancel'); } pushIf(data.glucose, translate('Blood Glucose') + ': ' + data.glucose); pushIf(data.glucose, translate('Measurement Method') + ': ' + translate(data.glucoseType)); pushIf(data.reason, translate('Reason') + ': ' + data.reason); - + var targetTop = data.targetTop; var targetBottom = data.targetBottom; - + if (units == "mmol") { - targetTop = Math.round(data.targetTop / 18.0 * 10) / 10; - targetBottom = Math.round(data.targetBottom / 18.0 * 10) / 10; - } - + targetTop = Math.round(data.targetTop / 18.0 * 10) / 10; + targetBottom = Math.round(data.targetBottom / 18.0 * 10) / 10; + } + pushIf(data.targetTop, translate('Target Top') + ': ' + targetTop); pushIf(data.targetBottom, translate('Target Bottom') + ': ' + targetBottom); pushIf(data.carbs, translate('Carbs Given') + ': ' + data.carbs); + pushIf(data.protein, translate('Protein Given') + ': ' + data.protein); + pushIf(data.fat, translate('Fat Given') + ': ' + data.fat); pushIf(data.insulin, translate('Insulin Given') + ': ' + data.insulin); pushIf(data.eventType === 'Combo Bolus', translate('Combo Bolus') + ': ' + data.splitNow + '% : ' + data.splitExt + '%'); pushIf(data.duration, translate('Duration') + ': ' + data.duration + ' ' + translate('mins')); @@ -297,13 +359,27 @@ function init (client, $) { return text.join('\n'); } - function confirmPost(data) { - if (window.confirm(buildConfirmText(data))) { - postTreatment(data); + function confirmPost (data) { + + const validation = validateData(data); + + if (!validation.allOk) { + + let messages = ""; + + validation.messages.forEach(function(m) { + messages += translate(m) + "\n"; + }); + + window.alert(messages); + } else { + if (window.confirm(buildConfirmText(data))) { + postTreatment(data); + } } } - function postTreatment(data) { + function postTreatment (data) { if (data.eventType === 'Combo Bolus') { data.enteredinsulin = data.insulin; data.insulin = data.enteredinsulin * data.splitNow / 100; @@ -312,9 +388,9 @@ function init (client, $) { $.ajax({ method: 'POST' - , url: '/api/v1/treatments/' - , headers: client.headers() - , data: data + , url: '/api/v1/treatments/' + , headers: client.headers() + , data: data }).done(function treatmentSaved (response) { console.info('treatment saved', response); }).fail(function treatmentSaveFail (response) { @@ -326,7 +402,7 @@ function init (client, $) { client.browserUtils.closeDrawer('#treatmentDrawer'); } - + careportal.dateTimeFocus = function dateTimeFocus (event) { $('#othertime').prop('checked', true); updateTime($(this), mergeDateAndTime()); @@ -374,4 +450,3 @@ function init (client, $) { } module.exports = init; - diff --git a/lib/client/clock-client.js b/lib/client/clock-client.js new file mode 100644 index 00000000000..2b4c063ff9f --- /dev/null +++ b/lib/client/clock-client.js @@ -0,0 +1,149 @@ +'use strict'; + +const browserSettings = require('./browser-settings'); + +var client = {}; + +client.settings = browserSettings(client, window.serverSettings, $); + +// console.log('settings', client.settings); +// client.settings now contains all settings + +client.query = function query () { + console.log('query'); + $.ajax('/api/v1/entries.json?count=3', { + success: client.render + }); +} + +client.render = function render (xhr) { + console.log('got data', xhr); + + let rec; + + xhr.some(element => { + if (element.sgv) { + rec = element; + return true; + } + }); + + let last = new Date(rec.date); + let now = new Date(); + + // Convert BG to mmol/L if necessary. + if (window.serverSettings.settings.units == 'mmol') { + var displayValue = window.Nightscout.units.mgdlToMMOL(rec.sgv); + } else { + displayValue = rec.sgv; + } + + // Insert the BG value text. + $('#bgnow').html(displayValue); + + // Insert the trend arrow. + $('#arrow').attr('src', '/images/' + rec.direction + '.svg'); + + // Time before data considered stale. + let staleMinutes = 13; + let threshold = 1000 * 60 * staleMinutes; + + // Toggle stale if necessary. + $('#bgnow').toggleClass('stale', (now - last > threshold)); + + // Generate and insert the clock. + let timeDivisor = (client.settings.timeFormat) ? client.settings.timeFormat : 12; + let today = new Date() + , h = today.getHours() % timeDivisor; + if (timeDivisor == 12) { + h = (h == 0) ? 12 : h; // In the case of 00:xx, change to 12:xx for 12h time + } + if (timeDivisor == 24) { + h = (h < 10) ? ("0" + h) : h; // Pad the hours with a 0 in 24h time + } + let m = today.getMinutes(); + if (m < 10) m = "0" + m; + $('#clock').text(h + ":" + m); + + var queryDict = {}; + location.search.substr(1).split("&").forEach(function(item) { queryDict[item.split("=")[0]] = item.split("=")[1] }); + + if (!window.serverSettings.settings.showClockClosebutton || !queryDict['showClockClosebutton']) { + $('#close').css('display', 'none'); + } + + // defined in the template this is loaded into + // eslint-disable-next-line no-undef + if (clockFace == 'clock-color') { + + var bgHigh = window.serverSettings.settings.thresholds.bgHigh; + var bgLow = window.serverSettings.settings.thresholds.bgLow; + var bgTargetBottom = window.serverSettings.settings.thresholds.bgTargetBottom; + var bgTargetTop = window.serverSettings.settings.thresholds.bgTargetTop; + + var bgNum = parseFloat(rec.sgv); + + // These are the particular shades of red, yellow, green, and blue. + var red = 'rgba(213,9,21,1)'; + var yellow = 'rgba(234,168,0,1)'; + var green = 'rgba(134,207,70,1)'; + var blue = 'rgba(78,143,207,1)'; + + var darkRed = 'rgba(183,9,21,1)'; + var darkYellow = 'rgba(214,168,0,1)'; + var darkGreen = 'rgba(110,192,70,1)'; + var darkBlue = 'rgba(78,143,187,1)'; + + var elapsedMins = Math.round(((now - last) / 1000) / 60); + + // Insert the BG stale time text. + $('#staleTime').text(elapsedMins + ' minutes ago'); + + // Threshold background coloring. + if (bgNum < bgLow) { + $('body').css('background-color', red); + $('#close').css('border-color', darkRed); + $('#close').css('color', darkRed); + } + if ((bgLow <= bgNum) && (bgNum < bgTargetBottom)) { + $('body').css('background-color', blue); + $('#close').css('border-color', darkBlue); + $('#close').css('color', darkBlue); + } + if ((bgTargetBottom <= bgNum) && (bgNum < bgTargetTop)) { + $('body').css('background-color', green); + $('#close').css('border-color', darkGreen); + $('#close').css('color', darkGreen); + } + if ((bgTargetTop <= bgNum) && (bgNum < bgHigh)) { + $('body').css('background-color', yellow); + $('#close').css('border-color', darkYellow); + $('#close').css('color', darkYellow); + } + if (bgNum >= bgHigh) { + $('body').css('background-color', red); + $('#close').css('border-color', darkRed); + $('#close').css('color', darkRed); + } + + // Restyle body bg, and make the "x minutes ago" visible too. + if (now - last > threshold) { + $('body').css('background-color', 'grey'); + $('body').css('color', 'black'); + $('#staleTime').css('display', 'block'); + $('#arrow').css('filter', 'brightness(0%)'); + } else { + $('#staleTime').css('display', 'none'); + $('body').css('color', 'white'); + $('#arrow').css('filter', 'brightness(100%)'); + } + } +} + +client.init = function init () { + console.log('init'); + client.query(); + setInterval(client.query, 1 * 60 * 1000); +} + +module.exports = client; diff --git a/lib/client/index.js b/lib/client/index.js index 354901bc899..63b37d7c9ed 100644 --- a/lib/client/index.js +++ b/lib/client/index.js @@ -16,13 +16,13 @@ var levels = require('../levels'); var times = require('../times'); var receiveDData = require('./receiveddata'); -var client = { }; +var client = {}; $('#loadingMessageText').html('Connecting to server'); client.hashauth = require('../hashauth').init(client, $); -client.headers = function headers ( ) { +client.headers = function headers () { if (client.authorized) { return { Authorization: 'Bearer ' + client.authorized.token @@ -32,11 +32,11 @@ client.headers = function headers ( ) { 'api-secret': client.hashauth.hash() }; } else { - return { }; + return {}; } }; -client.init = function init(callback) { +client.init = function init (callback) { client.browserUtils = require('./browser-utils')($); @@ -60,16 +60,17 @@ client.init = function init(callback) { console.log('Application appears to be online'); $('#centerMessagePanel').hide(); client.load(serverSettings, callback); - }).fail(function fail(jqXHR, textStatus, errorThrown) { + // eslint-disable-next-line no-unused-vars + }).fail(function fail (jqXHR, textStatus, errorThrown) { - // check if we couldn't reach the server at all, show offline message - if (jqXHR.readyState == 0) { + // check if we couldn't reach the server at all, show offline message + if (jqXHR.readyState == 0) { console.log('Application appears to be OFFLINE'); $('#loadingMessageText').html('Connecting to Nightscout server failed, retrying every 2 seconds'); window.setTimeout(window.Nightscout.client.init(), 2000); return; - } - + } + //no server setting available, use defaults, auth, etc if (client.settingsFailed) { console.log('Already tried to get settings after auth, but failed'); @@ -77,9 +78,9 @@ client.init = function init(callback) { client.settingsFailed = true; language.set('en'); client.translate = language.translate; - // auth failed, hide loader and request for key - $('#centerMessagePanel').hide(); - client.hashauth.requestAuthentication(function afterRequest ( ) { + // auth failed, hide loader and request for key + $('#centerMessagePanel').hide(); + client.hashauth.requestAuthentication(function afterRequest () { client.init(null, callback); }); } @@ -87,23 +88,21 @@ client.init = function init(callback) { }; -client.load = function load(serverSettings, callback) { +client.load = function load (serverSettings, callback) { var UPDATE_TRANS_MS = 750 // milliseconds , FORMAT_TIME_12 = '%-I:%M %p' , FORMAT_TIME_12_COMPACT = '%-I:%M' , FORMAT_TIME_24 = '%H:%M%' , FORMAT_TIME_12_SCALE = '%-I %p' - , FORMAT_TIME_24_SCALE = '%H' - ; + , FORMAT_TIME_24_SCALE = '%H'; var history = 48; - + var chart , socket , isInitialData = false - , prevSGV - , opacity = {current: 1, DAY: 1, NIGHT: 0.5} + , opacity = { current: 1, DAY: 1, NIGHT: 0.5 } , clientAlarms = {} , alarmInProgress = false , alarmMessage @@ -111,8 +110,7 @@ client.load = function load(serverSettings, callback) { , currentAnnouncement , alarmSound = 'alarm.mp3' , urgentAlarmSound = 'alarm2.mp3' - , previousNotifyTimestamp - ; + , previousNotifyTimestamp; client.entryToDate = function entryToDate (entry) { return new Date(entry.mills); }; @@ -130,8 +128,7 @@ client.load = function load(serverSettings, callback) { , minorPills = $('.bgStatus .minorPills') , statusPills = $('.status .statusPills') , primary = $('.primary') - , editButton = $('#editbutton') - ; + , editButton = $('#editbutton'); client.tooltip = d3.select('body').append('div') .attr('class', 'tooltip') @@ -146,9 +143,12 @@ client.load = function load(serverSettings, callback) { client.plugins = require('../plugins/')({ settings: client.settings + , extendedSettings: client.settings.extendedSettings , language: language }).registerClientDefaults(); + browserSettings.loadPluginSettings(client); + client.utils = require('../utils')({ settings: client.settings , language: language @@ -236,7 +236,7 @@ client.load = function load(serverSettings, callback) { client.boluscalc = require('./boluscalc')(client, $); client.profilefunctions = profile; - + client.editMode = false; //TODO: use the bus for updates and notifications @@ -248,13 +248,13 @@ client.load = function load(serverSettings, callback) { //start the bus after setting up listeners //client.ctx.bus.uptime( ); - client.dataExtent = function dataExtent ( ) { + client.dataExtent = function dataExtent () { return client.entries.length > 0 ? - d3.extent(client.entries, client.entryToDate) - : d3.extent([new Date(client.now - times.hours(history).msecs), new Date(client.now)]); + d3.extent(client.entries, client.entryToDate) : + d3.extent([new Date(client.now - times.hours(history).msecs), new Date(client.now)]); }; - client.bottomOfPills = function bottomOfPills ( ) { + client.bottomOfPills = function bottomOfPills () { //the offset's might not exist for some tests var bottomOfPrimary = primary.offset() ? primary.offset().top + primary.height() : 0; var bottomOfMinorPills = minorPills.offset() ? minorPills.offset().top + minorPills.height() : 0; @@ -262,7 +262,7 @@ client.load = function load(serverSettings, callback) { return Math.max(bottomOfPrimary, bottomOfMinorPills, bottomOfStatusPills); }; - function formatTime(time, compact) { + function formatTime (time, compact) { var timeFormat = getTimeFormat(false, compact); time = d3.time.format(timeFormat)(time); if (client.settings.timeFormat !== 24) { @@ -271,7 +271,7 @@ client.load = function load(serverSettings, callback) { return time; } - function getTimeFormat(isForScale, compact) { + function getTimeFormat (isForScale, compact) { var timeFormat = FORMAT_TIME_12; if (client.settings.timeFormat === 24) { timeFormat = isForScale ? FORMAT_TIME_24_SCALE : FORMAT_TIME_24; @@ -283,7 +283,7 @@ client.load = function load(serverSettings, callback) { } //TODO: replace with utils.scaleMgdl and/or utils.roundBGForDisplay - function scaleBg(bg) { + function scaleBg (bg) { if (client.settings.units === 'mmol') { return units.mgdlToMMOL(bg); } else { @@ -291,8 +291,8 @@ client.load = function load(serverSettings, callback) { } } - function generateTitle ( ) { - function s(value, sep) { return value ? value + ' ' : sep || ''; } + function generateTitle () { + function s (value, sep) { return value ? value + ' ' : sep || ''; } var title = ''; @@ -300,7 +300,7 @@ client.load = function load(serverSettings, callback) { if (status !== 'current') { var ago = client.timeago.calcDisplay(client.sbx.lastSGVEntry(), client.sbx.time); - title = s(ago.value) + s(ago.label, ' - ') + title; + title = s(ago.value) + s(ago.label, ' - ') + title; } else if (client.latestSGV) { var currentMgdl = client.latestSGV.mgdl; @@ -317,12 +317,12 @@ client.load = function load(serverSettings, callback) { return title; } - function resetCustomTitle ( ) { + function resetCustomTitle () { var customTitle = client.settings.customTitle || 'Nightscout'; $('.customTitle').text(customTitle); } - function checkAnnouncement() { + function checkAnnouncement () { var result = { inProgress: currentAnnouncement ? Date.now() - currentAnnouncement.received < times.mins(5).msecs : false }; @@ -339,19 +339,19 @@ client.load = function load(serverSettings, callback) { return result; } - function updateTitle ( ) { + function updateTitle () { var windowTitle; var announcementStatus = checkAnnouncement(); if (alarmMessage && alarmInProgress) { $('.customTitle').text(alarmMessage); - if (!isTimeAgoAlarmType( )) { + if (!isTimeAgoAlarmType()) { windowTitle = alarmMessage + ': ' + generateTitle(); } } else if (announcementStatus.inProgress && announcementStatus.message) { windowTitle = announcementStatus.message + ': ' + generateTitle(); - } else { + } else { resetCustomTitle(); } @@ -360,8 +360,8 @@ client.load = function load(serverSettings, callback) { $(document).attr('title', windowTitle || generateTitle()); } -// clears the current user brush and resets to the current real time data - function updateBrushToNow(skipBrushing) { + // clears the current user brush and resets to the current real time data + function updateBrushToNow (skipBrushing) { // get current time range var dataRange = client.dataExtent(); @@ -377,15 +377,15 @@ client.load = function load(serverSettings, callback) { } } - function alarmingNow() { + function alarmingNow () { return container.hasClass('alarming'); } - function inRetroMode() { + function inRetroMode () { return chart && chart.inRetroMode(); } - function brushed ( ) { + function brushed () { var brushExtent = chart.brush.extent(); @@ -403,7 +403,7 @@ client.load = function load(serverSettings, callback) { } } - function adjustCurrentSGVClasses(value, isCurrent) { + function adjustCurrentSGVClasses (value, isCurrent) { var reallyCurrentAndNotAlarming = isCurrent && !inRetroMode() && !alarmingNow(); bgStatus.toggleClass('current', alarmingNow() || reallyCurrentAndNotAlarming); @@ -469,7 +469,7 @@ client.load = function load(serverSettings, callback) { forecastOption.append(forecastLabel); forecastLabel.append(forecastCheckbox); forecastLabel.append('Show ' + info.label + ''); - forecastCheckbox.change(function onChange(event) { + forecastCheckbox.change(function onChange (event) { var checkbox = $(event.target); var type = checkbox.attr('data-forecast-type'); var checked = checkbox.prop('checked'); @@ -477,7 +477,7 @@ client.load = function load(serverSettings, callback) { client.settings.showForecast += ' ' + type; } else { client.settings.showForecast = _.chain(client.settings.showForecast.split(' ')) - .filter(function (forecast) { return forecast !== type; }) + .filter(function(forecast) { return forecast !== type; }) .value() .join(' '); } @@ -491,7 +491,7 @@ client.load = function load(serverSettings, callback) { client.boluscalc.updateVisualisations(client.sbx); } - function clearCurrentSGV ( ) { + function clearCurrentSGV () { currentBG.text('---'); container.removeClass('urgent warning inrange'); } @@ -502,7 +502,7 @@ client.load = function load(serverSettings, callback) { }); var focusPoint = _.last(nowData); - function updateHeader() { + function updateHeader () { if (inRetroMode()) { nowDate = brushExtent[1]; $('#currentTime') @@ -533,10 +533,10 @@ client.load = function load(serverSettings, callback) { } var top = (client.bottomOfPills() + 5); - $('#chartContainer').css({top: top + 'px', height: $(window).height() - top - 10}); + $('#chartContainer').css({ top: top + 'px', height: $(window).height() - top - 10 }); } - function sgvToColor(sgv) { + function sgvToColor (sgv) { var color = 'grey'; if (client.settings.theme !== 'default') { @@ -556,7 +556,7 @@ client.load = function load(serverSettings, callback) { return color; } - function sgvToColoredRange(sgv) { + function sgvToColoredRange (sgv) { var range = ''; if (client.settings.theme !== 'default') { @@ -576,7 +576,7 @@ client.load = function load(serverSettings, callback) { return range; } - function formatAlarmMessage(notify) { + function formatAlarmMessage (notify) { var announcementMessage = notify && notify.isAnnouncement && notify.message && notify.message.length > 1; if (announcementMessage) { @@ -584,7 +584,7 @@ client.load = function load(serverSettings, callback) { } else if (notify) { return notify.title; } - return null; + return null; } function setAlarmMessage (notify) { @@ -599,7 +599,7 @@ client.load = function load(serverSettings, callback) { var selector = '.audio.alarms audio.' + file; if (!alarmingNow()) { - d3.select(selector).each(function () { + d3.select(selector).each(function() { var audio = this; playAlarm(audio); $(this).addClass('playing'); @@ -628,7 +628,7 @@ client.load = function load(serverSettings, callback) { event.preventDefault(); } - function playAlarm(audio) { + function playAlarm (audio) { // ?mute=true disables alarms to testers. if (client.browserUtils.queryParms().mute !== 'true') { audio.play(); @@ -637,11 +637,11 @@ client.load = function load(serverSettings, callback) { } } - function stopAlarm(isClient, silenceTime, notify) { + function stopAlarm (isClient, silenceTime, notify) { alarmInProgress = false; alarmMessage = null; container.removeClass('urgent warning'); - d3.selectAll('audio.playing').each(function () { + d3.selectAll('audio.playing').each(function() { var audio = this; audio.pause(); $(this).removeClass('playing'); @@ -688,7 +688,7 @@ client.load = function load(serverSettings, callback) { brushed(); } - function refreshAuthIfNeeded ( ) { + function refreshAuthIfNeeded () { var token = client.browserUtils.queryParms().token; if (token && client.authorized) { var renewTime = (client.authorized.exp * 1000) - times.mins(15).msecs - Math.abs((client.authorized.iat * 1000) - client.authorized.lat); @@ -696,7 +696,7 @@ client.load = function load(serverSettings, callback) { if (client.now > renewTime) { console.info('Refreshing authorization'); $.ajax('/api/v2/authorization/request/' + token, { - success: function (authorized) { + success: function(authorized) { if (authorized) { console.info('Got new authorization', authorized); authorized.lat = client.now; @@ -710,10 +710,10 @@ client.load = function load(serverSettings, callback) { } } - function updateClock() { + function updateClock () { updateClockDisplay(); var interval = (60 - (new Date()).getSeconds()) * 1000 + 5; - setTimeout(updateClock,interval); + setTimeout(updateClock, interval); updateTimeAgo(); if (chart) { @@ -735,7 +735,7 @@ client.load = function load(serverSettings, callback) { } } - function updateClockDisplay() { + function updateClockDisplay () { if (inRetroMode()) { return; } @@ -743,7 +743,7 @@ client.load = function load(serverSettings, callback) { $('#currentTime').text(formatTime(new Date(client.now), true)).css('text-decoration', ''); } - function getClientAlarm(level, group) { + function getClientAlarm (level, group) { var key = level + '-' + group; var alarm = clientAlarms[key]; if (!alarm) { @@ -753,13 +753,13 @@ client.load = function load(serverSettings, callback) { return alarm; } - function isTimeAgoAlarmType() { + function isTimeAgoAlarmType () { return currentNotify && currentNotify.group === 'Time Ago'; } function isStale (status) { - return client.settings.alarmTimeagoWarn && status === 'warn' - || client.settings.alarmTimeagoUrgent && status === 'urgent'; + return client.settings.alarmTimeagoWarn && status === 'warn' || + client.settings.alarmTimeagoUrgent && status === 'urgent'; } function notAcked (alarm) { @@ -786,12 +786,12 @@ client.load = function load(serverSettings, callback) { container.toggleClass('alarming-timeago', status !== 'current'); - if (alarmingNow() && status === 'current' && isTimeAgoAlarmType( )) { + if (alarmingNow() && status === 'current' && isTimeAgoAlarmType()) { stopAlarm(true, times.min().msecs); } } - function updateTimeAgo() { + function updateTimeAgo () { var status = client.timeago.checkStatus(client.sbx); if (status !== 'current') { updateTitle(); @@ -799,20 +799,20 @@ client.load = function load(serverSettings, callback) { checkTimeAgoAlarm(status); } - function updateTimeAgoSoon() { - setTimeout(function updatingTimeAgoNow() { + function updateTimeAgoSoon () { + setTimeout(function updatingTimeAgoNow () { updateTimeAgo(); }, times.secs(10).msecs); } - function refreshChart(updateToNow) { + function refreshChart (updateToNow) { if (updateToNow) { updateBrushToNow(); } chart.update(false); } - (function watchVisibility ( ) { + (function watchVisibility () { // Set the name of the hidden property and the change event for visibility var hidden, visibilityChange; if (typeof document.hidden !== 'undefined') { @@ -829,7 +829,7 @@ client.load = function load(serverSettings, callback) { visibilityChange = 'webkitvisibilitychange'; } - document.addEventListener(visibilityChange, function visibilityChanged ( ) { + document.addEventListener(visibilityChange, function visibilityChanged () { var prevHidden = client.documentHidden; client.documentHidden = document[hidden]; @@ -845,7 +845,7 @@ client.load = function load(serverSettings, callback) { updateClock(); updateTimeAgoSoon(); - function Dropdown(el) { + function Dropdown (el) { this.ddmenuitem = 0; this.$el = $(el); @@ -853,13 +853,13 @@ client.load = function load(serverSettings, callback) { $(document).click(function() { that.close(); }); } - Dropdown.prototype.close = function () { + Dropdown.prototype.close = function() { if (this.ddmenuitem) { this.ddmenuitem.css('visibility', 'hidden'); this.ddmenuitem = 0; } }; - Dropdown.prototype.open = function (e) { + Dropdown.prototype.open = function(e) { this.close(); this.ddmenuitem = $(this.$el).css('visibility', 'visible'); e.stopPropagation(); @@ -868,7 +868,7 @@ client.load = function load(serverSettings, callback) { var silenceDropdown = new Dropdown('#silenceBtn'); var viewDropdown = new Dropdown('#viewMenu'); - $('.bgButton').click(function (e) { + $('.bgButton').click(function(e) { if (alarmingNow()) { silenceDropdown.open(e); } @@ -887,23 +887,23 @@ client.load = function load(serverSettings, callback) { viewDropdown.open(e); } }); - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Client-side code to connect to server and handle incoming data //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // eslint-disable-next-line no-undef client.socket = socket = io.connect(); socket.on('dataUpdate', dataUpdate); - function resetRetro ( ) { + function resetRetro () { client.retro = { loadedMills: 0 , loadStartedMills: 0 }; } - client.resetRetroIfNeeded = function resetRetroIfNeeded ( ) { + client.resetRetroIfNeeded = function resetRetroIfNeeded () { if (client.retro.loadedMills > 0 && Date.now() - client.retro.loadedMills > times.mins(5).msecs) { resetRetro(); console.info('Cleared retro data to free memory'); @@ -912,7 +912,7 @@ client.load = function load(serverSettings, callback) { resetRetro(); - client.loadRetroIfNeeded = function loadRetroIfNeeded ( ) { + client.loadRetroIfNeeded = function loadRetroIfNeeded () { var now = Date.now(); if (now - client.retro.loadStartedMills < times.secs(30).msecs) { console.info('retro already loading, started', new Date(client.retro.loadStartedMills)); @@ -940,7 +940,7 @@ client.load = function load(serverSettings, callback) { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Alarms and Text handling //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - socket.on('connect', function () { + socket.on('connect', function() { console.log('Client connected to server.'); socket.emit( 'authorize' @@ -950,10 +950,10 @@ client.load = function load(serverSettings, callback) { , token: client.authorized && client.authorized.token , history: history } - , function authCallback(data) { - console.log('Client rights: ',data); + , function authCallback (data) { + console.log('Client rights: ', data); if (!data.read || !hasRequiredPermission()) { - client.hashauth.requestAuthentication(function afterRequest ( ) { + client.hashauth.requestAuthentication(function afterRequest () { client.hashauth.updateSocketAuth(); if (callback) { callback(); @@ -966,7 +966,7 @@ client.load = function load(serverSettings, callback) { ); }); - function hasRequiredPermission ( ) { + function hasRequiredPermission () { if (client.requiredPermission) { if (client.hashauth && client.hashauth.isAuthenticated()) { return true; @@ -980,39 +980,38 @@ client.load = function load(serverSettings, callback) { //with predicted alarms, latestSGV may still be in target so to see if the alarm // is for a HIGH we can only check if it's >= the bottom of the target - function isAlarmForHigh() { + function isAlarmForHigh () { return client.latestSGV && client.latestSGV.mgdl >= client.settings.thresholds.bgTargetBottom; } //with predicted alarms, latestSGV may still be in target so to see if the alarm // is for a LOW we can only check if it's <= the top of the target - function isAlarmForLow() { + function isAlarmForLow () { return client.latestSGV && client.latestSGV.mgdl <= client.settings.thresholds.bgTargetTop; } - socket.on('notification', function (notify) { - console.log('notification from server:',notify); - - if (notify.timestamp && previousNotifyTimestamp != notify.timestamp) - { - previousNotifyTimestamp = notify.timestamp; + socket.on('notification', function(notify) { + console.log('notification from server:', notify); + + if (notify.timestamp && previousNotifyTimestamp != notify.timestamp) { + previousNotifyTimestamp = notify.timestamp; client.plugins.visualizeAlarm(client.sbx, notify, notify.title + ' ' + notify.message); } else { console.log('No timestamp found for notify, not passing to plugins'); } }); - socket.on('announcement', function (notify) { + socket.on('announcement', function(notify) { console.info('announcement received from server'); - console.log('notify:',notify); + console.log('notify:', notify); currentAnnouncement = notify; currentAnnouncement.received = Date.now(); updateTitle(); }); - socket.on('alarm', function (notify) { + socket.on('alarm', function(notify) { console.info('alarm received from server'); - console.log('notify:',notify); + console.log('notify:', notify); var enabled = (isAlarmForHigh() && client.settings.alarmHigh) || (isAlarmForLow() && client.settings.alarmLow); if (enabled) { console.log('Alarm raised!'); @@ -1023,9 +1022,9 @@ client.load = function load(serverSettings, callback) { chart.update(false); }); - socket.on('urgent_alarm', function (notify) { + socket.on('urgent_alarm', function(notify) { console.info('urgent alarm received from server'); - console.log('notify:',notify); + console.log('notify:', notify); var enabled = (isAlarmForHigh() && client.settings.alarmUrgentHigh) || (isAlarmForLow() && client.settings.alarmUrgentLow); if (enabled) { @@ -1037,7 +1036,7 @@ client.load = function load(serverSettings, callback) { chart.update(false); }); - socket.on('clear_alarm', function (notify) { + socket.on('clear_alarm', function(notify) { console.info('got clear_alarm', notify); if (alarmInProgress) { console.log('clearing alarm'); @@ -1046,7 +1045,15 @@ client.load = function load(serverSettings, callback) { }); $('#testAlarms').click(function(event) { - d3.selectAll('.audio.alarms audio').each(function () { + + // Speech synthesis also requires on iOS that user triggers a speech event for it to speak anything + if (client.plugins('speech').isEnabled) { + var msg = new SpeechSynthesisUtterance('Ok ok.'); + msg.lang = 'en-US'; + window.speechSynthesis.speak(msg); + } + + d3.selectAll('.audio.alarms audio').each(function() { var audio = this; playAlarm(audio); setTimeout(function() { @@ -1069,34 +1076,32 @@ client.load = function load(serverSettings, callback) { $('.foodcontrol').toggle(client.settings.enable.indexOf('food') > -1); // hide cob control if not enabled $('.cobcontrol').toggle(client.settings.enable.indexOf('cob') > -1); - // hide profile controls if not enabled - $('.profilecontrol').toggle(client.settings.enable.indexOf('profile') > -1); container.toggleClass('has-minor-pills', client.plugins.hasShownType('pill-minor', client.settings)); - function prepareEntries ( ) { + function prepareEntries () { // Post processing after data is in - var temp1 = [ ]; + var temp1 = []; var sbx = client.sbx.withExtendedSettings(client.rawbg); if (client.ddata.cal && client.rawbg.isEnabled(sbx)) { - temp1 = client.ddata.sgvs.map(function (entry) { + temp1 = client.ddata.sgvs.map(function(entry) { var rawbgValue = client.rawbg.showRawBGs(entry.mgdl, entry.noise, client.ddata.cal, sbx) ? client.rawbg.calc(entry, client.ddata.cal, sbx) : 0; if (rawbgValue > 0) { return { mills: entry.mills - 2000, mgdl: rawbgValue, color: 'white', type: 'rawbg' }; } else { return null; } - }).filter(function (entry) { + }).filter(function(entry) { return entry !== null; }); } - var temp2 = client.ddata.sgvs.map(function (obj) { - return { mills: obj.mills, mgdl: obj.mgdl, direction: obj.direction, color: sgvToColor(obj.mgdl), type: 'sgv', noise: obj.noise, filtered: obj.filtered, unfiltered: obj.unfiltered}; + var temp2 = client.ddata.sgvs.map(function(obj) { + return { mills: obj.mills, mgdl: obj.mgdl, direction: obj.direction, color: sgvToColor(obj.mgdl), type: 'sgv', noise: obj.noise, filtered: obj.filtered, unfiltered: obj.unfiltered }; }); client.entries = []; client.entries = client.entries.concat(temp1, temp2); - client.entries = client.entries.concat(client.ddata.mbgs.map(function (obj) { + client.entries = client.entries.concat(client.ddata.mbgs.map(function(obj) { return { mills: obj.mills, mgdl: obj.mgdl, color: 'red', type: 'mbg', device: obj.device }; })); @@ -1105,7 +1110,7 @@ client.load = function load(serverSettings, callback) { return entry.mills > tooOld; }); - client.entries.forEach(function (point) { + client.entries.forEach(function(point) { if (point.mgdl < 39) { point.color = 'transparent'; } @@ -1125,10 +1130,9 @@ client.load = function load(serverSettings, callback) { } if (client.ddata.sgvs) { - // change the next line so that it uses the prediction if the signal gets lost (max 1/2 hr) + // TODO change the next line so that it uses the prediction if the signal gets lost (max 1/2 hr) client.ctx.data.lastUpdated = lastUpdated; client.latestSGV = client.ddata.sgvs[client.ddata.sgvs.length - 1]; - prevSGV = client.ddata.sgvs[client.ddata.sgvs.length - 2]; } client.ddata.inRetroMode = false; diff --git a/lib/client/receiveddata.js b/lib/client/receiveddata.js index be622a7705f..e0adf13fb3b 100644 --- a/lib/client/receiveddata.js +++ b/lib/client/receiveddata.js @@ -4,22 +4,22 @@ var _ = require('lodash'); var TWO_DAYS = 172800000; -function mergeDataUpdate(isDelta, cachedDataArray, receivedDataArray, maxAge) { +function mergeDataUpdate (isDelta, cachedDataArray, receivedDataArray, maxAge) { - function nsArrayDiff(oldArray, newArray) { - var seen = {}; + function nsArrayDiff (oldArray, newArray) { + var seen = []; var l = oldArray.length; - + for (var i = 0; i < l; i++) { - if (oldArray[i] !== null) { - seen[oldArray[i].mills] = true; + if (oldArray[i] !== null) { + seen.push(oldArray[i].mills); } } - + var result = []; l = newArray.length; for (var j = 0; j < l; j++) { - if (!seen.hasOwnProperty(newArray[j].mills)) { + if (!seen.includes(newArray[j].mills)) { result.push(newArray[j]); //console.log('delta data found'); } } @@ -39,11 +39,11 @@ function mergeDataUpdate(isDelta, cachedDataArray, receivedDataArray, maxAge) { // purge old data from cache before updating var mAge = (isNaN(maxAge) || maxAge == null) ? TWO_DAYS : maxAge; var twoDaysAgo = new Date().getTime() - mAge; - + for (var i = 0; i < cachedDataArray.length; i++) { var element = cachedDataArray[i]; - if (element !== null && element !== undefined && element.mills <= twoDaysAgo) { - cachedDataArray.splice(i,0); + if (element !== null && element !== undefined && element.mills <= twoDaysAgo) { + cachedDataArray.splice(i, 0); } } @@ -54,7 +54,7 @@ function mergeDataUpdate(isDelta, cachedDataArray, receivedDataArray, maxAge) { }); } -function mergeTreatmentUpdate(isDelta, cachedDataArray, receivedDataArray) { +function mergeTreatmentUpdate (isDelta, cachedDataArray, receivedDataArray) { // If there was no delta data, just return the original data if (!receivedDataArray) { @@ -78,12 +78,12 @@ function mergeTreatmentUpdate(isDelta, cachedDataArray, receivedDataArray) { for (var j = 0; j < m; j++) { if (no._id === cachedDataArray[j]._id) { if (no.action === 'remove') { - cachedDataArray.splice(j,1); + cachedDataArray.splice(j, 1); break; } if (no.action === 'update') { delete no.action; - cachedDataArray.splice(j,1,no); + cachedDataArray.splice(j, 1, no); break; } } diff --git a/lib/client/renderer.js b/lib/client/renderer.js index bcb605e3bc1..5b1c36ad83b 100644 --- a/lib/client/renderer.js +++ b/lib/client/renderer.js @@ -8,21 +8,21 @@ var DEFAULT_FOCUS = times.hours(3).msecs , WIDTH_BIG_DOTS = 800 , TOOLTIP_TRANS_MS = 100 // milliseconds , TOOLTIP_WIDTH = 150 //min-width + padding - ; +; function init (client, d3) { - var renderer = { }; + var renderer = {}; var utils = client.utils; var translate = client.translate; //chart isn't created till the client gets data, so can grab the var at init - function chart() { + function chart () { return client.chart; } - function focusRangeAdjustment ( ) { + function focusRangeAdjustment () { return client.focusRangeMS === DEFAULT_FOCUS ? 1 : 1 + ((client.focusRangeMS - DEFAULT_FOCUS) / DEFAULT_FOCUS / 8); } @@ -39,20 +39,20 @@ function init (client, d3) { return radius / focusRangeAdjustment(); }; - function tooltipLeft ( ) { + function tooltipLeft () { var windowWidth = $(client.tooltip).parent().parent().width(); var left = d3.event.pageX + TOOLTIP_WIDTH < windowWidth ? d3.event.pageX : windowWidth - TOOLTIP_WIDTH - 10; return left + 'px'; } - function hideTooltip ( ) { + function hideTooltip () { client.tooltip.transition() .duration(TOOLTIP_TRANS_MS) .style('opacity', 0); } // get the desired opacity for context chart based on the brush extent - renderer.highlightBrushPoints = function highlightBrushPoints(data) { + renderer.highlightBrushPoints = function highlightBrushPoints (data) { if (data.mills >= chart().brush.extent()[0].getTime() && data.mills <= chart().brush.extent()[1].getTime()) { return chart().futureOpacity(data.mills - client.latestSGV.mills); } else { @@ -60,20 +60,20 @@ function init (client, d3) { } }; - renderer.bubbleScale = function bubbleScale ( ) { + renderer.bubbleScale = function bubbleScale () { // a higher bubbleScale will produce smaller bubbles (it's not a radius like focusDotRadius) return (chart().prevChartWidth < WIDTH_SMALL_DOTS ? 4 : (chart().prevChartWidth < WIDTH_BIG_DOTS ? 3 : 2)) * focusRangeAdjustment(); }; - renderer.addFocusCircles = function addFocusCircles ( ) { + renderer.addFocusCircles = function addFocusCircles () { // get slice of data so that concatenation of predictions do not interfere with subsequent updates var focusData = client.entries.slice(); if (client.sbx.pluginBase.forecastPoints) { - var shownForecastPoints = _.filter(client.sbx.pluginBase.forecastPoints, function isShown(point) { + var shownForecastPoints = _.filter(client.sbx.pluginBase.forecastPoints, function isShown (point) { return client.settings.showForecast.indexOf(point.info.type) > -1; }); - var maxForecastMills = _.max(_.map(shownForecastPoints, function (point) {return point.mills})); + var maxForecastMills = _.max(_.map(shownForecastPoints, function(point) { return point.mills })); // limit lookahead to the same as lookback var focusHoursAheadMills = chart().brush.extent()[1].getTime() + client.focusRangeMS; maxForecastMills = Math.min(focusHoursAheadMills, maxForecastMills); @@ -85,20 +85,20 @@ function init (client, d3) { // selects all our data into data and uses date function to get current max date var focusCircles = chart().focus.selectAll('circle').data(focusData, client.entryToDate); - function prepareFocusCircles(sel) { + function prepareFocusCircles (sel) { var badData = []; - sel.attr('cx', function (d) { - if (!d) { - console.error('Bad data', d); - return chart().xScale(new Date(0)); - } else if (!d.mills) { - console.error('Bad data, no mills', d); - return chart().xScale(new Date(0)); - } else { - return chart().xScale(new Date(d.mills)); - } - }) - .attr('cy', function (d) { + sel.attr('cx', function(d) { + if (!d) { + console.error('Bad data', d); + return chart().xScale(new Date(0)); + } else if (!d.mills) { + console.error('Bad data, no mills', d); + return chart().xScale(new Date(0)); + } else { + return chart().xScale(new Date(d.mills)); + } + }) + .attr('cy', function(d) { var scaled = client.sbx.scaleEntry(d); if (isNaN(scaled)) { badData.push(d); @@ -107,19 +107,19 @@ function init (client, d3) { return chart().yScale(scaled); } }) - .attr('fill', function (d) { + .attr('fill', function(d) { return d.type === 'forecast' ? 'none' : d.color; }) - .attr('opacity', function (d) { + .attr('opacity', function(d) { return d.noFade ? 100 : chart().futureOpacity(d.mills - client.latestSGV.mills); }) - .attr('stroke-width', function (d) { + .attr('stroke-width', function(d) { return d.type === 'mbg' ? 2 : d.type === 'forecast' ? 2 : 0; }) - .attr('stroke', function (d) { + .attr('stroke', function(d) { return (d.type === 'mbg' ? 'white' : d.color); }) - .attr('r', function (d) { + .attr('r', function(d) { return dotRadius(d.type); }); @@ -135,8 +135,8 @@ function init (client, d3) { return; } - function getRawbgInfo ( ) { - var info = { }; + function getRawbgInfo () { + var info = {}; var sbx = client.sbx.withExtendedSettings(client.rawbg); if (d.type === 'sgv') { info.noise = client.rawbg.noiseCodeToDisplay(d.mgdl, d.noise); @@ -150,12 +150,12 @@ function init (client, d3) { var rawbgInfo = getRawbgInfo(); client.tooltip.transition().duration(TOOLTIP_TRANS_MS).style('opacity', .9); - client.tooltip.html('' + translate('BG')+ ': ' + client.sbx.scaleEntry( d ) + - (d.type === 'mbg' ? '
' + translate('Device') + ': ' + d.device : '') + - (d.type === 'forecast' && d.forecastType ? '
' + translate('Forecast Type') + ': ' + d.forecastType : '') + - (rawbgInfo.value ? '
' + translate('Raw BG') + ': ' + rawbgInfo.value : '') + - (rawbgInfo.noise ? '
' + translate('Noise') + ': ' + rawbgInfo.noise : '') + - '
' + translate('Time') + ': ' + client.formatTime(new Date(d.mills))) + client.tooltip.html('' + translate('BG') + ': ' + client.sbx.scaleEntry(d) + + (d.type === 'mbg' ? '
' + translate('Device') + ': ' + d.device : '') + + (d.type === 'forecast' && d.forecastType ? '
' + translate('Forecast Type') + ': ' + d.forecastType : '') + + (rawbgInfo.value ? '
' + translate('Raw BG') + ': ' + rawbgInfo.value : '') + + (rawbgInfo.noise ? '
' + translate('Noise') + ': ' + rawbgInfo.noise : '') + + '
' + translate('Time') + ': ' + client.formatTime(new Date(d.mills))) .style('left', tooltipLeft()) .style('top', (d3.event.pageY + 15) + 'px'); } @@ -171,24 +171,24 @@ function init (client, d3) { focusCircles.exit().remove(); }; - renderer.addTreatmentCircles = function addTreatmentCircles ( ) { + renderer.addTreatmentCircles = function addTreatmentCircles () { function treatmentTooltip (d) { - return ''+translate('Time')+': ' + client.formatTime(new Date(d.mills)) + '
' + - (d.eventType ? ''+translate('Treatment type')+': ' + translate(client.careportal.resolveEventName(d.eventType)) + '
' : '') + - (d.reason ? ''+translate('Reason')+': ' + translate(d.reason) + '
' : '') + - (d.glucose ? ''+translate('BG')+': ' + d.glucose + (d.glucoseType ? ' (' + translate(d.glucoseType) + ')': '') + '
' : '') + - (d.enteredBy ? ''+translate('Entered By')+': ' + d.enteredBy + '
' : '') + - (d.targetTop ? ''+translate('Target Top')+': ' + d.targetTop + '
' : '') + - (d.targetBottom ? ''+translate('Target Bottom')+': ' + d.targetBottom + '
' : '') + - (d.duration ? ''+translate('Duration')+': ' + Math.round(d.duration) + ' min
' : '') + - (d.notes ? ''+translate('Notes')+': ' + d.notes : ''); + return '' + translate('Time') + ': ' + client.formatTime(new Date(d.mills)) + '
' + + (d.eventType ? '' + translate('Treatment type') + ': ' + translate(client.careportal.resolveEventName(d.eventType)) + '
' : '') + + (d.reason ? '' + translate('Reason') + ': ' + translate(d.reason) + '
' : '') + + (d.glucose ? '' + translate('BG') + ': ' + d.glucose + (d.glucoseType ? ' (' + translate(d.glucoseType) + ')' : '') + '
' : '') + + (d.enteredBy ? '' + translate('Entered By') + ': ' + d.enteredBy + '
' : '') + + (d.targetTop ? '' + translate('Target Top') + ': ' + d.targetTop + '
' : '') + + (d.targetBottom ? '' + translate('Target Bottom') + ': ' + d.targetBottom + '
' : '') + + (d.duration ? '' + translate('Duration') + ': ' + Math.round(d.duration) + ' min
' : '') + + (d.notes ? '' + translate('Notes') + ': ' + d.notes : ''); } function announcementTooltip (d) { - return ''+translate('Time')+': ' + client.formatTime(new Date(d.mills)) + '
' + - (d.eventType ? ''+translate('Announcement')+'
' : '') + - (d.notes && d.notes.length > 1 ? ''+translate('Message')+': ' + d.notes + '
' : '') + - (d.enteredBy ? ''+translate('Entered By')+': ' + d.enteredBy + '
' : ''); + return '' + translate('Time') + ': ' + client.formatTime(new Date(d.mills)) + '
' + + (d.eventType ? '' + translate('Announcement') + '
' : '') + + (d.notes && d.notes.length > 1 ? '' + translate('Message') + ': ' + d.notes + '
' : '') + + (d.enteredBy ? '' + translate('Entered By') + ': ' + d.enteredBy + '
' : ''); } //TODO: filter in oref0 instead of here and after most people upgrade take this out @@ -199,7 +199,7 @@ function init (client, d3) { var treatCircles = chart().focus.selectAll('treatment-dot').data(client.ddata.treatments.filter(function(treatment) { var notCarbsOrInsulin = !treatment.carbs && !treatment.insulin; - var notTempOrProfile = ! _.includes(['Temp Basal', 'Profile Switch', 'Combo Bolus', 'Temporary Target'], treatment.eventType); + var notTempOrProfile = !_.includes(['Temp Basal', 'Profile Switch', 'Combo Bolus', 'Temporary Target'], treatment.eventType); var notes = treatment.notes || ''; var enteredBy = treatment.enteredBy || ''; @@ -211,8 +211,8 @@ function init (client, d3) { return notCarbsOrInsulin && !treatment.duration && notTempOrProfile && notOpenAPSSpam; })); - function prepareTreatCircles(sel) { - function strokeColor(d) { + function prepareTreatCircles (sel) { + function strokeColor (d) { var color = 'white'; if (d.isAnnouncement) { color = 'orange'; @@ -222,7 +222,7 @@ function init (client, d3) { return color; } - function fillColor(d) { + function fillColor (d) { var color = 'grey'; if (d.isAnnouncement) { color = 'orange'; @@ -232,13 +232,13 @@ function init (client, d3) { return color; } - sel.attr('cx', function (d) { - return chart().xScale(new Date(d.mills)); - }) - .attr('cy', function (d) { + sel.attr('cx', function(d) { + return chart().xScale(new Date(d.mills)); + }) + .attr('cy', function(d) { return chart().yScale(client.sbx.scaleEntry(d)); }) - .attr('r', function () { + .attr('r', function() { return dotRadius('mbg'); }) .attr('stroke-width', 2) @@ -253,7 +253,7 @@ function init (client, d3) { // if new circle then just display prepareTreatCircles(treatCircles.enter().append('circle')) - .on('mouseover', function (d) { + .on('mouseover', function(d) { client.tooltip.transition().duration(TOOLTIP_TRANS_MS).style('opacity', .9); client.tooltip.html(d.isAnnouncement ? announcementTooltip(d) : treatmentTooltip(d)) .style('left', tooltipLeft()) @@ -263,7 +263,7 @@ function init (client, d3) { var durationTreatments = client.ddata.treatments.filter(function(treatment) { return !treatment.carbs && !treatment.insulin && treatment.duration && - ! _.includes(['Temp Basal', 'Profile Switch', 'Combo Bolus', 'Temporary Target'], treatment.eventType); + !_.includes(['Temp Basal', 'Profile Switch', 'Combo Bolus', 'Temporary Target'], treatment.eventType); }); //use the processed temp target so there are no overlaps @@ -272,7 +272,7 @@ function init (client, d3) { // treatments with duration var treatRects = chart().focus.selectAll('.g-duration').data(durationTreatments); - function fillColor(d) { + function fillColor (d) { // this is going to be updated by Event Type var color = 'grey'; if (d.eventType === 'Exercise') { @@ -305,20 +305,20 @@ function init (client, d3) { .attr('transform', rectTranslate); chart().focus.selectAll('.g-duration-rect').transition() - .attr('width', function (d) { + .attr('width', function(d) { return chart().xScale(new Date(d.mills + times.mins(d.duration).msecs)) - chart().xScale(new Date(d.mills)); }); chart().focus.selectAll('.g-duration-text').transition() - .attr('transform', function (d) { - return 'translate(' + (chart().xScale(new Date(d.mills + times.mins(d.duration).msecs)) - chart().xScale(new Date(d.mills)))/2 + ',' + 10 + ')'; + .attr('transform', function(d) { + return 'translate(' + (chart().xScale(new Date(d.mills + times.mins(d.duration).msecs)) - chart().xScale(new Date(d.mills))) / 2 + ',' + 10 + ')'; }); // if new rect then just display var gs = treatRects.enter().append('g') - .attr('class','g-duration') + .attr('class', 'g-duration') .attr('transform', rectTranslate) - .on('mouseover', function (d) { + .on('mouseover', function(d) { client.tooltip.transition().duration(TOOLTIP_TRANS_MS).style('opacity', .9); client.tooltip.html(d.isAnnouncement ? announcementTooltip(d) : treatmentTooltip(d)) .style('left', tooltipLeft()) @@ -328,7 +328,7 @@ function init (client, d3) { gs.append('rect') .attr('class', 'g-duration-rect') - .attr('width', function (d) { + .attr('width', function(d) { return chart().xScale(new Date(d.mills + times.mins(d.duration).msecs)) - chart().xScale(new Date(d.mills)); }) .attr('height', rectHeight) @@ -343,10 +343,10 @@ function init (client, d3) { .attr('fill', 'white') .attr('text-anchor', 'middle') .attr('dy', '.35em') - .attr('transform', function (d) { - return 'translate(' + (chart().xScale(new Date(d.mills + times.mins(d.duration).msecs)) - chart().xScale(new Date(d.mills)))/2 + ',' + 10 + ')'; + .attr('transform', function(d) { + return 'translate(' + (chart().xScale(new Date(d.mills + times.mins(d.duration).msecs)) - chart().xScale(new Date(d.mills))) / 2 + ',' + 10 + ')'; }) - .text(function (d) { + .text(function(d) { if (d.eventType === 'Temporary Target') { return ''; } @@ -354,14 +354,14 @@ function init (client, d3) { }); }; - renderer.addContextCircles = function addContextCircles ( ) { + renderer.addContextCircles = function addContextCircles () { // bind up the context chart data to an array of circles var contextCircles = chart().context.selectAll('circle').data(client.entries); - function prepareContextCircles(sel) { + function prepareContextCircles (sel) { var badData = []; - sel.attr('cx', function (d) { return chart().xScale2(new Date(d.mills)); }) - .attr('cy', function (d) { + sel.attr('cx', function(d) { return chart().xScale2(new Date(d.mills)); }) + .attr('cy', function(d) { var scaled = client.sbx.scaleEntry(d); if (isNaN(scaled)) { badData.push(d); @@ -370,11 +370,11 @@ function init (client, d3) { return chart().yScale2(scaled); } }) - .attr('fill', function (d) { return d.color; }) - .style('opacity', function (d) { return renderer.highlightBrushPoints(d) }) - .attr('stroke-width', function (d) { return d.type === 'mbg' ? 2 : 0; }) - .attr('stroke', function ( ) { return 'white'; }) - .attr('r', function (d) { return d.type === 'mbg' ? 4 : 2; }); + .attr('fill', function(d) { return d.color; }) + .style('opacity', function(d) { return renderer.highlightBrushPoints(d) }) + .attr('stroke-width', function(d) { return d.type === 'mbg' ? 2 : 0; }) + .attr('stroke', function() { return 'white'; }) + .attr('r', function(d) { return d.type === 'mbg' ? 4 : 2; }); if (badData.length > 0) { console.warn('Bad Data: isNaN(sgv)', badData); @@ -392,13 +392,13 @@ function init (client, d3) { contextCircles.exit().remove(); }; - function calcTreatmentRadius(treatment, opts, carbratio) { + function calcTreatmentRadius (treatment, opts, carbratio) { var CR = treatment.CR || carbratio || 20; var carbsOrInsulin = CR; - if ( treatment.carbs ) { - carbsOrInsulin = treatment.carbs; - } else if ( treatment.insulin ) { - carbsOrInsulin = treatment.insulin * CR; + if (treatment.carbs) { + carbsOrInsulin = treatment.carbs; + } else if (treatment.insulin) { + carbsOrInsulin = treatment.insulin * CR; } // R1 determines the size of the treatment dot @@ -406,8 +406,7 @@ function init (client, d3) { , R2 = R1 // R3/R4 determine how far from the treatment dot the labels are placed , R3 = R1 + 8 / opts.scale - , R4 = R1 + 25 / opts.scale - ; + , R4 = R1 + 25 / opts.scale; return { R1: R1 @@ -418,17 +417,17 @@ function init (client, d3) { }; } - function prepareArc(treatment, radius) { + function prepareArc (treatment, radius) { var arc_data = [ // white carb half-circle on top - { 'element': '', 'color': 'white', 'start': -1.5708, 'end': 1.5708, 'inner': 0, 'outer': radius.R1 }, - { 'element': '', 'color': 'transparent', 'start': -1.5708, 'end': 1.5708, 'inner': radius.R2, 'outer': radius.R3 }, + { 'element': '', 'color': 'white', 'start': -1.5708, 'end': 1.5708, 'inner': 0, 'outer': radius.R1 } + , { 'element': '', 'color': 'transparent', 'start': -1.5708, 'end': 1.5708, 'inner': radius.R2, 'outer': radius.R3 }, // blue insulin half-circle on bottom { 'element': '', 'color': '#0099ff', 'start': 1.5708, 'end': 4.7124, 'inner': 0, 'outer': radius.R1 }, // these form a very short transparent arc along the bottom of an insulin treatment to position the label // these used to be semicircles from 1.5708 to 4.7124, but that made the tooltip target too big - { 'element': '', 'color': 'transparent', 'start': 3.1400, 'end': 3.1432, 'inner': radius.R2, 'outer': radius.R3 }, - { 'element': '', 'color': 'transparent', 'start': 3.1400, 'end': 3.1432, 'inner': radius.R2, 'outer': radius.R4 } + { 'element': '', 'color': 'transparent', 'start': 3.1400, 'end': 3.1432, 'inner': radius.R2, 'outer': radius.R3 } + , { 'element': '', 'color': 'transparent', 'start': 3.1400, 'end': 3.1432, 'inner': radius.R2, 'outer': radius.R4 } ]; arc_data[0].outlineOnly = !treatment.carbs; @@ -438,20 +437,28 @@ function init (client, d3) { arc_data[1].element = Math.round(treatment.carbs) + ' g'; } + if (treatment.protein > 0) { + arc_data[1].element = arc_data[1].element + " / " + Math.round(treatment.protein) + ' g'; + } + + if (treatment.fat > 0) { + arc_data[1].element = arc_data[1].element + " / " + Math.round(treatment.fat) + ' g'; + } + if (treatment.foodType) { arc_data[1].element = arc_data[1].element + " " + treatment.foodType; } - if ( treatment.insulin > 0) { - var dosage_units = '' + Math.round(treatment.insulin * 100)/100; - + if (treatment.insulin > 0) { + var dosage_units = '' + Math.round(treatment.insulin * 100) / 100; + var unit_of_measurement = ' U'; // One international unit of insulin (1 IU) is shown as '1 U' var enteredBy = '' + treatment.enteredBy; - - if ( treatment.insulin < 1 && !treatment.carbs && enteredBy.indexOf('openaps') > -1) { // don't show the unit of measurement for insulin boluses < 1 without carbs (e.g. oref0 SMB's). Otherwise lot's of small insulin only dosages are often unreadable - unit_of_measurement = ''; - // remove leading zeros to avoid overlap with adjacent boluses - dosage_units = (dosage_units+"").replace(/^0/,""); + + if (treatment.insulin < 1 && !treatment.carbs && enteredBy.indexOf('openaps') > -1) { // don't show the unit of measurement for insulin boluses < 1 without carbs (e.g. oref0 SMB's). Otherwise lot's of small insulin only dosages are often unreadable + unit_of_measurement = ''; + // remove leading zeros to avoid overlap with adjacent boluses + dosage_units = (dosage_units + "").replace(/^0/, ""); } arc_data[3].element = dosage_units + unit_of_measurement; @@ -462,16 +469,16 @@ function init (client, d3) { } var arc = d3.svg.arc() - .innerRadius(function (d) { + .innerRadius(function(d) { return 5 * d.inner; }) - .outerRadius(function (d) { + .outerRadius(function(d) { return 5 * d.outer; }) - .endAngle(function (d) { + .endAngle(function(d) { return d.start; }) - .startAngle(function (d) { + .startAngle(function(d) { return d.end; }); @@ -481,27 +488,27 @@ function init (client, d3) { }; } - function isInRect(x,y,rect) { + function isInRect (x, y, rect) { return !(x < rect.x || x > rect.x + rect.width || y < rect.y || y > rect.y + rect.height); } - function appendTreatments(treatment, arc) { + function appendTreatments (treatment, arc) { function boluscalcTooltip (treatment) { if (!treatment.boluscalc) { return ''; } var html = '
'; - html += (treatment.boluscalc.othercorrection ? ''+translate('Other correction')+': ' + parseFloat(treatment.boluscalc.othercorrection).toFixed(2) + 'U
' : ''); - html += (treatment.boluscalc.profile ? ''+translate('Profile used')+': ' + treatment.boluscalc.profile + '
' : ''); + html += (treatment.boluscalc.othercorrection ? '' + translate('Other correction') + ': ' + parseFloat(treatment.boluscalc.othercorrection).toFixed(2) + 'U
' : ''); + html += (treatment.boluscalc.profile ? '' + translate('Profile used') + ': ' + treatment.boluscalc.profile + '
' : ''); if (treatment.boluscalc.foods && treatment.boluscalc.foods.length) { html += ''; - for (var fi=0; fi'; - html += ''; - html += ''; + html += ''; + html += ''; + html += ''; html += ''; } html += '
' + translate('Food') + '
'+ (f.portion*f.portions).toFixed(1) + ' ' + f.unit + '('+ (f.carbs*f.portions).toFixed(1) + ' g)' + f.name + '' + (f.portion * f.portions).toFixed(1) + ' ' + f.unit + '(' + (f.carbs * f.portions).toFixed(1) + ' g)
'; @@ -509,20 +516,22 @@ function init (client, d3) { return html; } - function treatmentTooltip() { + function treatmentTooltip () { client.tooltip.transition().duration(TOOLTIP_TRANS_MS).style('opacity', .9); client.tooltip.html('' + translate('Time') + ': ' + client.formatTime(new Date(treatment.mills)) + '
' + '' + translate('Treatment type') + ': ' + translate(client.careportal.resolveEventName(treatment.eventType)) + '
' + - (treatment.carbs ? '' + translate('Carbs') + ': ' + treatment.carbs + '
' : '') + - (treatment.absorptionTime > 0 ? '' + translate('Absorption Time') + ': ' + (Math.round( treatment.absorptionTime / 60.0 * 10) / 10) + 'h' + '
' : '') + - (treatment.insulin ? '' + translate('Insulin') + ': ' + treatment.insulin + '
' : '') + - (treatment.enteredinsulin ? '' + translate('Combo Bolus') + ': ' + treatment.enteredinsulin + 'U, ' + treatment.splitNow + '% : ' + treatment.splitExt + '%, ' + translate('Duration') + ': ' + treatment.duration + '
' : '') + - (treatment.glucose ? '' + translate('BG') + ': ' + treatment.glucose + (treatment.glucoseType ? ' (' + translate(treatment.glucoseType) + ')' : '') + '
' : '') + - (treatment.enteredBy ? '' + translate('Entered By') + ': ' + treatment.enteredBy + '
' : '') + - (treatment.notes ? '' + translate('Notes') + ': ' + treatment.notes : '') + - boluscalcTooltip(treatment) - ) - .style('left', tooltipLeft()) - .style('top', (d3.event.pageY + 15) + 'px'); + (treatment.carbs ? '' + translate('Carbs') + ': ' + treatment.carbs + '
' : '') + + (treatment.protein ? '' + translate('Protein') + ': ' + treatment.protein + '
' : '') + + (treatment.fat ? '' + translate('Fat') + ': ' + treatment.fat + '
' : '') + + (treatment.absorptionTime > 0 ? '' + translate('Absorption Time') + ': ' + (Math.round(treatment.absorptionTime / 60.0 * 10) / 10) + 'h' + '
' : '') + + (treatment.insulin ? '' + translate('Insulin') + ': ' + treatment.insulin + '
' : '') + + (treatment.enteredinsulin ? '' + translate('Combo Bolus') + ': ' + treatment.enteredinsulin + 'U, ' + treatment.splitNow + '% : ' + treatment.splitExt + '%, ' + translate('Duration') + ': ' + treatment.duration + '
' : '') + + (treatment.glucose ? '' + translate('BG') + ': ' + treatment.glucose + (treatment.glucoseType ? ' (' + translate(treatment.glucoseType) + ')' : '') + '
' : '') + + (treatment.enteredBy ? '' + translate('Entered By') + ': ' + treatment.enteredBy + '
' : '') + + (treatment.notes ? '' + translate('Notes') + ': ' + treatment.notes : '') + + boluscalcTooltip(treatment) + ) + .style('left', tooltipLeft()) + .style('top', (d3.event.pageY + 15) + 'px'); } var newTime; @@ -537,104 +546,104 @@ function init (client, d3) { var left = d3.event.x + TOOLTIP_WIDTH < windowWidth ? d3.event.x : windowWidth - TOOLTIP_WIDTH - 10; client.tooltip.transition().duration(TOOLTIP_TRANS_MS).style('opacity', .9) .style('left', left + 'px') - .style('top', (d3.event.pageY ? d3.event.pageY + 15 : 40) + 'px'); + .style('top', (d3.event.pageY ? d3.event.pageY + 15 : 40) + 'px'); deleteRect = { - x: 0, - y: 0, - width: 50, - height: chart().yScale(chart().yScale.domain()[0]) + x: 0 + , y: 0 + , width: 50 + , height: chart().yScale(chart().yScale.domain()[0]) }; chart().drag.append('rect') .attr({ - class:'drag-droparea', - x: deleteRect.x, - y: deleteRect.y, - width: deleteRect.width, - height: deleteRect.height, - fill: 'red', - opacity: 0.4, - rx: 10, - ry: 10 + class: 'drag-droparea' + , x: deleteRect.x + , y: deleteRect.y + , width: deleteRect.width + , height: deleteRect.height + , fill: 'red' + , opacity: 0.4 + , rx: 10 + , ry: 10 }); chart().drag.append('text') .attr({ - class:'drag-droparea', - x: deleteRect.x + deleteRect.width / 2, - y: deleteRect.y + deleteRect.height / 2, - 'font-size': 15, - 'font-weight': 'bold', - fill: 'red', - 'text-anchor': 'middle', - dy: '.35em', - transform: 'rotate(-90 ' + (deleteRect.x + deleteRect.width / 2) + ',' + (deleteRect.y + deleteRect.height / 2) + ')' + class: 'drag-droparea' + , x: deleteRect.x + deleteRect.width / 2 + , y: deleteRect.y + deleteRect.height / 2 + , 'font-size': 15 + , 'font-weight': 'bold' + , fill: 'red' + , 'text-anchor': 'middle' + , dy: '.35em' + , transform: 'rotate(-90 ' + (deleteRect.x + deleteRect.width / 2) + ',' + (deleteRect.y + deleteRect.height / 2) + ')' }) .text(translate('Remove')); if (treatment.insulin && treatment.carbs) { carbsRect = { - x: 0, - y: 0, - width: chart().charts.attr('width'), - height: 50 + x: 0 + , y: 0 + , width: chart().charts.attr('width') + , height: 50 }; insulinRect = { - x: 0, - y: chart().yScale(chart().yScale.domain()[0]) - 50, - width: chart().charts.attr('width'), - height: 50 + x: 0 + , y: chart().yScale(chart().yScale.domain()[0]) - 50 + , width: chart().charts.attr('width') + , height: 50 }; chart().drag.append('rect') .attr({ - class:'drag-droparea', - x: carbsRect.x, - y: carbsRect.y, - width: carbsRect.width, - height: carbsRect.height, - fill: 'white', - opacity: 0.4, - rx: 10, - ry: 10 + class: 'drag-droparea' + , x: carbsRect.x + , y: carbsRect.y + , width: carbsRect.width + , height: carbsRect.height + , fill: 'white' + , opacity: 0.4 + , rx: 10 + , ry: 10 }); chart().drag.append('text') .attr({ - class:'drag-droparea', - x: carbsRect.x + carbsRect.width / 2, - y: carbsRect.y + carbsRect.height / 2, - 'font-size': 15, - 'font-weight': 'bold', - fill: 'white', - 'text-anchor': 'middle', - dy: '.35em' + class: 'drag-droparea' + , x: carbsRect.x + carbsRect.width / 2 + , y: carbsRect.y + carbsRect.height / 2 + , 'font-size': 15 + , 'font-weight': 'bold' + , fill: 'white' + , 'text-anchor': 'middle' + , dy: '.35em' }) .text(translate('Move carbs')); chart().drag.append('rect') .attr({ - class:'drag-droparea', - x: insulinRect.x, - y: insulinRect.y, - width: insulinRect.width, - height: insulinRect.height, - fill: '#0099ff', - opacity: 0.4, - rx: 10, - ry: 10 + class: 'drag-droparea' + , x: insulinRect.x + , y: insulinRect.y + , width: insulinRect.width + , height: insulinRect.height + , fill: '#0099ff' + , opacity: 0.4 + , rx: 10 + , ry: 10 }); chart().drag.append('text') .attr({ - class:'drag-droparea', - x: insulinRect.x + insulinRect.width / 2, - y: insulinRect.y + insulinRect.height / 2, - 'font-size': 15, - 'font-weight': 'bold', - fill: '#0099ff', - 'text-anchor': 'middle', - dy: '.35em' + class: 'drag-droparea' + , x: insulinRect.x + insulinRect.width / 2 + , y: insulinRect.y + insulinRect.height / 2 + , 'font-size': 15 + , 'font-weight': 'bold' + , fill: '#0099ff' + , 'text-anchor': 'middle' + , dy: '.35em' }) .text(translate('Move insulin')); } - chart().basals.attr('display','none'); + chart().basals.attr('display', 'none'); operation = 'Move'; }) @@ -660,22 +669,22 @@ function init (client, d3) { newTime = new Date(chart().xScale.invert(x)); var minDiff = times.msecs(newTime.getTime() - treatment.mills).mins.toFixed(0); client.tooltip.html( - '' + translate('Operation') + ': ' + translate(operation) + '
' - + '' + translate('New time') + ': ' + newTime.toLocaleTimeString() + '
' - + '' + translate('Difference') + ': ' + (minDiff > 0 ? '+' : '') + minDiff + ' ' + translate('mins') - ); + '' + translate('Operation') + ': ' + translate(operation) + '
' + + '' + translate('New time') + ': ' + newTime.toLocaleTimeString() + '
' + + '' + translate('Difference') + ': ' + (minDiff > 0 ? '+' : '') + minDiff + ' ' + translate('mins') + ); chart().drag.selectAll('.arrow').remove(); chart().drag.append('line') .attr({ - 'class':'arrow', - 'marker-end':'url(#arrow)', - 'x1': chart().xScale(new Date(treatment.mills)), - 'y1': chart().yScale(client.sbx.scaleEntry(treatment)), - 'x2': x, - 'y2': y, - 'stroke-width': 2, - 'stroke': 'white' + 'class': 'arrow' + , 'marker-end': 'url(#arrow)' + , 'x1': chart().xScale(new Date(treatment.mills)) + , 'y1': chart().yScale(client.sbx.scaleEntry(treatment)) + , 'x2': x + , 'y2': y + , 'stroke-width': 2 + , 'stroke': 'white' }); }) @@ -685,15 +694,14 @@ function init (client, d3) { hideTooltip(); switch (operation) { case 'Move': - if (window.confirm(translate('Change treatment time to %1 ?', { params: [newTime.toLocaleTimeString()] } ))) { + if (window.confirm(translate('Change treatment time to %1 ?', { params: [newTime.toLocaleTimeString()] }))) { client.socket.emit( - 'dbUpdate', - { - collection: 'treatments', - _id: treatment._id, - data: { created_at: newTime.toISOString() } - }, - function callback(result) { + 'dbUpdate', { + collection: 'treatments' + , _id: treatment._id + , data: { created_at: newTime.toISOString() } + } + , function callback (result) { console.log(result); chart().drag.selectAll('.arrow').transition().duration(5000).style('opacity', 0).remove(); } @@ -705,13 +713,12 @@ function init (client, d3) { case 'Remove insulin': if (window.confirm(translate('Remove insulin from treatment ?'))) { client.socket.emit( - 'dbUpdateUnset', - { - collection: 'treatments', - _id: treatment._id, - data: { insulin: 1 } - }, - function callback(result) { + 'dbUpdateUnset', { + collection: 'treatments' + , _id: treatment._id + , data: { insulin: 1 } + } + , function callback (result) { console.log(result); chart().drag.selectAll('.arrow').transition().duration(5000).style('opacity', 0).remove(); } @@ -723,13 +730,12 @@ function init (client, d3) { case 'Remove carbs': if (window.confirm(translate('Remove carbs from treatment ?'))) { client.socket.emit( - 'dbUpdateUnset', - { - collection: 'treatments', - _id: treatment._id, - data: { carbs: 1 } - }, - function callback(result) { + 'dbUpdateUnset', { + collection: 'treatments' + , _id: treatment._id + , data: { carbs: 1 } + } + , function callback (result) { console.log(result); chart().drag.selectAll('.arrow').transition().duration(5000).style('opacity', 0).remove(); } @@ -741,12 +747,11 @@ function init (client, d3) { case 'Remove': if (window.confirm(translate('Remove treatment ?'))) { client.socket.emit( - 'dbRemove', - { - collection: 'treatments', - _id: treatment._id - }, - function callback(result) { + 'dbRemove', { + collection: 'treatments' + , _id: treatment._id + } + , function callback (result) { console.log(result); chart().drag.selectAll('.arrow').transition().duration(5000).style('opacity', 0).remove(); } @@ -756,13 +761,12 @@ function init (client, d3) { } break; case 'Move insulin': - if (window.confirm(translate('Change insulin time to %1 ?', { params: [newTime.toLocaleTimeString()] } ))) { + if (window.confirm(translate('Change insulin time to %1 ?', { params: [newTime.toLocaleTimeString()] }))) { client.socket.emit( - 'dbUpdateUnset', - { - collection: 'treatments', - _id: treatment._id, - data: { insulin: 1 } + 'dbUpdateUnset', { + collection: 'treatments' + , _id: treatment._id + , data: { insulin: 1 } } ); newTreatment = _.cloneDeep(treatment); @@ -771,12 +775,11 @@ function init (client, d3) { delete newTreatment.carbs; newTreatment.created_at = newTime.toISOString(); client.socket.emit( - 'dbAdd', - { - collection: 'treatments', - data: newTreatment - }, - function callback(result) { + 'dbAdd', { + collection: 'treatments' + , data: newTreatment + } + , function callback (result) { console.log(result); chart().drag.selectAll('.arrow').transition().duration(5000).style('opacity', 0).remove(); } @@ -786,13 +789,12 @@ function init (client, d3) { } break; case 'Move carbs': - if (window.confirm(translate('Change carbs time to %1 ?', { params: [newTime.toLocaleTimeString()] } ))) { + if (window.confirm(translate('Change carbs time to %1 ?', { params: [newTime.toLocaleTimeString()] }))) { client.socket.emit( - 'dbUpdateUnset', - { - collection: 'treatments', - _id: treatment._id, - data: { carbs: 1 } + 'dbUpdateUnset', { + collection: 'treatments' + , _id: treatment._id + , data: { carbs: 1 } } ); newTreatment = _.cloneDeep(treatment); @@ -801,12 +803,11 @@ function init (client, d3) { delete newTreatment.insulin; newTreatment.created_at = newTime.toISOString(); client.socket.emit( - 'dbAdd', - { - collection: 'treatments', - data: newTreatment - }, - function callback(result) { + 'dbAdd', { + collection: 'treatments' + , data: newTreatment + } + , function callback (result) { console.log(result); chart().drag.selectAll('.arrow').transition().duration(5000).style('opacity', 0).remove(); } @@ -816,7 +817,7 @@ function init (client, d3) { } break; } - chart().basals.attr('display',''); + chart().basals.attr('display', ''); }); var treatmentDots = chart().focus.selectAll('treatment-insulincarbs') @@ -835,16 +836,16 @@ function init (client, d3) { treatmentDots.append('path') .attr('class', 'path') - .attr('fill', function (d) { + .attr('fill', function(d) { return d.outlineOnly ? 'transparent' : d.color; }) - .attr('stroke-width', function (d) { + .attr('stroke-width', function(d) { return d.outlineOnly ? 1 : 0; }) - .attr('stroke', function (d) { + .attr('stroke', function(d) { return d.color; }) - .attr('id', function (d, i) { + .attr('id', function(d, i) { return 's' + i; }) .attr('d', arc.svg); @@ -852,42 +853,42 @@ function init (client, d3) { return treatmentDots; } - function appendLabels(treatmentDots, arc, opts) { + function appendLabels (treatmentDots, arc, opts) { // labels for carbs and insulin if (opts.showLabels) { var label = treatmentDots.append('g') .attr('class', 'path') .attr('id', 'label') .style('fill', 'white'); - + // reduce the treatment label font size to make it readable with SMB - var fontBaseSize = (opts.treatments >= 30) ? 40 : 50 - Math.floor((25-opts.treatments)/30 * 10); + var fontBaseSize = (opts.treatments >= 30) ? 40 : 50 - Math.floor((25 - opts.treatments) / 30 * 10); label.append('text') .style('font-size', fontBaseSize / opts.scale) .style('text-shadow', '0px 0px 10px rgba(0, 0, 0, 1)') .attr('text-anchor', 'middle') .attr('dy', '.35em') - .attr('transform', function (d) { + .attr('transform', function(d) { d.outerRadius = d.outerRadius * 2.1; d.innerRadius = d.outerRadius * 2.1; return 'translate(' + arc.svg.centroid(d) + ')'; }) - .text(function (d) { + .text(function(d) { return d.element; }); } } - renderer.drawTreatments = function drawTreatments(client) { - + renderer.drawTreatments = function drawTreatments (client) { + var treatmentCount = 0; chart().focus.selectAll('.draggable-treatment').remove(); - + _.forEach(client.ddata.treatments, function eachTreatment (d) { - if (Number(d.insulin) > 0 || Number(d.carbs) > 0) { treatmentCount += 1; }; + if (Number(d.insulin) > 0 || Number(d.carbs) > 0) { treatmentCount += 1; } }); - + // add treatment bubbles _.forEach(client.ddata.treatments, function eachTreatment (d) { renderer.drawTreatment(d, { @@ -896,9 +897,9 @@ function init (client, d3) { , treatments: treatmentCount }, client.sbx.data.profile.getCarbRatio(new Date())); }); - }; + } - renderer.drawTreatment = function drawTreatment(treatment, opts, carbratio) { + renderer.drawTreatment = function drawTreatment (treatment, opts, carbratio) { if (!treatment.carbs && !treatment.insulin) { return; } @@ -919,7 +920,7 @@ function init (client, d3) { var arc = prepareArc(treatment, radius); var treatmentDots = appendTreatments(treatment, arc); appendLabels(treatmentDots, arc, opts); - }; + } renderer.addBasals = function addBasals (client) { @@ -949,20 +950,20 @@ function init (client, d3) { while (date <= to) { var basalvalue = profile.getTempBasal(date); if (!_.isEqual(lastbasal, basalvalue)) { - linedata.push( { d: date, b: basalvalue.totalbasal } ); - notemplinedata.push( { d: date, b: basalvalue.basal } ); + linedata.push({ d: date, b: basalvalue.totalbasal }); + notemplinedata.push({ d: date, b: basalvalue.basal }); if (basalvalue.combobolustreatment && basalvalue.combobolustreatment.relative) { - tempbasalareadata.push( { d: date, b: basalvalue.tempbasal } ); - basalareadata.push( { d: date, b: 0 } ); - comboareadata.push( { d: date, b: basalvalue.totalbasal } ); + tempbasalareadata.push({ d: date, b: basalvalue.tempbasal }); + basalareadata.push({ d: date, b: 0 }); + comboareadata.push({ d: date, b: basalvalue.totalbasal }); } else if (basalvalue.treatment) { - tempbasalareadata.push( { d: date, b: basalvalue.totalbasal } ); - basalareadata.push( { d: date, b: 0 } ); - comboareadata.push( { d: date, b: 0 } ); + tempbasalareadata.push({ d: date, b: basalvalue.totalbasal }); + basalareadata.push({ d: date, b: 0 }); + comboareadata.push({ d: date, b: 0 }); } else { - tempbasalareadata.push( { d: date, b: 0 } ); - basalareadata.push( { d: date, b: basalvalue.totalbasal } ); - comboareadata.push( { d: date, b: 0 } ); + tempbasalareadata.push({ d: date, b: 0 }); + basalareadata.push({ d: date, b: basalvalue.totalbasal }); + comboareadata.push({ d: date, b: 0 }); } } lastbasal = basalvalue; @@ -971,15 +972,15 @@ function init (client, d3) { var toTempBasal = profile.getTempBasal(to); - linedata.push( { d: to, b: toTempBasal.totalbasal } ); - notemplinedata.push( { d: to, b: toTempBasal.basal } ); - basalareadata.push( { d: to, b: toTempBasal.basal } ); - tempbasalareadata.push( { d: to, b: toTempBasal.totalbasal } ); - comboareadata.push( { d: to, b: toTempBasal.totalbasal } ); + linedata.push({ d: to, b: toTempBasal.totalbasal }); + notemplinedata.push({ d: to, b: toTempBasal.basal }); + basalareadata.push({ d: to, b: toTempBasal.basal }); + tempbasalareadata.push({ d: to, b: toTempBasal.totalbasal }); + comboareadata.push({ d: to, b: toTempBasal.totalbasal }); - var max_linedata = d3.max(linedata, function (d) { return d.b; }); - var max_notemplinedata = d3.max(notemplinedata, function (d) { return d.b; }); - var max = Math.max(max_linedata, max_notemplinedata) * ('icicle' === mode ? 1 : 1.1 ); + var max_linedata = d3.max(linedata, function(d) { return d.b; }); + var max_notemplinedata = d3.max(notemplinedata, function(d) { return d.b; }); + var max = Math.max(max_linedata, max_notemplinedata) * ('icicle' === mode ? 1 : 1.1); chart().maxBasalValue = max; chart().yScaleBasals.domain('icicle' === mode ? [0, max] : [max, 0]); @@ -1051,7 +1052,7 @@ function init (client, d3) { .attr('fill', '#0099ff') .attr('text-anchor', 'middle') .attr('dy', '.35em') - .attr('x', chart().xScaleBasals((Math.max(t.mills, from) + Math.min(t.mills + times.mins(t.duration).msecs, to))/2)) + .attr('x', chart().xScaleBasals((Math.max(t.mills, from) + Math.min(t.mills + times.mins(t.duration).msecs, to)) / 2)) .attr('y', 10) .text((t.percent ? (t.percent > 0 ? '+' : '') + t.percent + '%' : '') + (isNaN(t.absolute) ? '' : Number(t.absolute).toFixed(2) + 'U') + (t.relative ? 'C: +' + t.relative + 'U' : '')); // better hide if not fit @@ -1070,19 +1071,19 @@ function init (client, d3) { } function profileTooltip (d) { - return ''+translate('Time')+': ' + client.formatTime(new Date(d.mills)) + '
' + - (d.eventType ? ''+translate('Treatment type')+': ' + translate(client.careportal.resolveEventName(d.eventType)) + '
' : '') + - (d.endprofile ? ''+translate('End of profile')+': ' + d.endprofile + '
' : '') + - (d.profile ? ''+translate('Profile')+': ' + d.profile + '
' : '') + - (d.duration ? ''+translate('Duration')+': ' + d.duration + translate('mins') + '
' : '') + - (d.enteredBy ? ''+translate('Entered By')+': ' + d.enteredBy + '
' : '') + - (d.notes ? ''+translate('Notes')+': ' + d.notes : ''); + return '' + translate('Time') + ': ' + client.formatTime(new Date(d.mills)) + '
' + + (d.eventType ? '' + translate('Treatment type') + ': ' + translate(client.careportal.resolveEventName(d.eventType)) + '
' : '') + + (d.endprofile ? '' + translate('End of profile') + ': ' + d.endprofile + '
' : '') + + (d.profile ? '' + translate('Profile') + ': ' + d.profile + '
' : '') + + (d.duration ? '' + translate('Duration') + ': ' + d.duration + translate('mins') + '
' : '') + + (d.enteredBy ? '' + translate('Entered By') + ': ' + d.enteredBy + '
' : '') + + (d.notes ? '' + translate('Notes') + ': ' + d.notes : ''); } // calculate position of profile on left side var from = chart().brush.extent()[0].getTime(); var to = chart().brush.extent()[1].getTime(); - var mult = (to-from) / times.hours(24).msecs; + var mult = (to - from) / times.hours(24).msecs; from += times.mins(20 * mult).msecs; var mode = client.settings.extendedSettings.basal.render; @@ -1096,12 +1097,12 @@ function init (client, d3) { _.forEach(client.ddata.profileTreatments, function eachTreatment (d) { if (d.duration && !d.cuttedby) { - data.push({ - cutting: d.profile - , profile: client.profilefunctions.activeProfileToTime(times.mins(d.duration).msecs + d.mills + 1) - , mills: times.mins(d.duration).msecs + d.mills - , end: true - }); + data.push({ + cutting: d.profile + , profile: client.profilefunctions.activeProfileToTime(times.mins(d.duration).msecs + d.mills + 1) + , mills: times.mins(d.duration).msecs + d.mills + , end: true + }); } }); @@ -1109,24 +1110,24 @@ function init (client, d3) { var topOfText = ('icicle' === mode ? chart().maxBasalValue + 0.05 : -0.05); - var generateText = function (t) { - var sign = t.first ? '▲▲▲' : '▬▬▬'; - var ret; - if (t.cutting) { - ret = sign + ' ' + t.cutting + ' ' + '►►►' + ' ' + t.profile + ' ' + sign; - } else { - ret = sign + ' ' + t.profile + ' ' + sign; - } - return ret; + var generateText = function(t) { + var sign = t.first ? '▲▲▲' : '▬▬▬'; + var ret; + if (t.cutting) { + ret = sign + ' ' + t.cutting + ' ' + '►►►' + ' ' + t.profile + ' ' + sign; + } else { + ret = sign + ' ' + t.profile + ' ' + sign; + } + return ret; }; treatProfiles.transition().duration(0) - .attr('transform', function (t) { + .attr('transform', function(t) { // change text of record on left side return 'rotate(-90,' + chart().xScale(t.mills) + ',' + chart().yScaleBasals(topOfText) + ') ' + - 'translate(' + chart().xScale(t.mills) + ',' + chart().yScaleBasals(topOfText) + ')'; + 'translate(' + chart().xScale(t.mills) + ',' + chart().yScaleBasals(topOfText) + ')'; }). - text(generateText); + text(generateText); treatProfiles.enter().append('text') .attr('class', 'g-profile') @@ -1135,12 +1136,12 @@ function init (client, d3) { .attr('fill', '#0099ff') .attr('text-anchor', 'end') .attr('dy', '.35em') - .attr('transform', function (t) { + .attr('transform', function(t) { return 'rotate(-90 ' + chart().xScale(t.mills) + ',' + chart().yScaleBasals(topOfText) + ') ' + 'translate(' + chart().xScale(t.mills) + ',' + chart().yScaleBasals(topOfText) + ')'; }) .text(generateText) - .on('mouseover', function (d) { + .on('mouseover', function(d) { client.tooltip.transition().duration(TOOLTIP_TRANS_MS).style('opacity', .9); client.tooltip.html(profileTooltip(d)) .style('left', (d3.event.pageX) + 'px') diff --git a/lib/data/calcdelta.js b/lib/data/calcdelta.js index 8e39885d86a..e3e0fde7052 100644 --- a/lib/data/calcdelta.js +++ b/lib/data/calcdelta.js @@ -108,7 +108,7 @@ module.exports = function calcDelta (oldData, newData) { // Calculate delta and assign delta over if changes were found var deltaData = (a === 'treatments' ? nsArrayTreatments(oldData[a], newData[a]) : nsArrayDiff(oldData[a], newData[a])); if (deltaData.length > 0) { - console.log('delta changes found on', a); + //console.log('delta changes found on', a); changesFound = true; sort(deltaData); delta[a] = deltaData; @@ -129,7 +129,7 @@ module.exports = function calcDelta (oldData, newData) { var o = skippableObjects[object]; if (newData.hasOwnProperty(o)) { if (JSON.stringify(newData[o]) !== JSON.stringify(oldData[o])) { - console.log('delta changes found on', o); + //console.log('delta changes found on', o); changesFound = true; delta[o] = newData[o]; } diff --git a/lib/data/dataloader.js b/lib/data/dataloader.js index cc303da1d72..cc4426aa6ab 100644 --- a/lib/data/dataloader.js +++ b/lib/data/dataloader.js @@ -11,6 +11,7 @@ var ONE_DAY = 86400000, function uniq(a) { var seen = {}; return a.filter(function(item) { + // eslint-disable-next-line no-prototype-builtins return seen.hasOwnProperty(item.mills) ? false : (seen[item.mills] = true); }); } @@ -222,8 +223,10 @@ function loadActivity(ddata, ctx, callback) { } function loadTreatments(ddata, ctx, callback) { + + // Load 2.5 days to cover last 48 hours including overlapping temp boluses or temp targets var dateRange = { - $gte: new Date(ddata.lastUpdated - (ONE_DAY * 8)).toISOString() + $gte: new Date(ddata.lastUpdated - (ONE_DAY * 2.5)).toISOString() }; if (ddata.page && ddata.page.frame) { dateRange['$lte'] = new Date(ddata.lastUpdated).toISOString(); @@ -237,7 +240,6 @@ function loadTreatments(ddata, ctx, callback) { } }; - console.log('searching treatments q', tq); ctx.treatments.list(tq, function(err, results) { if (!err && results) { mergeToTreatments(ddata, results); @@ -256,6 +258,7 @@ function loadProfileSwitchTreatments(ddata, ctx, callback) { dateRange['$lte'] = new Date(ddata.lastUpdated).toISOString(); } + // Load the latest profile switch treatment var tq = { find: { eventType: 'Profile Switch', @@ -291,6 +294,18 @@ function loadProfileSwitchTreatments(ddata, ctx, callback) { } function loadSensorAndInsulinTreatments(ddata, ctx, callback) { + async.parallel([ + loadLatestSingle.bind(null, ddata, ctx, 'Sensor Start') + ,loadLatestSingle.bind(null, ddata, ctx, 'Sensor Change') + ,loadLatestSingle.bind(null, ddata, ctx, 'Sensor Stop') + ,loadLatestSingle.bind(null, ddata, ctx, 'Site Change') + ,loadLatestSingle.bind(null, ddata, ctx, 'Insulin Change') + ,loadLatestSingle.bind(null, ddata, ctx, 'Pump Battery Change') + ], callback); +} + +function loadLatestSingle(ddata, ctx, dataType, callback) { + var dateRange = { $gte: new Date(ddata.lastUpdated - (ONE_DAY * 32)).toISOString() }; @@ -302,13 +317,14 @@ function loadSensorAndInsulinTreatments(ddata, ctx, callback) { var tq = { find: { eventType: { - $in: ['Sensor Start', 'Sensor Change', 'Insulin Change', 'Pump Battery Change'] + $eq: dataType }, created_at: dateRange }, sort: { created_at: -1 - } + }, + count: 1 }; ctx.treatments.list(tq, function(err, results) { diff --git a/lib/data/ddata.js b/lib/data/ddata.js index a055b9f3049..1912ca4a6ae 100644 --- a/lib/data/ddata.js +++ b/lib/data/ddata.js @@ -5,270 +5,269 @@ var times = require('../times'); var DEVICE_TYPE_FIELDS = ['uploader', 'pump', 'openaps', 'loop', 'xdripjs']; -function init() { - - var ddata = { - sgvs: [], - treatments: [], - mbgs: [], - cals: [], - profiles: [], - devicestatus: [], - food: [], - activity: [], - lastUpdated: 0 +function init () { + + var ddata = { + sgvs: [] + , treatments: [] + , mbgs: [] + , cals: [] + , profiles: [] + , devicestatus: [] + , food: [] + , activity: [] + , lastUpdated: 0 + }; + + ddata.clone = function clone () { + return _.clone(ddata, function(value) { + //special handling of mongo ObjectID's + //see https://github.com/lodash/lodash/issues/602#issuecomment-47414964 + + //instead of requiring Mongo.ObjectID here and having it get pulled into the bundle + //we'll look for the toHexString function and then assume it's an ObjectID + if (value && value.toHexString && value.toHexString.call && value.toString && value.toString.call) { + return value.toString(); + } + }); + }; + + ddata.splitRecent = function splitRecent (time, cutoff, max, treatmentsToo) { + var result = { + first: {} + , rest: {} }; - ddata.clone = function clone() { - return _.clone(ddata, function(value) { - //special handling of mongo ObjectID's - //see https://github.com/lodash/lodash/issues/602#issuecomment-47414964 + function recent (item) { + return item.mills >= time - cutoff; + } - //instead of requiring Mongo.ObjectID here and having it get pulled into the bundle - //we'll look for the toHexString function and then assume it's an ObjectID - if (value && value.toHexString && value.toHexString.call && value.toString && value.toString.call) { - return value.toString(); - } - }); - }; - - ddata.splitRecent = function splitRecent(time, cutoff, max, treatmentsToo) { - var result = { - first: {}, - rest: {} - }; + function filterMax (item) { + return item.mills >= time - max; + } - function recent(item) { - return item.mills >= time - cutoff; - } + function partition (field, filter) { + var data; + if (filter) { + data = ddata[field].filter(filterMax); + } else { + data = ddata[field]; + } - function filterMax(item) { - return item.mills >= time - max; - } + var parts = _.partition(data, recent); + result.first[field] = parts[0]; + result.rest[field] = parts[1]; + } - function partition(field, filter) { - var data; - if (filter) { - data = ddata[field].filter(filterMax); - } else { - data = ddata[field]; - } - - var parts = _.partition(data, recent); - result.first[field] = parts[0]; - result.rest[field] = parts[1]; - } + partition('treatments', treatmentsToo ? filterMax : false); - partition('treatments', treatmentsToo ? filterMax : false); + result.first.devicestatus = ddata.recentDeviceStatus(time); - result.first.devicestatus = ddata.recentDeviceStatus(time); + result.first.sgvs = ddata.sgvs.filter(filterMax); + result.first.cals = ddata.cals; - result.first.sgvs = ddata.sgvs.filter(filterMax); - result.first.cals = ddata.cals; - - var profiles = _.cloneDeep(ddata.profiles); - if (profiles && profiles[0]) - for (var k in profiles[0].store) { - if (profiles[0].store.hasOwnProperty(k)) { - if (k.indexOf('@@@@@') > 0) { - delete profiles[0].store[k]; - } - } - } - result.first.profiles = profiles; - - result.rest.mbgs = ddata.mbgs.filter(filterMax); - result.rest.food = ddata.food; - result.rest.activity = ddata.activity; - - console.log('results.first size', JSON.stringify(result.first).length, 'bytes'); - console.log('results.rest size', JSON.stringify(result.rest).length, 'bytes'); - - return result; - }; - - ddata.recentDeviceStatus = function recentDeviceStatus(time) { - - var deviceAndTypes = - _.chain(ddata.devicestatus) - .map(function eachStatus(status) { - return _.chain(status) - .keys() - .filter(function isExcluded(key) { - return _.includes(DEVICE_TYPE_FIELDS, key); - }) - .map(function toDeviceTypeKey(key) { - return { - device: status.device, - type: key - }; - }) - .value(); - }) - .flatten() - .uniqWith(_.isEqual) - .value(); - - //console.info('>>>deviceAndTypes', deviceAndTypes); - - var rv = _.chain(deviceAndTypes) - .map(function findMostRecent(deviceAndType) { - return _.chain(ddata.devicestatus) - .filter(function isSameDeviceType(status) { - return status.device === deviceAndType.device && _.has(status, deviceAndType.type) - }) - .filter(function notInTheFuture(status) { - return status.mills <= time; - }) - .sortBy('mills') - .takeRight(10) - .value(); - }).value(); - - var merged = [].concat.apply([], rv); - - rv = _.chain(merged) - .filter(_.isObject) - .uniq('_id') - .sortBy('mills') - .value(); - - return rv; - - }; - - ddata.processDurations = function processDurations(treatments, keepzeroduration) { - - treatments = _.uniqBy(treatments, 'mills'); - - // cut temp basals by end events - // better to do it only on data update - var endevents = treatments.filter(function filterEnd(t) { - return !t.duration; - }); - - function cutIfInInterval(base, end) { - if (base.mills < end.mills && base.mills + times.mins(base.duration).msecs > end.mills) { - base.duration = times.msecs(end.mills - base.mills).mins; - if (end.profile) { - base.cuttedby = end.profile; - end.cutting = base.profile; - } - } + var profiles = _.cloneDeep(ddata.profiles); + if (profiles && profiles[0]) { + Object.keys(profiles[0].store).forEach(k => { + if (k.indexOf('@@@@@') > 0) { + delete profiles[0].store[k]; } - - // cut by end events - treatments.forEach(function allTreatments(t) { - if (t.duration) { - endevents.forEach(function allEndevents(e) { - cutIfInInterval(t, e); - }); - } - }); - - // cut by overlaping events - treatments.forEach(function allTreatments(t) { - if (t.duration) { - treatments.forEach(function allEndevents(e) { - cutIfInInterval(t, e); - }); - } - }); - - if (keepzeroduration) { - return treatments; - } else { - return treatments.filter(function filterEnd(t) { - return t.duration; - }); + }) + } + result.first.profiles = profiles; + + result.rest.mbgs = ddata.mbgs.filter(filterMax); + result.rest.food = ddata.food; + result.rest.activity = ddata.activity; + + console.log('results.first size', JSON.stringify(result.first).length, 'bytes'); + console.log('results.rest size', JSON.stringify(result.rest).length, 'bytes'); + + return result; + }; + + ddata.recentDeviceStatus = function recentDeviceStatus (time) { + + var deviceAndTypes = + _.chain(ddata.devicestatus) + .map(function eachStatus (status) { + return _.chain(status) + .keys() + .filter(function isExcluded (key) { + return _.includes(DEVICE_TYPE_FIELDS, key); + }) + .map(function toDeviceTypeKey (key) { + return { + device: status.device + , type: key + }; + }) + .value(); + }) + .flatten() + .uniqWith(_.isEqual) + .value(); + + //console.info('>>>deviceAndTypes', deviceAndTypes); + + var rv = _.chain(deviceAndTypes) + .map(function findMostRecent (deviceAndType) { + return _.chain(ddata.devicestatus) + .filter(function isSameDeviceType (status) { + return status.device === deviceAndType.device && _.has(status, deviceAndType.type) + }) + .filter(function notInTheFuture (status) { + return status.mills <= time; + }) + .sortBy('mills') + .takeRight(10) + .value(); + }).value(); + + var merged = [].concat.apply([], rv); + + rv = _.chain(merged) + .filter(_.isObject) + .uniq('_id') + .sortBy('mills') + .value(); + + return rv; + + }; + + ddata.processDurations = function processDurations (treatments, keepzeroduration) { + + treatments = _.uniqBy(treatments, 'mills'); + + // cut temp basals by end events + // better to do it only on data update + var endevents = treatments.filter(function filterEnd (t) { + return !t.duration; + }); + + function cutIfInInterval (base, end) { + if (base.mills < end.mills && base.mills + times.mins(base.duration).msecs > end.mills) { + base.duration = times.msecs(end.mills - base.mills).mins; + if (end.profile) { + base.cuttedby = end.profile; + end.cutting = base.profile; } - }; - - ddata.processTreatments = function processTreatments(preserveOrignalTreatments) { - - // filter & prepare 'Site Change' events - ddata.sitechangeTreatments = ddata.treatments.filter(function filterSensor(t) { - return t.eventType.indexOf('Site Change') > -1; - }).sort(function(a, b) { - return a.mills > b.mills; + } + } + + // cut by end events + treatments.forEach(function allTreatments (t) { + if (t.duration) { + endevents.forEach(function allEndevents (e) { + cutIfInInterval(t, e); }); - - // filter & prepare 'Insulin Change' events - ddata.insulinchangeTreatments = ddata.treatments.filter(function filterInsulin(t) { - return t.eventType.indexOf('Insulin Change') > -1; - }).sort(function(a, b) { - return a.mills > b.mills; - }); - - // filter & prepare 'Pump Battery Change' events - ddata.batteryTreatments = ddata.treatments.filter(function filterSensor(t) { - return t.eventType.indexOf('Pump Battery Change') > -1; - }).sort(function(a, b) { - return a.mills > b.mills; - }); - - // filter & prepare 'Sensor' events - ddata.sensorTreatments = ddata.treatments.filter(function filterSensor(t) { - return t.eventType.indexOf('Sensor') > -1; - }).sort(function(a, b) { - return a.mills > b.mills; + } + }); + + // cut by overlaping events + treatments.forEach(function allTreatments (t) { + if (t.duration) { + treatments.forEach(function allEndevents (e) { + cutIfInInterval(t, e); }); - - // filter & prepare 'Profile Switch' events - var profileTreatments = ddata.treatments.filter(function filterProfiles(t) { - return t.eventType === 'Profile Switch'; - }).sort(function(a, b) { - return a.mills > b.mills; - }); - if (preserveOrignalTreatments) - profileTreatments = _.cloneDeep(profileTreatments); - ddata.profileTreatments = ddata.processDurations(profileTreatments, true); - - // filter & prepare 'Combo Bolus' events - ddata.combobolusTreatments = ddata.treatments.filter(function filterComboBoluses(t) { - return t.eventType === 'Combo Bolus'; - }).sort(function(a, b) { - return a.mills > b.mills; - }); - - // filter & prepare temp basals - var tempbasalTreatments = ddata.treatments.filter(function filterBasals(t) { - return t.eventType && t.eventType.indexOf('Temp Basal') > -1; - }); - if (preserveOrignalTreatments) - tempbasalTreatments = _.cloneDeep(tempbasalTreatments); - ddata.tempbasalTreatments = ddata.processDurations(tempbasalTreatments, false); - - // filter temp target - var tempTargetTreatments = ddata.treatments.filter(function filterTargets(t) { - //check for a units being sent - if (t.units) { - if (t.units == 'mmol') { - //convert to mgdl - t.targetTop = t.targetTop * 18; - t.targetBottom = t.targetBottom * 18; - t.units = 'mg/dl'; - } - } - //if we have a temp target thats below 20, assume its mmol and convert to mgdl for safety. - if (t.targetTop < 20) { - t.targetTop = t.targetTop * 18; - t.units = 'mg/dl'; - } - if (t.targetBottom < 20) { - t.targetBottom = t.targetBottom * 18; - t.units = 'mg/dl'; - } - return t.eventType && t.eventType.indexOf('Temporary Target') > -1; - }); - if (preserveOrignalTreatments) - tempTargetTreatments = _.cloneDeep(tempTargetTreatments); - ddata.tempTargetTreatments = ddata.processDurations(tempTargetTreatments, false); - - }; - - return ddata; + } + }); + + if (keepzeroduration) { + return treatments; + } else { + return treatments.filter(function filterEnd (t) { + return t.duration; + }); + } + }; + + ddata.processTreatments = function processTreatments (preserveOrignalTreatments) { + + // filter & prepare 'Site Change' events + ddata.sitechangeTreatments = ddata.treatments.filter(function filterSensor (t) { + return t.eventType.indexOf('Site Change') > -1; + }).sort(function(a, b) { + return a.mills > b.mills; + }); + + // filter & prepare 'Insulin Change' events + ddata.insulinchangeTreatments = ddata.treatments.filter(function filterInsulin (t) { + return t.eventType.indexOf('Insulin Change') > -1; + }).sort(function(a, b) { + return a.mills > b.mills; + }); + + // filter & prepare 'Pump Battery Change' events + ddata.batteryTreatments = ddata.treatments.filter(function filterSensor (t) { + return t.eventType.indexOf('Pump Battery Change') > -1; + }).sort(function(a, b) { + return a.mills > b.mills; + }); + + // filter & prepare 'Sensor' events + ddata.sensorTreatments = ddata.treatments.filter(function filterSensor (t) { + return t.eventType.indexOf('Sensor') > -1; + }).sort(function(a, b) { + return a.mills > b.mills; + }); + + // filter & prepare 'Profile Switch' events + var profileTreatments = ddata.treatments.filter(function filterProfiles (t) { + return t.eventType === 'Profile Switch'; + }).sort(function(a, b) { + return a.mills > b.mills; + }); + if (preserveOrignalTreatments) + profileTreatments = _.cloneDeep(profileTreatments); + ddata.profileTreatments = ddata.processDurations(profileTreatments, true); + + // filter & prepare 'Combo Bolus' events + ddata.combobolusTreatments = ddata.treatments.filter(function filterComboBoluses (t) { + return t.eventType === 'Combo Bolus'; + }).sort(function(a, b) { + return a.mills > b.mills; + }); + + // filter & prepare temp basals + var tempbasalTreatments = ddata.treatments.filter(function filterBasals (t) { + return t.eventType && t.eventType.indexOf('Temp Basal') > -1; + }); + if (preserveOrignalTreatments) + tempbasalTreatments = _.cloneDeep(tempbasalTreatments); + ddata.tempbasalTreatments = ddata.processDurations(tempbasalTreatments, false); + + // filter temp target + var tempTargetTreatments = ddata.treatments.filter(function filterTargets (t) { + //check for a units being sent + if (t.units) { + if (t.units == 'mmol') { + //convert to mgdl + t.targetTop = t.targetTop * 18; + t.targetBottom = t.targetBottom * 18; + t.units = 'mg/dl'; + } + } + //if we have a temp target thats below 20, assume its mmol and convert to mgdl for safety. + if (t.targetTop < 20) { + t.targetTop = t.targetTop * 18; + t.units = 'mg/dl'; + } + if (t.targetBottom < 20) { + t.targetBottom = t.targetBottom * 18; + t.units = 'mg/dl'; + } + return t.eventType && t.eventType.indexOf('Temporary Target') > -1; + }); + if (preserveOrignalTreatments) + tempTargetTreatments = _.cloneDeep(tempTargetTreatments); + ddata.tempTargetTreatments = ddata.processDurations(tempTargetTreatments, false); + + }; + + return ddata; } -module.exports = init; \ No newline at end of file +module.exports = init; diff --git a/lib/data/treatmenttocurve.js b/lib/data/treatmenttocurve.js index a96d3a795ce..8bca564d091 100644 --- a/lib/data/treatmenttocurve.js +++ b/lib/data/treatmenttocurve.js @@ -2,6 +2,9 @@ var _ = require('lodash'); +const MAX_BG_MMOL = 22; +const MAX_BG_MGDL = MAX_BG_MMOL * 18; + module.exports = function fitTreatmentsToBGCurve (ddata, env, ctx) { var settings = env.settings; @@ -62,15 +65,16 @@ module.exports = function fitTreatmentsToBGCurve (ddata, env, ctx) { console.warn('found an invalid glucose value', treatment); } else if (treatment.glucose && treatment.units) { if (treatment.units === 'mmol') { - treatment.mmol = Number(treatment.glucose); + treatment.mmol = Math.min(Number(treatment.glucose), MAX_BG_MMOL); } else { - treatment.mgdl = Number(treatment.glucose); + treatment.mgdl = Math.min(Number(treatment.glucose), MAX_BG_MGDL); } } else if (treatment.glucose) { //no units, assume everything is the same //console.warn('found a glucose value without any units, maybe from an old version?', _.pick(treatment, '_id', 'created_at', 'enteredBy')); var units = settings.units === 'mmol' ? 'mmol' : 'mgdl'; - treatment[units] = Number(treatment.glucose); + + treatment[units] = settings.units === 'mmol' ? Math.min(Number(treatment.glucose), MAX_BG_MMOL) : Math.min(Number(treatment.glucose), MAX_BG_MGDL); } else { treatment.mgdl = mgdlByTime(); } diff --git a/lib/language.js b/lib/language.js index 875582c6298..b7c826d3a73 100644 --- a/lib/language.js +++ b/lib/language.js @@ -102,7 +102,7 @@ function init() { ,sv: 'Tis' ,ro: 'Ma' ,bg: 'Вт' - ,hr: 'Ut' + ,hr: 'Uto' ,it: 'Mar' ,ja: '火' ,dk: 'Tir' @@ -488,7 +488,7 @@ function init() { ,ru: 'Имя' ,sk: 'Meno' ,nl: 'Naam' - ,ko: '이름' + ,ko: '프로파일 명' ,tr: 'İsim' ,zh_cn: '名称' } @@ -834,7 +834,6 @@ function init() { ,dk: 'Noter indeholder' ,fi: 'Merkinnät sisältävät' ,nb: 'Notater inneholder' - ,he: 'הערות מכילות' ,pl: 'Zawierają uwagi' ,ru: 'Примечания содержат' ,sk: 'Poznámky obsahujú' @@ -914,7 +913,7 @@ function init() { ,ru: 'Показать' ,sk: 'Ukáž' ,nl: 'Laat zien' - ,ko: '보여 주세요~' + ,ko: '확인' ,tr: 'Göster' ,zh_cn: '生成' } @@ -1316,7 +1315,7 @@ function init() { ,ru: 'Ежедневно' ,sk: 'Deň po dni' ,nl: 'Dag tot Dag' - ,ko: '날짜' + ,ko: '일별 그래프' ,tr: 'Günden Güne' ,zh_cn: '日到日' } @@ -1330,7 +1329,7 @@ function init() { ,sv: 'Week to week' ,ro: 'Week to week' ,bg: 'Week to week' - ,hr: 'Week to week' + ,hr: 'Tjedno' ,it: 'Week to week' ,dk: 'Week to week' ,fi: 'Week to week' @@ -1340,7 +1339,7 @@ function init() { ,ru: 'Week to week' ,sk: 'Week to week' ,nl: 'Week to week' - ,ko: 'Week to week' + ,ko: '주별 그래프' ,zh_cn: 'Week to week' } ,'Daily Stats' : { @@ -1364,7 +1363,7 @@ function init() { ,ru: 'Ежедневная статистика' ,sk: 'Denné štatistiky' ,nl: 'Dagelijkse statistiek' - ,ko: '날짜 통계' + ,ko: '일간 통계' ,tr: 'Günlük İstatistikler' ,zh_cn: '每日状态' } @@ -1377,7 +1376,7 @@ function init() { ,pt: 'Percentis' ,ro: 'Grafic percentile' ,bg: 'Процентна графика' - ,hr: 'Tablica u postotcima' + ,hr: 'Percentili' ,sv: 'Procentgraf' ,it: 'Grafico percentile' ,ja: 'パーセント図' @@ -1439,7 +1438,7 @@ function init() { ,ru: 'Почасовая статистика' ,sk: 'Hodinové štatistiky' ,nl: 'Statistieken per uur' - ,ko: '시간 통계' + ,ko: '시간대별 통계' ,tr: 'Saatlik istatistikler' ,zh_cn: '每小时状态' } @@ -1451,6 +1450,7 @@ function init() { ,de: 'netIOB Statistiken' ,fi: 'netIOB tilasto' ,bg: 'netIOB татистика' + ,hr: 'netIOB statistika' ,ru: 'статистика netIOB' ,tr: 'netIOB istatistikleri' } @@ -1459,15 +1459,14 @@ function init() { ,sv: 'temp basal måste vara synlig för denna rapport' ,de: 'temporäre Basalraten müssen für diesen Report sichtbar sein' ,fi: 'tämä raportti vaatii, että basaalien piirto on päällä' - ,he: 'חובה לאפשר רמה בזלית זמנית כדי לרות דוח זה' ,bg: 'временните базали трябва да са показани за да се покаже тази това' + ,hr: 'temp bazali moraju biti prikazani kako bi se vidio ovaj izvještaj' ,he: 'חובה לאפשר רמה בזלית זמנית כדי לרות דוח זה' ,ru: 'Для этого отчета требуется показать данные о врем базалах' ,tr: 'Bu raporu görüntülemek için geçici bazal oluşturulmalıdır' } ,'Weekly success' : { cs: 'Statistika po týdnech' - ,he: 'הצלחה שבועית' ,de: 'Wöchentlicher Erfolg' ,es: 'Resultados semanales' ,fr: 'Résultat hebdomadaire' @@ -1745,7 +1744,6 @@ function init() { cs: 'Normální' ,de: 'Normal' ,es: 'Normal' - ,he: 'נורמלי ' ,fr: 'Normale' ,el: 'Εντός Στόχου' ,pt: 'Normal' @@ -1863,13 +1861,12 @@ function init() { ,ru: 'Суточная статистика' ,sk: 'Denné štatistiky' ,nl: 'Dagelijkse statistieken' - ,ko: '날짜 통계 보고서' + ,ko: '일간 통계 보고서' ,tr: 'Günlük istatistikler raporu' ,zh_cn: '每日状态报表' } ,'Glucose Percentile report' : { cs: 'Tabulka percentil glykémií' - ,he: 'דוח אחוזוני גלוקוזה' ,de: 'Glukose-Perzentil Bericht' ,es: 'Informe de percetiles de glucemia' ,fr: 'Rapport percentiles Glycémie' @@ -1939,7 +1936,7 @@ function init() { ,ru: 'всего дней' ,sk: 'dní celkom' ,nl: 'Totaal dagen' - ,ko: '날짜 전체' + ,ko: '일 전체' ,tr: 'toplam gün' ,zh_cn: '天总计' } @@ -1953,7 +1950,7 @@ function init() { ,sv: 'antal dagar' ,ro: 'total zile' ,bg: 'общо за деня' - ,hr: 'ukupno dana' + ,hr: 'Ukupno po danu' ,it: 'Giorni totali' ,dk: 'antal dage' ,fi: 'päivän arvio' @@ -1963,7 +1960,7 @@ function init() { ,ru: 'всего за сутки' ,sk: 'dní celkom' ,nl: 'Totaal dagen' - ,ko: '날짜 전체' + ,ko: '하루 총량' ,tr: 'Günlük toplam' ,zh_cn: '天总计' } @@ -1977,7 +1974,7 @@ function init() { ,sv: 'Genomsnitt' ,ro: 'General' ,bg: 'Общо' - ,hr: 'Ukupno' + ,hr: 'Sveukupno' ,it: 'Generale' ,ja: '総合' ,dk: 'Gennemsnit' @@ -2038,7 +2035,7 @@ function init() { ,ru: '% измерений' ,sk: '% záznamov' ,nl: '% metingen' - ,ko: '% 읽는 중' + ,ko: '수신된 혈당 비율(%)' ,tr: '% Okumaların' ,zh_cn: '%已读取' } @@ -2063,7 +2060,7 @@ function init() { ,ru: 'кол-во измерений' ,sk: 'Počet záznamov' ,nl: 'Aantal metingen' - ,ko: '# 읽는 중' + ,ko: '수신된 혈당 개수(#)' ,tr: '# Okumaların' ,zh_cn: '#已读取' } @@ -2194,7 +2191,6 @@ function init() { } ,'Weekly Success' : { cs: 'Týdenní úspěšnost' - ,he: 'הצלחה שבועית ' ,de: 'Wöchtlicher Erfolg' ,es: 'Resultados semanales' ,fr: 'Réussite hebdomadaire' @@ -2261,7 +2257,6 @@ function init() { ,dk: 'Anvender gemt API-nøgle' ,fi: 'Tallennettu salainen API-tarkiste käytössä' ,nb: 'Bruker lagret API nøkkel' - ,he: 'עורך אוכל' ,pl: 'Korzystając z zapisanego poufnego hasha API' ,ru: 'Применение сохраненного пароля API' ,sk: 'Používam uložený API hash heslo' @@ -2273,7 +2268,6 @@ function init() { } ,'No API secret hash stored yet. You need to enter API secret.' : { cs: 'Není uložený žádný hash API hesla. Musíte zadat API heslo.' - ,he: 'הכנס את סיסמת ממשק תכנות יישומים הסודית' ,de: 'Keine API-Prüfsumme gespeichert. Bitte API-Prüfsumme eingeben.' ,es: 'No se ha almacenado ningún hash todavía. Debe introducir su secreto API.' ,fr: 'Pas de secret API existant. Vous devez en entrer un.' @@ -2300,7 +2294,6 @@ function init() { } ,'Database loaded' : { cs: 'Databáze načtena' - ,he: 'אגר מידע נטען ' ,de: 'Datenbank geladen' ,es: 'Base de datos cargada' ,fr: 'Base de données chargée' @@ -2361,6 +2354,7 @@ function init() { ,dk: 'Error' ,sv: 'Error' ,bg: 'Error' + ,hr: 'Greška' ,it: 'Error' ,fi: 'Error' ,pl: 'Error' @@ -2493,7 +2487,6 @@ function init() { ,pl: 'IG' ,ru: 'ГИ' ,sk: 'GI' - ,he: 'GI' ,nl: 'Glycemische index ' ,ko: '혈당 지수' ,tr: 'GI-Glisemik İndeks' @@ -2520,7 +2513,7 @@ function init() { ,ru: 'Редактировать запись' ,sk: 'Upraviť záznam' ,nl: 'Bewerk invoer' - ,ko: '편집' + ,ko: '편집기록' ,tr: 'Kaydı düzenle' ,zh_cn: '编辑记录' } @@ -2545,7 +2538,7 @@ function init() { ,ru: 'Стереть запись' ,sk: 'Zmazať záznam' ,nl: 'Verwijder invoer' - ,ko: '삭제' + ,ko: '삭제기록' ,tr: 'Kaydı sil' ,zh_cn: '删除记录' } @@ -2635,7 +2628,6 @@ function init() { ,ro: 'Cheia API trebuie să aibă mai mult de 12 caractere' ,bg: 'Вашата АPI парола трябва да е дълга поне 12 символа' ,hr: 'Vaš tajni API mora sadržavati barem 12 znakova' - ,he:' הסיסמא הסודית חייבת להיות באורך של 12 תווים לפחות' ,sv: 'Hemlig API-nyckel måsta innehålla 12 tecken' ,it: 'il vostro API secreto deve essere lungo almeno 12 caratteri' ,ja: 'APIシークレットは12文字以上の長さが必要です' @@ -2670,7 +2662,6 @@ function init() { ,nb: 'Ugyldig API nøkkel' ,pl: 'Błędny klucz API' ,ru: 'Плохой пароль API' - ,he: ' הסיסמא הסודית אינה חוקית' ,sk: 'Nesprávne API heslo' ,nl: 'Onjuist API wachtwoord' ,ko: '잘못된 API secret' @@ -2696,7 +2687,6 @@ function init() { ,fi: 'API salaisuus talletettu' ,nb: 'API nøkkel lagret' ,pl: 'Poufne klucz API zapisane' - ,he: ' הסיסמא הסודית נשמרה' ,ru: 'Хэш пароля API сохранен' ,sk: 'Hash API hesla uložený' ,nl: 'API wachtwoord opgeslagen' @@ -2747,7 +2737,6 @@ function init() { ,dk: 'Ikke indlæst' ,fi: 'Ei ladattu' ,nb: 'Ikke lest' - ,he: 'לא נטען' ,pl: 'Nie załadowany' ,ru: 'Не загружено' ,sk: 'Nenačítaný' @@ -2770,7 +2759,6 @@ function init() { ,sv: 'Födoämneseditor' ,it: 'NS - Database Alimenti' ,ja: '食事編集' - ,he: 'עורך מזון' ,dk: 'Mad editor' ,fi: 'Muokkaa ruokia' ,nb: 'Mat editor' @@ -2778,7 +2766,7 @@ function init() { ,ru: 'Редактор еды' ,sk: 'Editor jedál' ,nl: 'Voeding beheer' - ,ko: '음식 편집기' + ,ko: '음식 편집' ,tr: 'Gıda Editörü' ,zh_cn: '食物编辑器' } @@ -2970,7 +2958,6 @@ function init() { ,ro: 'Cheia API' ,bg: 'Твоята API парола' ,hr: 'Vaš tajni API' - ,he: 'הסיסמא הסודית שלך' ,it: 'Il tuo API secreto' ,ja: 'あなたのAPI Secret' ,dk: 'Din API-nøgle' @@ -3002,7 +2989,6 @@ function init() { ,dk: 'Gemme hash på denne computer (brug kun på privat computer)' ,fi: 'Tallenna avain tälle tietokoneelle (käytä vain omalla tietokoneellasi)' ,nb: 'Lagre hash på denne pc (bruk kun på privat pc)' - ,he:'שמור סיסמא הסודית על המחשב ( יש להשתמש רק על מחשב פרטי)' ,pl: 'Zapisz na tym komputerze (korzystaj tylko na komputerach prywatnych)' ,ru: 'Сохранить хеш на этом ПК (только для личных компьютеров)' ,sk: 'Uložiť hash na tomto počítači (Používajte iba na súkromných počítačoch)' @@ -3033,7 +3019,7 @@ function init() { ,ru: 'Лечение' ,sk: 'Ošetrenie' ,nl: 'Behandelingen' - ,ko: '대처' + ,ko: '관리' ,tr: 'Tedaviler' ,zh_cn: '操作' } @@ -3134,7 +3120,7 @@ function init() { ,ru: 'Введено от' ,sk: 'Zadal' ,nl: 'Ingevoerd door' - ,ko: '입력됨' + ,ko: '입력 내용' ,tr: 'Tarafından girildi' ,zh_cn: '输入人' } @@ -3172,7 +3158,7 @@ function init() { ,pt: 'Carboidratos' ,ro: 'Carbohidrați' ,bg: 'ВХ' - ,hr: 'Količina UH' + ,hr: 'Količina UGH' ,sv: 'Antal kolhydrater' ,it: 'Carboidrati' ,ja: '摂取糖質量' @@ -3498,7 +3484,7 @@ function init() { ,pt: 'Usar correção de COB no cálculo' ,ro: 'Folosește COB în calcule' ,bg: 'Включи активните ВХ в изчислението' - ,hr: 'Koristi aktivne UH u izračunu' + ,hr: 'Koristi aktivne UGH u izračunu' ,sv: 'Använd aktiva kolhydrater för beräkning' ,it: 'Utilizzare la correzione COB nel calcolo' ,ja: 'COB補正計算を使用' @@ -3647,7 +3633,7 @@ function init() { ,pt: 'Carboidratos necessários' ,ro: 'Necesar carbohidrați' ,bg: 'Необходими въглехидрати' - ,hr: 'Potrebno UH' + ,hr: 'Potrebno UGH' ,sv: 'Beräknad kolhydratmängd' ,it: 'Carboidrati necessari' ,ja: '必要糖質量' @@ -3673,7 +3659,7 @@ function init() { ,pt: 'Carboidratos necessários se Insulina total for negativa' ,ro: 'Carbohidrați când necesarul de insulină este negativ' ,bg: 'Необходими въглехидрати, ако няма инсулин' - ,hr: 'Potrebno UH ako je ukupna vrijednost inzulina negativna' + ,hr: 'Potrebno UGH ako je ukupna vrijednost inzulina negativna' ,sv: 'Nödvändig kolhydratmängd för angiven insulinmängd' ,it: 'Carboidrati necessari se l\'insulina totale è un valore negativo' ,ja: 'インスリン合計値がマイナスであればカーボ値入力が必要です。' @@ -3709,7 +3695,7 @@ function init() { ,ru: 'Скорость базала' ,sk: 'Bazál' ,nl: 'Basaal snelheid' - ,ko: '기초량 비율' + ,ko: 'Basal 단위' ,tr: 'Basal oranı' ,zh_cn: '基础率' } @@ -4097,7 +4083,7 @@ function init() { ,sv: 'Överför händelse' ,ro: 'Trimite formularul' ,bg: 'Въвеждане на данните' - ,hr: 'Predaj obrazac' + ,hr: 'Spremi' ,it: 'Invia il modulo' ,ja: 'フォームを投稿する' ,dk: 'Gem hændelsen' @@ -4133,7 +4119,7 @@ function init() { ,ru: 'Редактор профиля' ,sk: 'Editor profilu' ,nl: 'Profiel beheer' - ,ko: '프로 편집기' + ,ko: '프로파일 편집' ,tr: 'Profil Düzenleyicisi' ,zh_cn: '配置文件编辑器' ,zh_tw: '配置文件編輯器' @@ -4149,7 +4135,7 @@ function init() { ,sv: 'Rapportverktyg' ,ro: 'Instrumente raportare' ,bg: 'Статистика' - ,hr: 'Alat za prijavu' + ,hr: 'Izvještaji' ,it: 'NS - Statistiche' ,ja: '報告' ,dk: 'Rapporteringsværktøj' @@ -4542,7 +4528,7 @@ function init() { ,ru: 'Масштаб' ,sk: 'Mierka' ,nl: 'Schaal' - ,ko: '규모' + ,ko: '스케일' ,tr: 'Ölçek' ,zh_cn: '函数' ,zh_tw: '函數' @@ -4594,7 +4580,7 @@ function init() { ,ru: 'Логарифмический' ,sk: 'Logaritmické' ,nl: 'Logaritmisch' - ,ko: '다수' + ,ko: 'Logarithmic' ,tr: 'Logaritmik' ,zh_cn: '对数' ,zh_tw: '對數' @@ -4611,6 +4597,7 @@ function init() { ,el: 'Λογαριθμική (Δυναμική)' ,ro: 'Logaritmic (Dinamic)' ,bg: 'Логоритмична (Динамична)' + ,hr: 'Logaritamski (Dinamički)' ,nb: 'Logaritmisk (Dynamisk)' ,fi: 'Logaritminen (Dynaaminen)' ,sv: 'Logaritmisk (Dynamisk)' @@ -4637,6 +4624,7 @@ function init() { ,el: 'Ενεργή Ινσουλίνη (IOB)' ,ro: 'IOB-Insulină activă' ,bg: 'Активен инсулин' + ,hr: 'Aktivni inzulin' ,fi: 'Aktiivinen insuliini (IOB)' ,sv: 'Aktivt insulin (IOB)' ,pl: 'Aktywna insulina (IOB)' @@ -4662,6 +4650,7 @@ function init() { ,el: 'Ενεργοί Υδατάνθρακες (COB)' ,ro: 'COB-Carbohidrați activi' ,bg: 'Активни въглехидрати' + ,hr: 'Aktivni ugljikohidrati' ,fi: 'Aktiivinen hiilihydraatti (COB)' ,sv: 'Aktiva kolhydrater (COB)' ,pl: 'Aktywne wglowodany (COB)' @@ -4687,6 +4676,7 @@ function init() { ,el: 'Εργαλείο Εκτίμησης Επάρκειας Ινσουλίνης (BWP)' ,ro: 'BWP-Sugestie de bolusare' ,bg: 'Болус калкулатор' + ,hr: 'Pregled bolus čarobnjaka' ,fi: 'Aterialaskurin Esikatselu (BWP)' ,sv: 'Boluskalkylator (BWP)' ,pl: 'Kalkulator Bolusa (BWP)' @@ -4712,6 +4702,7 @@ function init() { ,el: 'Τιμή ανακτήθηκε' ,ro: 'Valoare încărcată' ,bg: 'Стойност заредена' + ,hr: 'Vrijednost učitana' ,fi: 'Arvo ladattu' ,sv: 'Laddat värde' ,pl: 'Wartości wczytane' @@ -4719,7 +4710,7 @@ function init() { ,ru: 'Величина загружена' ,nl: 'Waarde geladen' ,sk: 'Hodnoty načítané' - ,ko: '값이 로드됨' + ,ko: '데이터가 로드됨' ,tr: 'Yüklenen Değer' ,zh_cn: '数值已读取' ,zh_tw: '數值已讀取' @@ -4737,6 +4728,7 @@ function init() { ,nb: 'Nålalder' ,ro: 'CAGE-Vechime canulă' ,bg: 'Възраст на канюлата' + ,hr: 'Starost kanile' ,fi: 'Kanyylin ikä (CAGE)' ,sv: 'Kanylålder (CAGE)' ,pl: 'Czas wkłucia (CAGE)' @@ -4762,6 +4754,7 @@ function init() { ,nb: 'Basalprofil' ,ro: 'Profil bazală' ,bg: 'Базален профил' + ,hr: 'Bazalni profil' ,fi: 'Basaaliprofiili' ,sv: 'Basalprofil' ,pl: 'Profil dawki bazowej' @@ -5768,6 +5761,7 @@ function init() { ,de: 'Pumpenbatterie wechseln' ,fi: 'Pumpun patterin vaihto' ,bg: 'Смяна на батерия на помпата' + ,hr: 'Zamjena baterije pumpe' ,ja: 'ポンプバッテリー交換' ,pl: 'Zmiana baterii w pompie' ,ru: 'замена батареи помпы' @@ -5780,6 +5774,7 @@ function init() { ,de: 'Pumpenbatterie niedrig Alarm' ,fi: 'Varoitus! Pumpun patteri loppumassa' ,bg: 'Аларма за слаба батерия на помпата' + ,hr: 'Upozorenje slabe baterije pumpe' ,ja: 'ポンプバッテリーが低下' ,pl: 'Alarm! Niski poziom baterii w pompie' ,ru: 'Внимание! низкий заряд батареи помпы' @@ -5792,6 +5787,7 @@ function init() { ,de: 'Pumpenbatterie Wechsel überfällig!' ,fi: 'Pumpun patterin vaihto myöhässä!' ,bg: 'Смяната на батерията на помпата - наложителна' + ,hr: 'Prošao je rok za zamjenu baterije pumpe!' ,ja: 'ポンプバッテリー交換期限切れてます!' , pl: 'Bateria pompy musi być wymieniona!' ,ru: 'пропущен срок замены батареи!' @@ -6333,6 +6329,7 @@ function init() { ,ro: 'Culori pentru cei cu deficiențe de vedere' ,ko: '색맹 친화적인 색상' ,bg: 'Цветове за далтонисти' + ,hr: 'Boje za daltoniste' ,it: 'Colori per daltonici' ,ja: '色覚異常の方向けの色' ,fi: 'Värisokeille sopivat värit' @@ -6364,7 +6361,7 @@ function init() { ,sk: 'Resetovať do pôvodného nastavenia' ,nl: 'Herstel standaard waardes' ,ko: '초기화 그리고 초기설정으로 사용' - ,tr: 'Sıfırla ve varsayılanları kullan' + ,tr: 'Sıfırla ve varsayılanları kullan' ,zh_cn: '使用默认值重置' ,zh_tw: '使用默認值重置' } @@ -6545,7 +6542,7 @@ function init() { ,sk: 'hod. pred' ,nl: 'uren geleden' ,ko: '시간 전' - ,tr: 'saatler önce' + ,tr: 'saat önce' ,zh_cn: '小时前' ,zh_tw: '小時前' } @@ -6950,7 +6947,7 @@ function init() { ,ru: 'О приложении' ,sk: 'O aplikácii' ,nl: 'Over' - ,ko: '대하여' + ,ko: '정보' ,tr: 'Hakkında' ,zh_cn: '关于' ,zh_tw: '關於' @@ -6989,7 +6986,7 @@ function init() { ,pt: 'Hora do carboidrato' ,ro: 'Ora carbohidrați' ,bg: 'Ядене след' - ,hr: 'Vrijeme unosa UH' + ,hr: 'Vrijeme unosa UGH' ,sv: 'Kolhydratstid' ,it: 'Tempo' ,ja: 'カーボ時間' @@ -7019,6 +7016,7 @@ function init() { ,pt: 'Língua' ,ro: 'Limba' ,bg: 'Език' + ,hr: 'Jezik' ,pl: 'Język' ,it: 'Lingua' ,ja: '言語' @@ -7041,6 +7039,7 @@ function init() { ,ro: 'Adaugă nou' ,el: 'Προσθήκη' ,bg: 'Добави нов' + ,hr: 'Dodaj novi' ,nb: 'Legg til ny' ,fi: 'Lisää uusi' ,pl: 'Dodaj nowy' @@ -7064,6 +7063,7 @@ function init() { ,sv: 'g' ,ro: 'g' ,bg: 'гр' + ,hr: 'g' ,nb: 'g' ,fi: 'g' ,pl: 'g' @@ -7088,6 +7088,7 @@ function init() { ,sv: 'ml' ,ro: 'ml' ,bg: 'мл' + ,hr: 'ml' ,nb: 'ml' ,fi: 'ml' ,pl: 'ml' @@ -7112,6 +7113,7 @@ function init() { ,sv: 'st' ,ro: 'buc' ,bg: 'бр' + ,hr: 'kom' ,nb: 'stk' ,fi: 'kpl' ,pl: 'cz.' @@ -7137,6 +7139,7 @@ function init() { ,ro: 'Drag&drop aliment aici' ,el: 'Σύρετε εδώ φαγητό' ,bg: 'Хвани и премести храна тук' + ,hr: 'Privuci hranu ovdje' ,nb: 'Dra og slipp mat her' ,fi: 'Pudota ruoka tähän' ,pl: 'Tutaj przesuń/upuść jedzenie' @@ -7160,6 +7163,7 @@ function init() { ,dk: 'Omsorgsportal' ,ro: 'Care Portal' ,bg: 'Въвеждане на данни' + ,hr: 'Care Portal' ,nb: 'Omsorgsportal' ,fi: 'Hoidot' ,pl: 'Care Portal' @@ -7183,6 +7187,7 @@ function init() { ,ro: 'Mediu/Necunoscut' ,el: 'Μέσος/Άγνωστος' ,bg: 'Среден/неизвестен' + ,hr: 'Srednji/Nepoznat' ,nb: 'Medium/ukjent' ,fi: 'Keskiarvo/Ei tiedossa' ,pl: 'Średni/nieznany' @@ -7206,6 +7211,7 @@ function init() { ,dk: 'I fremtiden' ,el: 'ΣΤΟ ΜΕΛΛΟΝ' ,bg: 'В БЪДЕШЕТО' + ,hr: 'U BUDUĆNOSTI' ,nb: 'I fremtiden' ,fi: 'TULEVAISUUDESSA' ,pl: 'W PRZYSZŁOŚCI' @@ -7231,6 +7237,7 @@ function init() { ,el: 'Ενημέρωση' ,ro: 'Actualizare' ,bg: 'Актуализирай' + ,hr: 'Osvježi' ,it: 'Aggiornamento' ,pl: 'Aktualizacja' ,fi: 'Tallenna' @@ -7254,6 +7261,7 @@ function init() { ,el: 'Σειρά κατάταξης' ,ro: 'Sortare' ,bg: 'Ред' + ,hr: 'Sortiranje' ,it: 'Ordina' ,pl: 'Kolejność' ,pt: 'Ordenar' @@ -7277,6 +7285,7 @@ function init() { ,el: 'τα παλαιότερα πρώτα' ,ro: 'mai vechi primele' ,bg: 'Старите най-отгоре' + ,hr: 'najstarije na vrhu' ,it: 'più vecchio in alto' ,pl: 'Najstarszy na górze' ,pt: 'mais antigos no topo' @@ -7300,6 +7309,7 @@ function init() { ,el: 'τα νεότερα πρώτα' ,ro: 'mai noi primele' ,bg: 'Новите най-отгоре' + ,hr: 'najnovije na vrhu' ,it: 'più recente in alto' ,pl: 'Najnowszy na górze' ,pt: 'Mais recentes no topo' @@ -7324,6 +7334,7 @@ function init() { ,el: 'Όλα τα συμβάντα του αισθητήρα' ,ro: 'Evenimente legate de senzor' ,bg: 'Всички събития от сензора' + ,hr: 'Svi događaji senzora' ,it: 'Tutti gli eventi del sensore' ,fi: 'Kaikki sensorin tapahtumat' ,pl: 'Wszystkie zdarzenia sensora' @@ -7347,6 +7358,7 @@ function init() { ,ro: 'Șterge date din viitor din baza de date mongo' ,sv: 'Ta bort framtida händelser från mongodatabasen' ,bg: 'Премахни бъдещите точки от Монго базата с данни' + ,hr: 'Obriši buduće zapise iz baze podataka' ,it: 'Rimuovere gli oggetti dal database di mongo in futuro' ,fi: 'Poista tapahtumat mongo-tietokannasta' ,pl: 'Usuń przyszłe/błędne wpisy z bazy mongo' @@ -7371,6 +7383,7 @@ function init() { ,ro: 'Caută și elimină tratamente din viitor' ,sv: 'Hitta och ta bort framtida behandlingar' ,bg: 'Намери и премахни събития в бъдещето' + ,hr: 'Nađi i obriši tretmane u budućnosti' ,it: 'Individuare e rimuovere le somministrazioni in futuro' ,fi: 'Etsi ja poista tapahtumat joiden aikamerkintä on tulevaisuudessa' ,pt: 'Encontrar e remover tratamentos futuros' @@ -7395,6 +7408,7 @@ function init() { ,ro: 'Acest instrument curăță tratamentele din viitor.' ,sv: 'Denna uppgift hittar och rensar framtida händelser' ,bg: 'Тази опция намира и премахва събития в бъдещето.' + ,hr: 'Ovo nalazi i briše tretmane u budućnosti' ,it: 'Trovare e rimuovere le somministrazioni in futuro' ,fi: 'Tämä työkalu poistaa tapahtumat joiden aikamerkintä on tulevaisuudessa.' ,pl: 'To narzędzie znajduje i usuwa przyszłe/błędne zabiegi' @@ -7419,6 +7433,7 @@ function init() { ,ro: 'Șterge tratamentele din viitor' ,sv: 'Ta bort framtida händelser' ,bg: 'Премахни събитията в бъдешето' + ,hr: 'Obriši tretmane u budućnosti' ,it: 'Rimuovere somministrazioni in futuro' ,fi: 'Poista tapahtumat' ,pl: 'Usuń zabiegi w przyszłości' @@ -7441,6 +7456,7 @@ function init() { ,nb: 'Finn og fjern fremtidige hendelser' ,el: 'Εύρεση και αφαίρεση μελλοντικών εγγραφών από τη βάση δεδομένων' ,bg: 'Намери и премахни данни от сензора в бъдещето' + ,hr: 'Nađi i obriši zapise u budućnosti' ,ro: 'Caută și elimină valorile din viitor' ,sv: 'Hitta och ta bort framtida händelser' ,it: 'Trovare e rimuovere le voci in futuro' @@ -7465,6 +7481,7 @@ function init() { ,es: 'Este comando encuentra y elimina datos del sensor futuros creados por actualizaciones con errores en fecha/hora' ,dk: 'Denne handling finder og fjerner CGM data i fremtiden forårsaget af indlæsning med forkert dato/tid.' ,bg: 'Тази опция ще намери и премахне данни от сензора в бъдещето, създадени поради грешна дата/време.' + ,hr: 'Ovo nalazi i briše podatke sa senzora u budućnosti nastalih s uploaderom sa krivim datumom/vremenom' ,ro: 'Instrument de căutare și eliminare a datelor din viitor, create de uploader cu ora setată greșit' ,sv: 'Denna uppgift hittar och tar bort framtida CGM-data skapad vid felaktig tidsinställning' ,it: 'Trovare e rimuovere i dati CGM in futuro creato da uploader/xdrip con data/ora sbagliato.' @@ -7489,6 +7506,7 @@ function init() { ,dk: 'Fjern indgange i fremtiden' ,el: 'Αφαίρεση μελλοντικών ενεργειών' ,bg: 'Премахни данните от сензора в бъдещето' + ,hr: 'Obriši zapise u budućnosti' ,ro: 'Elimină înregistrările din viitor' ,sv: 'Ta bort framtida händelser' ,it: 'Rimuovere le voci in futuro' @@ -7513,6 +7531,7 @@ function init() { ,dk: 'Indlæser database ...' ,el: 'Φόρτωση Βάσης Δεδομένων' ,bg: 'Зареждане на базата с данни ...' + ,hr: 'Učitavanje podataka' ,ro: 'Încarc baza de date' ,sv: 'Laddar databas ...' ,it: 'Carica Database ...' @@ -7539,6 +7558,7 @@ function init() { ,es: 'Base de datos contiene %1 registros futuros' ,dk: 'Databasen indeholder %1 fremtidige indgange' ,bg: 'Базата с дани съдържа %1 бъдещи записи' + ,hr: 'Baza sadrži %1 zapisa u budućnosti' ,it: 'Contiene Database %1 record futuri' ,fi: 'Tietokanta sisältää %1 merkintää tulevaisuudessa' ,pl: 'Baza danych zawiera %1 przyszłych rekordów' @@ -7563,6 +7583,7 @@ function init() { ,ro: 'Șterg %1 înregistrări selectate?' ,sv: 'Ta bort %1 valda händelser' ,bg: 'Премахване на %1 от избраните записи?' + ,hr: 'Obriši %1 odabrani zapis?' ,it: 'Rimuovere %1 record selezionati?' ,fi: 'Poista %1 valittua merkintää?' ,pl: 'Usunąć %1 wybranych rekordów?' @@ -7587,6 +7608,7 @@ function init() { ,ro: 'Eroare la încărcarea bazei de date' ,sv: 'Fel vid laddning av databas' ,bg: 'Грешка при зареждане на базата с данни' + ,hr: 'Greška pri učitavanju podataka' ,it: 'Errore di caricamento del database' ,fi: 'Ongelma tietokannan lataamisessa' ,pl: 'Błąd wczytywania bazy danych' @@ -7611,6 +7633,7 @@ function init() { ,ro: 'Înregistrarea %1 a fost ștearsă...' ,sv: 'Händelse %1 borttagen ...' ,bg: '%1 записи премахнати' + ,hr: 'Zapis %1 obrisan...' ,it: 'Record %1 rimosso ...' ,fi: 'Merkintä %1 poistettu ...' ,pl: '%1 rekordów usunięto ...' @@ -7635,6 +7658,7 @@ function init() { ,ro: 'Eroare la ștergerea înregistrării %1' ,sv: 'Fel vid borttagning av %1' ,bg: 'Грешка при премахването на %1 от записите' + ,hr: 'Greška prilikom brisanja zapisa %1' ,it: 'Errore rimozione record %1' ,fi: 'Virhe poistaessa merkintää numero %1' ,pl: 'Błąd przy usuwaniu rekordu %1' @@ -7651,7 +7675,7 @@ function init() { cs: 'Odstraňování záznamů ...' ,he: 'מוחק רשומות ... ' ,nb: 'Fjerner elementer...' - ,fr: 'Effacement d\événements...' + ,fr: 'Effacement dévénements...' ,ro: 'Se șterg înregistrările...' ,el: 'Αφαίρεση Εγγραφών' ,de: 'Entferne Einträge ...' @@ -7659,6 +7683,7 @@ function init() { ,dk: 'Sletter indgange ...' ,sv: 'Tar bort händelser ...' ,bg: 'Изтриване на записите...' + ,hr: 'Brisanje zapisa' ,it: 'Elimino dei record ...' ,fi: 'Poistan merkintöjä' ,pl: 'Usuwanie rekordów ...' @@ -7672,28 +7697,7 @@ function init() { ,zh_tw: '正在刪除記錄...' } ,'%1 records deleted' : { - cs: '%1 records deleted' - ,he: '%1 records deleted' - ,nb: '%1 records deleted' - ,fr: '%1 records deleted' - ,ro: '%1 records deleted' - ,el: '%1 records deleted' - ,de: '%1 records deleted' - ,es: '%1 records deleted' - ,dk: '%1 records deleted' - ,sv: '%1 records deleted' - ,bg: '%1 records deleted' - ,it: '%1 records deleted' - ,fi: '%1 records deleted' - ,pl: '%1 records deleted' - ,pt: '%1 records deleted' - ,ru: '%1 records deleted' - ,sk: '%1 records deleted' - ,nl: '%1 records deleted' - ,ko: '%1 records deleted' - ,tr: '%1 records deleted' - ,zh_cn: '%1 records deleted' - ,zh_tw: '%1 records deleted' + hr: 'obrisano %1 zapisa' } ,'Clean Mongo status database' : { cs: 'Vyčištění Mongo databáze statusů' @@ -7707,6 +7711,7 @@ function init() { ,dk: 'Slet Mongo status database' ,sv: 'Rensa Mongo status databas' ,bg: 'Изчисти статуса на Монго базата с данни' + ,hr: 'Obriši bazu statusa' ,it: 'Pulisci database di Mongo' ,fi: 'Siivoa statustietokanta' ,pl: 'Oczyść status bazy danych Mongo' @@ -7730,6 +7735,7 @@ function init() { ,ro: 'Șterge toate documentele din colecția de status dispozitiv' ,sv: 'Ta bort alla dokument i devicestatus collektionen' ,bg: 'Изтрий всички документи от папката статус-устройство' + ,hr: 'Obriši sve zapise o statusima' ,it: 'Eliminare tutti i documenti dalla collezione "devicestatus"' ,fi: 'Poista kaikki tiedot statustietokannasta' ,pl: 'Usuń wszystkie dokumenty z kolekcji devicestatus' @@ -7752,6 +7758,7 @@ function init() { ,ro: 'Acest instrument șterge toate documentele din colecția devicestatus. Se folosește când încărcarea bateriei nu se afișează corect.' ,sv: 'Denna uppgift tar bort alla dokument från devicestatuskollektionen. Användbart när batteristatus ej uppdateras' ,bg: 'Тази опция премахва всички документи от папката статус-устройство. Полезно е, когато статусът на батерията не се обновява.' + ,hr: 'Ovo briše sve zapise o statusima. Korisno kada se status baterije uploadera ne osvježava ispravno.' ,it: 'Questa attività elimina tutti i documenti dalla collezione "devicestatus". Utile quando lo stato della batteria uploader/xdrip non si aggiorna.' ,fi: 'Tämä työkalu poistaa kaikki tiedot statustietokannasta, mikä korjaa tilanteen, jossa puhelimen akun lataustilanne ei näy oikein.' ,pl: 'To narzędzie usuwa wszystkie dokumenty z kolekcji devicestatus. Potrzebne jest wtedy, gdy status baterii uploadera nie jest aktualizowany' @@ -7775,6 +7782,7 @@ function init() { ,dk: 'Slet alle dokumenter' ,sv: 'Ta bort alla dokument' ,bg: 'Изтрий всички документи' + ,hr: 'Obriši sve zapise' ,it: 'Eliminare tutti i documenti' ,fi: 'Poista kaikki tiedot' ,pl: 'Usuń wszystkie dokumenty' @@ -7798,6 +7806,7 @@ function init() { ,ro: 'Șterg toate documentele din colecția devicestatus?' ,sv: 'Ta bort alla dokument från devicestatuscollektionen' ,bg: 'Изтриване на всички документи от папката статус-устройство?' + ,hr: 'Obriši sve zapise statusa?' ,it: 'Eliminare tutti i documenti dalla collezione devicestatus?' ,fi: 'Poista tiedot statustietokannasta?' ,pl: 'Czy na pewno usunąć wszystkie dokumenty z kolekcji devicestatus?' @@ -7821,6 +7830,7 @@ function init() { ,ro: 'Baza de date conține %1 înregistrări' ,sv: 'Databasen innehåller %1 händelser' ,bg: 'Базата с данни съдържа %1 записи' + ,hr: 'Baza sadrži %1 zapisa' ,it: 'Contiene Database %1 record' ,fi: 'Tietokanta sisältää %1 merkintää' ,pl: 'Baza danych zawiera %1 rekordów' @@ -7844,6 +7854,7 @@ function init() { ,ro: 'Toate înregistrările au fost șterse.' ,sv: 'Alla händelser raderade ...' ,bg: 'Всички записи премахнати ...' + ,hr: 'Svi zapisi obrisani' ,it: 'Tutti i record rimossi ...' ,fi: 'Kaikki merkinnät poistettu ...' ,pl: 'Wszystkie rekordy usunięto' @@ -7856,364 +7867,49 @@ function init() { ,zh_cn: '所有记录已经被清除' } ,'Delete all documents from devicestatus collection older than 30 days' : { - cs: 'Delete all documents from devicestatus collection older than 30 days' - ,he: 'Delete all documents from devicestatus collection older than 30 days' - ,nb: 'Delete all documents from devicestatus collection older than 30 days' - ,fr: 'Delete all documents from devicestatus collection older than 30 days' - ,ro: 'Delete all documents from devicestatus collection older than 30 days' - ,el: 'Delete all documents from devicestatus collection older than 30 days' - ,de: 'Delete all documents from devicestatus collection older than 30 days' - ,es: 'Delete all documents from devicestatus collection older than 30 days' - ,dk: 'Delete all documents from devicestatus collection older than 30 days' - ,sv: 'Delete all documents from devicestatus collection older than 30 days' - ,bg: 'Delete all documents from devicestatus collection older than 30 days' - ,it: 'Delete all documents from devicestatus collection older than 30 days' - ,fi: 'Delete all documents from devicestatus collection older than 30 days' - ,pl: 'Delete all documents from devicestatus collection older than 30 days' - ,pt: 'Delete all documents from devicestatus collection older than 30 days' - ,ru: 'Delete all documents from devicestatus collection older than 30 days' - ,sk: 'Delete all documents from devicestatus collection older than 30 days' - ,nl: 'Delete all documents from devicestatus collection older than 30 days' - ,ko: 'Delete all documents from devicestatus collection older than 30 days' - ,tr: 'Delete all documents from devicestatus collection older than 30 days' - ,zh_cn: 'Delete all documents from devicestatus collection older than 30 days' - ,zh_tw: 'Delete all documents from devicestatus collection older than 30 days' + hr: 'Obriši sve statuse starije od 30 dana' } ,'Number of Days to Keep:' : { - cs: 'Number of Days to Keep:' - ,he: 'Number of Days to Keep:' - ,nb: 'Number of Days to Keep:' - ,fr: 'Number of Days to Keep:' - ,ro: 'Number of Days to Keep:' - ,el: 'Number of Days to Keep:' - ,de: 'Number of Days to Keep:' - ,es: 'Number of Days to Keep:' - ,dk: 'Number of Days to Keep:' - ,sv: 'Number of Days to Keep:' - ,bg: 'Number of Days to Keep:' - ,it: 'Number of Days to Keep:' - ,fi: 'Number of Days to Keep:' - ,pl: 'Number of Days to Keep:' - ,pt: 'Number of Days to Keep:' - ,ru: 'Number of Days to Keep:' - ,sk: 'Number of Days to Keep:' - ,nl: 'Number of Days to Keep:' - ,ko: 'Number of Days to Keep:' - ,tr: 'Number of Days to Keep:' - ,zh_cn: 'Number of Days to Keep:' - ,zh_tw: 'Number of Days to Keep:' + hr: 'Broj dana za sačuvati:' } ,'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' : { - cs: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' - ,he: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' - ,nb: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' - ,fr: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' - ,ro: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' - ,el: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' - ,de: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' - ,es: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' - ,dk: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' - ,sv: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' - ,bg: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' - ,it: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' - ,fi: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' - ,pl: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' - ,pt: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' - ,ru: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' - ,sk: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' - ,nl: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' - ,ko: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' - ,tr: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' - ,zh_cn: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' - ,zh_tw: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' + hr: 'Ovo uklanja sve statuse starije od 30 dana. Korisno kada se status baterije uploadera ne osvježava ispravno.' } ,'Delete old documents from devicestatus collection?' : { - cs: 'Delete old documents from devicestatus collection?' - ,he: 'Delete old documents from devicestatus collection?' - ,nb: 'Delete old documents from devicestatus collection?' - ,fr: 'Delete old documents from devicestatus collection?' - ,ro: 'Delete old documents from devicestatus collection?' - ,el: 'Delete old documents from devicestatus collection?' - ,de: 'Delete old documents from devicestatus collection?' - ,es: 'Delete old documents from devicestatus collection?' - ,dk: 'Delete old documents from devicestatus collection?' - ,sv: 'Delete old documents from devicestatus collection?' - ,bg: 'Delete old documents from devicestatus collection?' - ,it: 'Delete old documents from devicestatus collection?' - ,fi: 'Delete old documents from devicestatus collection?' - ,pl: 'Delete old documents from devicestatus collection?' - ,pt: 'Delete old documents from devicestatus collection?' - ,ru: 'Delete old documents from devicestatus collection?' - ,sk: 'Delete old documents from devicestatus collection?' - ,nl: 'Delete old documents from devicestatus collection?' - ,ko: 'Delete old documents from devicestatus collection?' - ,tr: 'Delete old documents from devicestatus collection?' - ,zh_cn: 'Delete old documents from devicestatus collection?' - ,zh_tw: 'Delete old documents from devicestatus collection?' + hr: 'Obriši stare statuse' } ,'Clean Mongo entries (glucose entries) database' : { - cs: 'Clean Mongo entries (glucose entries) database' - ,he: 'Clean Mongo entries (glucose entries) database' - ,nb: 'Clean Mongo entries (glucose entries) database' - ,fr: 'Clean Mongo entries (glucose entries) database' - ,ro: 'Clean Mongo entries (glucose entries) database' - ,el: 'Clean Mongo entries (glucose entries) database' - ,de: 'Clean Mongo entries (glucose entries) database' - ,es: 'Clean Mongo entries (glucose entries) database' - ,dk: 'Clean Mongo entries (glucose entries) database' - ,sv: 'Clean Mongo entries (glucose entries) database' - ,bg: 'Clean Mongo entries (glucose entries) database' - ,it: 'Clean Mongo entries (glucose entries) database' - ,fi: 'Clean Mongo entries (glucose entries) database' - ,pl: 'Clean Mongo entries (glucose entries) database' - ,pt: 'Clean Mongo entries (glucose entries) database' - ,ru: 'Clean Mongo entries (glucose entries) database' - ,sk: 'Clean Mongo entries (glucose entries) database' - ,nl: 'Clean Mongo entries (glucose entries) database' - ,ko: 'Clean Mongo entries (glucose entries) database' - ,tr: 'Clean Mongo entries (glucose entries) database' - ,zh_cn: 'Clean Mongo entries (glucose entries) database' - ,zh_tw: 'Clean Mongo entries (glucose entries) database' + hr: 'Obriši GUK zapise iz baze' } ,'Delete all documents from entries collection older than 180 days' : { - cs: 'Delete all documents from entries collection older than 180 days' - ,he: 'Delete all documents from entries collection older than 180 days' - ,nb: 'Delete all documents from entries collection older than 180 days' - ,fr: 'Delete all documents from entries collection older than 180 days' - ,ro: 'Delete all documents from entries collection older than 180 days' - ,el: 'Delete all documents from entries collection older than 180 days' - ,de: 'Delete all documents from entries collection older than 180 days' - ,es: 'Delete all documents from entries collection older than 180 days' - ,dk: 'Delete all documents from entries collection older than 180 days' - ,sv: 'Delete all documents from entries collection older than 180 days' - ,bg: 'Delete all documents from entries collection older than 180 days' - ,it: 'Delete all documents from entries collection older than 180 days' - ,fi: 'Delete all documents from entries collection older than 180 days' - ,pl: 'Delete all documents from entries collection older than 180 days' - ,pt: 'Delete all documents from entries collection older than 180 days' - ,ru: 'Delete all documents from entries collection older than 180 days' - ,sk: 'Delete all documents from entries collection older than 180 days' - ,nl: 'Delete all documents from entries collection older than 180 days' - ,ko: 'Delete all documents from entries collection older than 180 days' - ,tr: 'Delete all documents from entries collection older than 180 days' - ,zh_cn: 'Delete all documents from entries collection older than 180 days' - ,zh_tw: 'Delete all documents from entries collection older than 180 days' + hr: 'Obriši sve zapise starije od 180 dana' } ,'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.' : { - cs: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,he: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,nb: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,fr: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,ro: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,el: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,de: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,es: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,dk: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,sv: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,bg: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,it: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,fi: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,pl: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,pt: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,ru: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,sk: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,nl: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,ko: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,tr: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,zh_cn: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,zh_tw: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.' + hr: 'Ovo briše sve zapise starije od 180 dana. Korisno kada se status baterije uploadera ne osvježava.' } ,'Delete old documents' : { - cs: 'Delete old documents' - ,he: 'Delete old documents' - ,nb: 'Delete old documents' - ,fr: 'Delete old documents' - ,ro: 'Delete old documents' - ,el: 'Delete old documents' - ,de: 'Delete old documents' - ,es: 'Delete old documents' - ,dk: 'Delete old documents' - ,sv: 'Delete old documents' - ,bg: 'Delete old documents' - ,it: 'Delete old documents' - ,fi: 'Delete old documents' - ,pl: 'Delete old documents' - ,pt: 'Delete old documents' - ,ru: 'Delete old documents' - ,sk: 'Delete old documents' - ,nl: 'Delete old documents' - ,ko: 'Delete old documents' - ,tr: 'Delete old documents' - ,zh_cn: 'Delete old documents' - ,zh_tw: 'Delete old documents' + hr: 'Obriši stare zapise' } ,'Delete old documents from entries collection?' : { - cs: 'Delete old documents from entries collection?' - ,he: 'Delete old documents from entries collection?' - ,nb: 'Delete old documents from entries collection?' - ,fr: 'Delete old documents from entries collection?' - ,ro: 'Delete old documents from entries collection?' - ,el: 'Delete old documents from entries collection?' - ,de: 'Delete old documents from entries collection?' - ,es: 'Delete old documents from entries collection?' - ,dk: 'Delete old documents from entries collection?' - ,sv: 'Delete old documents from entries collection?' - ,bg: 'Delete old documents from entries collection?' - ,it: 'Delete old documents from entries collection?' - ,fi: 'Delete old documents from entries collection?' - ,pl: 'Delete old documents from entries collection?' - ,pt: 'Delete old documents from entries collection?' - ,ru: 'Delete old documents from entries collection?' - ,sk: 'Delete old documents from entries collection?' - ,nl: 'Delete old documents from entries collection?' - ,ko: 'Delete old documents from entries collection?' - ,tr: 'Delete old documents from entries collection?' - ,zh_cn: 'Delete old documents from entries collection?' - ,zh_tw: 'Delete old documents from entries collection?' + hr: 'Obriši stare zapise?' } ,'%1 is not a valid number' : { - cs: '%1 is not a valid number' - ,he: '%1 is not a valid number' - ,nb: '%1 is not a valid number' - ,fr: '%1 is not a valid number' - ,ro: '%1 is not a valid number' - ,el: '%1 is not a valid number' - ,de: '%1 is not a valid number' - ,es: '%1 is not a valid number' - ,dk: '%1 is not a valid number' - ,sv: '%1 is not a valid number' - ,bg: '%1 is not a valid number' - ,it: '%1 is not a valid number' - ,fi: '%1 is not a valid number' - ,pl: '%1 is not a valid number' - ,pt: '%1 is not a valid number' - ,ru: '%1 is not a valid number' - ,sk: '%1 is not a valid number' - ,nl: '%1 is not a valid number' - ,ko: '%1 is not a valid number' - ,tr: '%1 is not a valid number' - ,zh_cn: '%1 is not a valid number' - ,zh_tw: '%1 is not a valid number' + hr: '%1 nije valjan broj' } ,'%1 is not a valid number - must be more than 2' : { - cs: '%1 is not a valid number - must be more than 2' - ,he: '%1 is not a valid number - must be more than 2' - ,nb: '%1 is not a valid number - must be more than 2' - ,fr: '%1 is not a valid number - must be more than 2' - ,ro: '%1 is not a valid number - must be more than 2' - ,el: '%1 is not a valid number - must be more than 2' - ,de: '%1 is not a valid number - must be more than 2' - ,es: '%1 is not a valid number - must be more than 2' - ,dk: '%1 is not a valid number - must be more than 2' - ,sv: '%1 is not a valid number - must be more than 2' - ,bg: '%1 is not a valid number - must be more than 2' - ,it: '%1 is not a valid number - must be more than 2' - ,fi: '%1 is not a valid number - must be more than 2' - ,pl: '%1 is not a valid number - must be more than 2' - ,pt: '%1 is not a valid number - must be more than 2' - ,ru: '%1 is not a valid number - must be more than 2' - ,sk: '%1 is not a valid number - must be more than 2' - ,nl: '%1 is not a valid number - must be more than 2' - ,ko: '%1 is not a valid number - must be more than 2' - ,tr: '%1 is not a valid number - must be more than 2' - ,zh_cn: '%1 is not a valid number - must be more than 2' - ,zh_tw: '%1 is not a valid number - must be more than 2' + hr: '%1 nije valjan broj - mora biti veći od 2' } ,'Clean Mongo treatments database' : { - cs: 'Clean Mongo treatments database' - ,he: 'Clean Mongo treatments database' - ,nb: 'Clean Mongo treatments database' - ,fr: 'Clean Mongo treatments database' - ,ro: 'Clean Mongo treatments database' - ,el: 'Clean Mongo treatments database' - ,de: 'Clean Mongo treatments database' - ,es: 'Clean Mongo treatments database' - ,dk: 'Clean Mongo treatments database' - ,sv: 'Clean Mongo treatments database' - ,bg: 'Clean Mongo treatments database' - ,it: 'Clean Mongo treatments database' - ,fi: 'Clean Mongo treatments database' - ,pl: 'Clean Mongo treatments database' - ,pt: 'Clean Mongo treatments database' - ,ru: 'Clean Mongo treatments database' - ,sk: 'Clean Mongo treatments database' - ,nl: 'Clean Mongo treatments database' - ,ko: 'Clean Mongo treatments database' - ,tr: 'Clean Mongo treatments database' - ,zh_cn: 'Clean Mongo treatments database' - ,zh_tw: 'Clean Mongo treatments database' + hr: 'Obriši tretmane iz baze' } ,'Delete all documents from treatments collection older than 180 days' : { - cs: 'Delete all documents from treatments collection older than 180 days' - ,he: 'Delete all documents from treatments collection older than 180 days' - ,nb: 'Delete all documents from treatments collection older than 180 days' - ,fr: 'Delete all documents from treatments collection older than 180 days' - ,ro: 'Delete all documents from treatments collection older than 180 days' - ,el: 'Delete all documents from treatments collection older than 180 days' - ,de: 'Delete all documents from treatments collection older than 180 days' - ,es: 'Delete all documents from treatments collection older than 180 days' - ,dk: 'Delete all documents from treatments collection older than 180 days' - ,sv: 'Delete all documents from treatments collection older than 180 days' - ,bg: 'Delete all documents from treatments collection older than 180 days' - ,it: 'Delete all documents from treatments collection older than 180 days' - ,fi: 'Delete all documents from treatments collection older than 180 days' - ,pl: 'Delete all documents from treatments collection older than 180 days' - ,pt: 'Delete all documents from treatments collection older than 180 days' - ,ru: 'Delete all documents from treatments collection older than 180 days' - ,sk: 'Delete all documents from treatments collection older than 180 days' - ,nl: 'Delete all documents from treatments collection older than 180 days' - ,ko: 'Delete all documents from treatments collection older than 180 days' - ,tr: 'Delete all documents from treatments collection older than 180 days' - ,zh_cn: 'Delete all documents from treatments collection older than 180 days' - ,zh_tw: 'Delete all documents from treatments collection older than 180 days' + hr: 'Obriši tretmane starije od 180 dana iz baze' } ,'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.' : { - cs: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,he: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,nb: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,fr: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,ro: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,el: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,de: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,es: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,dk: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,sv: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,bg: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,it: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,fi: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,pl: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,pt: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,ru: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,sk: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,nl: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,ko: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,tr: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,zh_cn: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.' - ,zh_tw: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.' + hr: 'Ovo briše sve tretmane starije od 180 dana iz baze. Korisno kada se status baterije uploadera ne osvježava.' } ,'Delete old documents from treatments collection?' : { - cs: 'Delete old documents from treatments collection?' - ,he: 'Delete old documents from treatments collection?' - ,nb: 'Delete old documents from treatments collection?' - ,fr: 'Delete old documents from treatments collection?' - ,ro: 'Delete old documents from treatments collection?' - ,el: 'Delete old documents from treatments collection?' - ,de: 'Delete old documents from treatments collection?' - ,es: 'Delete old documents from treatments collection?' - ,dk: 'Delete old documents from treatments collection?' - ,sv: 'Delete old documents from treatments collection?' - ,bg: 'Delete old documents from treatments collection?' - ,it: 'Delete old documents from treatments collection?' - ,fi: 'Delete old documents from treatments collection?' - ,pl: 'Delete old documents from treatments collection?' - ,pt: 'Delete old documents from treatments collection?' - ,ru: 'Delete old documents from treatments collection?' - ,sk: 'Delete old documents from treatments collection?' - ,nl: 'Delete old documents from treatments collection?' - ,ko: 'Delete old documents from treatments collection?' - ,tr: 'Delete old documents from treatments collection?' - ,zh_cn: 'Delete old documents from treatments collection?' - ,zh_tw: 'Delete old documents from treatments collection?' + hr: 'Obriši stare tretmane?' } ,'Admin Tools' : { cs: 'Nástroje pro správu' @@ -8228,6 +7924,7 @@ function init() { ,sv: 'Adminverktyg' ,dk: 'Administrations værktøj' ,bg: 'Настройки на администратора' + ,hr: 'Administracija' ,it: 'NS - Dati Mongo' ,fi: 'Ylläpitotyökalut' ,pl: 'Narzędzia administratora' @@ -8252,6 +7949,7 @@ function init() { ,dk: 'Nightscout - rapporter' ,sv: 'Nightscout - Statistik' ,bg: 'Найтскаут статистика' + ,hr: 'Nightscout izvješća' ,it: 'Nightscout - Statistiche' ,fi: 'Nightscout raportointi' ,pl: 'Nightscout - raporty' @@ -8259,7 +7957,7 @@ function init() { ,ru: 'Статистика Nightscout' ,sk: 'Nightscout výkazy' ,nl: 'Nightscout rapportages' - ,ko: 'Nightscout 보고하기' + ,ko: 'Nightscout 보고서' ,tr: 'NightScout raporları' ,zh_cn: 'Nightscout报表生成器' } @@ -8275,6 +7973,7 @@ function init() { ,ro: 'Renunță' ,sv: 'Avbryt' ,bg: 'Откажи' + ,hr: 'Odustani' ,it: 'Cancellare' ,ja: '中止' ,fi: 'Peruuta' @@ -8299,6 +7998,7 @@ function init() { ,el: 'Επεξεργασία Εγγραφής' ,sv: 'Redigera behandling' ,bg: 'Редакция на събитие' + ,hr: 'Uredi tretman' ,it: 'Modifica Somministrazione' ,fi: 'Muuta merkintää' ,pl: 'Edytuj zabieg' @@ -8321,6 +8021,7 @@ function init() { ,el: 'Διάρκεια' ,sv: 'Varaktighet' ,bg: 'Времетраене' + ,hr: 'Trajanje' ,it: 'Tempo' ,nb: 'Varighet' ,fi: 'Kesto' @@ -8344,6 +8045,7 @@ function init() { ,el: 'Διάρκεια σε λεπτά' ,sv: 'Varaktighet i minuter' ,bg: 'Времетраене в мин.' + ,hr: 'Trajanje u minutama' ,it: 'Tempo in minuti' ,nb: 'Varighet i minutter' ,fi: 'Kesto minuuteissa' @@ -8366,6 +8068,7 @@ function init() { ,ro: 'Bazală temporară' ,sv: 'Temporär basal' ,bg: 'Временен базал' + ,hr: 'Privremeni bazal' ,it: 'Basale Temp' ,nb: 'Midlertidig basal' ,fi: 'Tilapäinen basaali' @@ -8388,6 +8091,7 @@ function init() { ,fr: 'Début du débit basal temporaire' ,dk: 'Midlertidig basal start' ,bg: 'Начало на временен базал' + ,hr: 'Početak privremenog bazala' ,it: 'Inizio Basale Temp' ,nb: 'Midlertidig basal start' ,fi: 'Tilapäinen basaali alku' @@ -8407,6 +8111,7 @@ function init() { ,fr: 'Fin du débit basal temporaire' ,sv: 'Temporär basalavslut' ,bg: 'Край на временен базал' + ,hr: 'Kraj privremenog bazala' ,it: 'Fine Basale Temp' ,de: 'Ende Temporäre Basalrate' ,es: 'Fin Tasa Basal temporal' @@ -8433,6 +8138,7 @@ function init() { ,el: 'Επι τοις εκατό' ,sv: 'Procent' ,bg: 'Процент' + ,hr: 'Postotak' ,it: 'Percentuale' ,nb: 'Prosent' ,fi: 'Prosentti' @@ -8452,6 +8158,7 @@ function init() { ,fr: 'Changement du débit basal en %' ,sv: 'Basaländring i %' ,bg: 'Промяна на базала с %' + ,hr: 'Promjena bazala u %' ,de: 'Basalratenänderung in %' ,es: 'Basal modificado en %' ,dk: 'Basal ændring i %' @@ -8477,6 +8184,7 @@ function init() { ,es: 'Valor basal' ,dk: 'Basalværdi' ,bg: 'Временен базал' + ,hr: 'Vrijednost bazala' ,it: 'Valore Basale' ,nb: 'Basalverdi' ,fi: 'Basaalin määrä' @@ -8493,6 +8201,7 @@ function init() { cs: 'Hodnota bazálu' ,he: 'ערך בזלי מוחלט ' ,bg: 'Базална стойност' + ,hr: 'Apsolutna vrijednost bazala' ,it: 'Valore Basale Assoluto' ,fr: 'Débit basal absolu' ,de: 'Absoluter Basalratenwert' @@ -8514,6 +8223,7 @@ function init() { ,'Announcement' : { cs: 'Oznámení' ,bg: 'Известяване' + ,hr: 'Objava' ,de: 'Ankündigung' ,es: 'Aviso' ,fr: 'Annonce' @@ -8547,6 +8257,7 @@ function init() { ,nb: 'Laster verdier for midlertidig basal' ,fi: 'Lataan tilapäisten basaalien tietoja' ,bg: 'Зареждане на данни за временния базал' + ,hr: 'Učitavanje podataka o privremenom bazalu' ,pl: 'Wczytuje dane tymczasowej dawki podstawowej' ,pt: 'Carregando os dados de basal temporária' ,ru: 'Загрузка данных временного базала' @@ -8569,6 +8280,7 @@ function init() { ,dk: 'Gem aktuelle hændelse før der skiftes til ny?' ,fi: 'Tallenna nykyinen merkintä ennen vaihtoa uuteen?' ,bg: 'Запази текущият запис преди да промениш новия ' + ,hr: 'Spremi trenutni zapis prije promjene na idući?' ,pl: 'Zapisać bieżący rekord przed zamianą na nowy?' ,pt: 'Salvar o registro atual antes de mudar para um novo?' ,ru: 'Сохранить текущие данные перед переходом к новым?' @@ -8592,6 +8304,7 @@ function init() { ,nb: 'Bytt profil' ,fi: 'Vaihda profiilia' ,bg: 'Смяна на профил' + ,hr: 'Promjena profila' ,pl: 'Przełączenie profilu' ,pt: 'Troca de perfil' ,ru: 'Изменить профиль' @@ -8616,6 +8329,7 @@ function init() { ,nb: 'Profil' ,fi: 'Profiili' ,bg: 'Профил' + ,hr: 'Profil' ,pl: 'Profil' ,pt: 'Perfil' ,ru: 'Профиль' @@ -8638,6 +8352,7 @@ function init() { ,nb: 'Profilinstillinger' ,fi: 'Yleiset profiiliasetukset' ,bg: 'Основни настройки на профила' + ,hr: 'Opće postavke profila' ,pl: 'Ogólne ustawienia profilu' ,pt: 'Configurações de perfil gerais' ,ru: 'Общие настройки профиля' @@ -8661,6 +8376,7 @@ function init() { ,nb: 'Tittel' ,fi: 'Otsikko' ,bg: 'Заглавие' + ,hr: 'Naslov' ,pl: 'Nazwa' ,pt: 'Título' ,ru: 'Наименование' @@ -8684,6 +8400,7 @@ function init() { ,dk: 'Database hændelser' ,fi: 'Tietokantamerkintöjä' ,bg: 'Записи в базата с данни' + ,hr: 'Zapisi u bazi' ,pl: 'Rekordy bazy danych' ,pt: 'Registros do banco de dados' ,ru: 'Записи в базе данных' @@ -8707,6 +8424,7 @@ function init() { ,dk: 'Tilføj ny hændelse' ,fi: 'Lisää uusi merkintä' ,bg: 'Добави нов запис' + ,hr: 'Dodaj zapis' ,pl: 'Dodaj nowy rekord' ,pt: 'Adicionar novo registro' ,ru: 'Добавить новую запись' @@ -8731,6 +8449,7 @@ function init() { ,fk: 'Fjern denne indgang' ,fi: 'Poista tämä merkintä' ,bg: 'Премахни този запис' + ,hr: 'Obriši ovaj zapis' ,pl: 'Usuń ten rekord' ,pt: 'Remover este registro' ,ru: 'Удалить эту запись' @@ -8755,6 +8474,7 @@ function init() { ,dk: 'Kopier denne hændelse til ny' ,fi: 'Kopioi tämä merkintä uudeksi' ,bg: 'Копирай този запис като нов' + ,hr: 'Kloniraj zapis' ,pl: 'Powiel ten rekord na nowy' ,pt: 'Duplicar este registro como novo' ,ru: 'Клонировать эту запись в новый' @@ -8778,14 +8498,15 @@ function init() { ,nb: 'Rad gyldig fra' ,fi: 'Merkintä voimassa alkaen' ,bg: 'Записът е валиден от ' + ,hr: 'Zapis vrijedi od' ,pl: 'Rekord ważny od' ,pt: 'Registro válido desde' ,ru: 'Запись действительна от' ,sk: 'Záznam platný od' ,nl: 'Geldig van' - ,ko: '유효 기록' + ,ko: '기록을 시작한 날짜' ,it: 'Record valido da' - ,tr: 'Buradan geçerli giriş' + ,tr: 'Kayıt itibaren geçerli' ,zh_cn: '有效记录,从' } ,'Stored profiles' : { @@ -8801,6 +8522,7 @@ function init() { ,nb: 'Lagrede profiler' ,fi: 'Tallennetut profiilit' ,bg: 'Запаметени профили' + ,hr: 'Pohranjeni profili' ,pl: 'Zachowane profile' ,pt: 'Perfis guardados' ,ru: 'Запомненные профили' @@ -8824,6 +8546,7 @@ function init() { ,nb: 'Tidssone' ,fi: 'Aikavyöhyke' ,bg: 'Часова зона' + ,hr: 'Vremenska zona' ,pl: 'Strefa czasowa' ,pt: 'Fuso horário' ,ru: 'Часовой пояс' @@ -8847,6 +8570,7 @@ function init() { ,dk: 'Varighed af insulin aktivitet (DIA)' ,fi: 'Insuliinin vaikutusaika (DIA)' ,bg: 'Продължителност на инсулиновата активност DIA' + ,hr: 'Trajanje aktivnosti inzulina (DIA)' ,pl: 'Czas trwania aktywnej insuliny (DIA)' ,pt: 'Duração da Atividade da Insulina (DIA)' ,ru: 'Время действия инсулина (DIA)' @@ -8870,6 +8594,7 @@ function init() { ,nb: 'Representerer typisk insulinvarighet. Varierer per pasient og per insulin type. Vanligvis 3-4 timer for de fleste typer insulin og de fleste pasientene. Noen ganger også kalt insulinlevetid.' ,fi: 'Kertoo insuliinin tyypillisen vaikutusajan. Vaihtelee potilaan ja insuliinin tyypin mukaan. Tyypillisesti 3-4 tuntia pumpuissa käytettävällä insuliinilla.' ,bg: 'Представя типичната продължителност на действието на инсулина. Варира между отделните пациенти и различни инсулини. Обикновено е 3-4 часа за пациентите с помпа. Нарича се още живот на инсулина ' + ,hr: 'Predstavlja uobičajeno trajanje djelovanje inzulina. Varira po vrstama inzulina i osobama. Tipično je to 3-4 sata za inzuline u pumpama za većinu osoba. Ponekad se naziva i vijek inzulina' ,pl: 'Odzwierciedla czas działania insuliny. Może różnić się w zależności od chorego i rodzaju insuliny. Zwykle są to 3-4 godziny dla insuliny podawanej pompą u większości chorych. Inna nazwa to czas trwania insuliny.' ,pt: 'Representa a tempo típico durante o qual a insulina tem efeito. Varia de acordo com o paciente e tipo de insulina. Tipicamente 3-4 horas para a maioria das insulinas usadas em bombas e dos pacientes. Algumas vezes chamada de tempo de vida da insulina' ,ru: 'Представляет типичную продолжительность действия инсулина. Зависит от пациента и от типа инсулина. Обычно 3-4 часа для большинства помповых инсулинов и большинства пациентов' @@ -8893,12 +8618,13 @@ function init() { ,dk: 'Insulin til kulhydrat forhold også kaldet Kulhydrat-insulinratio (I:C)' ,fi: 'Insuliiniannoksen hiilihydraattisuhde (I:HH)' ,bg: 'Съотношение инсулин/въглехидратите ICR I:C И:ВХ' + ,hr: 'Omjer UGH:Inzulin (I:C)' ,pl: 'Współczynnik insulina/węglowodany (I:C)' ,pt: 'Relação Insulina-Carboidrato (I:C)' ,ru: 'Соотношение инсулин/углеводы I:C' ,sk: 'Inzulín-sacharidový pomer (I:C)' ,nl: 'Insuline - Koolhydraat ratio (I:C)' - ,ko: '탄수화물에 대한 인슐린 비율(I:C)' + ,ko: '인슐린에 대한 탄수화물 비율(I:C)' ,it: 'Rapporto Insulina-Carboidrati (I:C)' ,tr: 'İnsülin/Karbonhidrat oranı (I:C)' ,zh_cn: '碳水化合物系数(ICR)' @@ -8916,6 +8642,7 @@ function init() { ,nb: 'timer' ,fi: 'tuntia' ,bg: 'часове' + ,hr: 'sati' ,pl: 'godziny' ,pt: 'horas' ,ru: 'час' @@ -8938,6 +8665,7 @@ function init() { ,dk: 'g/time' ,fi: 'g/tunti' ,bg: 'гр/час' + ,hr: 'g/h' ,pl: 'g/godzine' ,pt: 'g/hora' ,ru: 'г/час' @@ -8961,6 +8689,7 @@ function init() { ,nb: 'g karbohydrater per enhet insulin. Beskriver hvor mange gram karbohydrater som hånderes av en enhet insulin.' ,fi: 'g hiilihydraattia / yksikkö insuliinia. Suhde, joka kertoo montako grammaa hiilihydraattia vastaa yhtä yksikköä insuliinia.' ,bg: 'грам въглехидрат към 1 единица инсулин. Съотношението колко грама въглехидрат се покриват от 1 единица инсулин.' + ,hr: 'grama UGH po jedinici inzulina. Omjer koliko grama UGH pokriva jedna jedinica inzulina.' ,pl: 'g węglowodanów na 1j insuliny. Współczynnik ilości gram weglowodanów równoważonych przez 1j insuliny.' ,pt: 'g de carboidrato por unidade de insulina. A razão de quantos gramas de carboidrato são processados por cada unidade de insulina.' ,ru: 'г углеводов на ед инсулина. Соотношение показывает количество гр углеводов компенсируемого единицей инсулина.' @@ -8984,6 +8713,7 @@ function init() { ,nb: 'Insulinfølsomhetsfaktor' ,fi: 'Insuliiniherkkyys (ISF)' ,bg: 'Фактор на инсулинова чувствителност ISF ' + ,hr: 'Faktor inzulinske osjetljivosti (ISF)' ,pl: 'Współczynnik wrażliwosci na insulinę (ISF)' ,pt: 'Fator de Sensibilidade da Insulina (ISF)' ,ru: 'Фактор чувствительности к инсулину ISF' @@ -9007,6 +8737,7 @@ function init() { ,nb: 'mg/dl eller mmol/l per enhet insulin. Beskriver hvor mye blodsukkeret senkes per enhet insulin.' ,fi: 'mg/dL tai mmol/L / 1 yksikkö insuliinia. Suhde, joka kertoo montako yksikköä verensokeria yksi yksikkö insuliinia laskee.' ,bg: 'мг/дл или ммол към 1 единица инсулин. Съотношението как се променя кръвната захар със всяка единица инсулинова корекция' + ,hr: 'md/dL ili mmol/L po jedinici inzulina. Omjer koliko se GUK mijenja sa jednom jedinicom korekcije inzulina.' ,pl: 'mg/dl lub mmol/L na 1j insuliny. Współczynnik obniżenia poziomu glukozy przez 1j insuliny' ,pt: 'mg/dL ou mmol/L por unidade de insulina. A razão entre queda glicêmica e cada unidade de insulina de correção administrada.' ,ru: 'мг/дл или ммол/л на единицу инсулина. Насколько меняется СК с каждой единицей коррегирующего инсулина' @@ -9030,6 +8761,7 @@ function init() { ,nb: 'Karbohydrattid' ,fi: 'Hiilihydraattiaktiivisuus / imeytymisnopeus' ,bg: 'Активност на въглехидратите / време за абсорбиране' + ,hr: 'UGH aktivnost / omjer apsorpcije' ,pl: 'Aktywność węglowodanów / współczynnik absorpcji' ,pt: 'Atividade dos carboidratos / taxa de absorção' ,ru: 'Активность углеводов / скорость усвоения' @@ -9053,6 +8785,7 @@ function init() { ,nb: 'gram per tidsenhet. Representerer både endringen i COB per tidsenhet, såvel som mengden av karbohydrater som blir tatt opp i løpet av den tiden. Carb absorpsjon / virkningskurver er mindre forstått enn insulinaktivitet, men kan tilnærmes ved hjelp av en forsinkelse fulgt av en konstant hastighet av absorpsjon ( g / time ) .' ,fi: 'grammaa / aika. Kertoo tyypillisen nopeuden, jolla hiilihydraatit imeytyvät syömisen jälkeen. Imeytyminen tunnetaan jokseenkin huonosti, mutta voidaan arvioida keskimääräisesti. Yksikkönä grammaa tunnissa (g/h).' ,bg: 'грам за единица време. Представлява както промяната в COB за единица време, така и количеството ВХ които биха се усвоили за това време.' + ,hr: 'grama po jedinici vremena. Predstavlja promjenu aktivnih UGH u jedinici vremena, kao i količinu UGH koja bi trebala utjecati kroz to vrijeme.' ,pl: 'g na jednostkę czasu. Odzwierciedla zmianę COB na jednostkę czasu oraz ilość węglowodanów mających przynieść efekt w czasie. Krzywe absorpcji / aktywnosci węglowodanów są mniej poznane niż aktywności insuliny ale mogą być oszacowane przez ocenę opóźnienia wchłaniania przy stałym współczynniku absorpcji (g/h).' ,pt: 'Gramas por unidade de tempo. Representa a mudança em COB por unidade de tempo, bem como a quantidade de carboidratos que deve ter efeito durante esse período de tempo. Absorção de carboidrato / curvas de atividade são menos conhecidas que atividade de insulina, mas podem ser aproximadas usando um atraso inicial seguido de uma taxa de absorção constante (g/h). ' ,ru: 'грамм на ед времени. Представляет изменение кол-ва углеводов в организме (COB)за единицу времени a также количество активных углеводов' @@ -9076,6 +8809,7 @@ function init() { ,nb: 'Basal [enhet/t]' ,fi: 'Basaali [yksikköä/tunti]' ,bg: 'Базална стойност [единица/час]' + ,hr: 'Bazali [jedinica/sat]' ,pl: 'Dawka podstawowa [j/h]' ,pt: 'Taxas de basal [unidades/hora]' ,ru: 'Базал ед/час' @@ -9099,6 +8833,7 @@ function init() { ,nb: 'Ønsket blodsukkerintervall [mg/dl,mmmol/l]' ,fi: 'Tavoitealue [mg/dL tai mmol/L]' ,bg: 'Целеви диапазон на КЗ [мг/дл , ммол]' + ,hr: 'Ciljani raspon GUK [mg/dL,mmol/L]' ,pl: 'Docelowy przedział glikemii [mg/dl, mmol/L])' ,pt: 'Meta de glicemia [mg/dL, mmol/L]' ,ru: 'Целевой диапазон СК [mg/dL,mmol/L]' @@ -9122,6 +8857,7 @@ function init() { ,nb: 'Starttidspunkt for gyldighet' ,fi: 'Merkinnän alkupäivämäärä' ,bg: 'Начало на записа' + ,hr: 'Trenutak važenja zapisa' ,pl: 'Początek ważnych rekordów' ,pt: 'Início da validade dos dados' ,ru: 'Начало валидности записей' @@ -9145,6 +8881,7 @@ function init() { ,nb: 'Isfjell' ,fi: 'Jääpuikko' ,bg: 'Висящ' + ,hr: 'Padajuće' ,pl: 'Odwrotność' ,pt: 'Inverso' ,nl: 'Ijspegel' @@ -9169,6 +8906,7 @@ function init() { ,nb: 'Basalgraf' ,fi: 'Näytä basaali' ,bg: 'Базал' + ,hr: 'Iscrtaj bazale' ,pl: 'Zmiana dawki bazowej' ,pt: 'Renderizar basal' ,ru: 'показывать базал' @@ -9192,6 +8930,7 @@ function init() { ,nb: 'Brukt profil' ,fi: 'Käytetty profiili' ,bg: 'Използван профил' + ,hr: 'Korišteni profil' ,pl: 'Profil wykorzystywany' ,pt: 'Perfil utilizado' ,ru: 'Используемый профиль' @@ -9215,6 +8954,7 @@ function init() { ,nb: 'Innenfor målområde' ,fi: 'Laskettu arvo on tavoitealueella' ,bg: 'Калкулацията е в граници' + ,hr: 'Izračun je u ciljanom rasponu.' ,pl: 'Obliczenie mieści się w zakresie docelowym' ,pt: 'O cálculo está dentro da meta' ,ru: 'Расчет в целевых пределах ' @@ -9238,6 +8978,7 @@ function init() { ,sv: 'Laddar profildata ...' ,fi: 'Ladataan profiileja ...' ,bg: 'Зареждане на профили' + ,hr: 'Učitavanje profila...' ,pl: 'Wczytywanie rekordów profilu' ,pt: 'Carregando dados do perfil ...' ,ru: 'Загрузка записей профиля' @@ -9261,6 +9002,7 @@ function init() { ,sv: 'Värden laddas' ,fi: 'Arvot ladattu' ,bg: 'Стойностите за заредени.' + ,hr: 'Vrijednosti učitane.' ,pl: 'Wartości wczytane.' ,pt: 'Valores carregados.' ,ru: 'Данные загружены' @@ -9284,6 +9026,7 @@ function init() { ,sv: 'Standardvärden valda' ,fi: 'Oletusarvot ladattu' ,bg: 'Стойностите по подразбиране са използвани.' + ,hr: 'Koriste se zadane vrijednosti.' ,pl: 'Używane domyślne wartości.' ,pt: 'Valores padrão em uso.' ,ru: 'Используются значения по умолчанию' @@ -9307,6 +9050,7 @@ function init() { ,sv: 'Error. Standardvärden valda.' ,fi: 'Virhe! Käytetään oletusarvoja.' ,bg: 'Грешка. Стойностите по подразбиране са използвани.' + ,hr: 'Pogreška. Koristiti će se zadane vrijednosti.' ,pl: 'Błąd. Używane domyślne wartości.' ,pt: 'Erro. Valores padrão em uso.' ,ru: 'Ошибка. Используются значения по умолчанию' @@ -9330,6 +9074,7 @@ function init() { ,sv: 'Tidsintervall för målområde låg och hög stämmer ej' ,fi: 'Matalan ja korkean tavoitteen aikarajat eivät täsmää. Arvot on vaihdettu oletuksiin.' ,bg: 'Времевите интервали за долна граница на кз и горна граница на кз не съвпадат. Стойностите са възстановени по подразбиране.' + ,hr: 'Vremenski rasponi donje ciljane i gornje ciljane vrijednosti nisu ispravni. Vrijednosti vraćene na zadano.' ,pl: 'Zakres czasu w docelowo niskim i wysokim przedziale nie są dopasowane. Przywrócono wartości domyślne' ,pt: 'Os intervalos de tempo da meta inferior e da meta superior não conferem. Os valores padrão serão restaurados.' ,ru: 'Диапазон времени нижних и верхних целевых значений не совпадают. Восстановлены значения по умолчанию' @@ -9353,6 +9098,7 @@ function init() { ,sv: 'Giltig från:' ,fi: 'Alkaen:' ,bg: 'Валиден от' + ,hr: 'Vrijedi od:' ,pl: 'Ważne od:' ,pt: 'Válido desde:' ,ru: 'Действует с' @@ -9360,7 +9106,7 @@ function init() { ,nl: 'Geldig van:' ,ko: '유효' ,it: 'Valido da:' - ,tr: 'Tarihinden itibaren geçerli' + ,tr: 'Tarihinden itibaren geçerli' ,zh_cn: '生效从:' } ,'Save current record before switching to new?' : { @@ -9376,6 +9122,7 @@ function init() { ,sv: 'Spara före byte till nytt?' ,fi: 'Tallenna nykyinen merkintä ennen vaihtamista uuteen?' ,bg: 'Запазване текущият запис преди превключване на нов?' + ,hr: 'Spremi trenutni zapis prije prelaska na novi?' ,pl: 'Nagrać bieżący rekord przed przełączeniem na nowy?' ,pt: 'Salvar os dados atuais antes de mudar para um novo?' ,ru: 'Сохранить текущие записи перед переходом к новым?' @@ -9399,6 +9146,7 @@ function init() { ,sv: 'Lägg till nytt intervall före' ,fi: 'Lisää uusi aikaväli ennen' ,bg: 'Добави интервал преди' + ,hr: 'Dodaj novi interval iznad' ,pl: 'Dodaj nowy przedział przed' ,pt: 'Adicionar novo intervalo antes de' ,ru: 'Добавить интервал перед' @@ -9422,6 +9170,7 @@ function init() { ,sv: 'Ta bort intervall' ,fi: 'Poista aikaväli' ,bg: 'Изтрий интервал' + ,hr: 'Obriši interval' ,pl: 'Usuń przedział' ,pt: 'Apagar intervalo' ,ru: 'Удалить интервал' @@ -9444,6 +9193,7 @@ function init() { ,sv: 'I:C' ,fi: 'I:HH' ,bg: 'И:ВХ' + ,hr: 'I:C' ,pl: 'I:C' ,pt: 'I:C' ,ru: 'Инс:Углев' @@ -9466,6 +9216,7 @@ function init() { ,sv: 'ISF' ,fi: 'ISF' ,bg: 'Инсулинова чувствителност' + ,hr: 'ISF' ,pl: 'ISF' ,pt: 'ISF' ,nl: 'ISF' @@ -9489,6 +9240,7 @@ function init() { ,sv: 'Combo-bolus' ,nb: 'Kombinasjonsbolus' ,bg: 'Двоен болус' + ,hr: 'Dual bolus' ,fi: 'Yhdistelmäbolus' ,pt: 'Bolus duplo' ,ru: 'Комбинированный болюс' @@ -9511,6 +9263,7 @@ function init() { ,sv: 'Skillnad' ,nb: 'Forskjell' ,bg: 'Разлика' + ,hr: 'Razlika' ,fi: 'Ero' ,ru: 'Разность' ,sk: 'Rozdiel' @@ -9534,6 +9287,7 @@ function init() { ,sv: 'Ny tid' ,nb: 'Ny tid' ,bg: 'Ново време' + ,hr: 'Novo vrijeme' ,fi: 'Uusi aika' ,ru: 'Новое время' ,sk: 'Nový čas' @@ -9557,6 +9311,7 @@ function init() { ,el: 'Λειτουργία Επεξεργασίας' ,nb: 'Editeringsmodus' ,bg: 'Редактиране' + ,hr: 'Uređivanje' ,fi: 'Muokkausmoodi' ,ru: 'Режим редактирования' ,sk: 'Editačný mód' @@ -9582,6 +9337,7 @@ function init() { ,sv: 'Ikon visas när editeringsläge är aktivt' ,nb: 'Ikon vises når editeringsmodus er aktivert' ,bg: 'Когато е активно ,иконката за редактиране ще се вижда' + ,hr: 'Kada je omogućeno, mod uređivanje je omogućen' ,fi: 'Muokkausmoodin ikoni tulee näkyviin kun laitat tämän päälle' ,ru: 'При активации видна икона начать режим редактирования' ,sk: 'Keď je povolený, je zobrazená ikona editačného módu' @@ -9606,6 +9362,7 @@ function init() { ,sv: 'Operation' ,nb: 'Operasjon' ,bg: 'Операция' + ,hr: 'Operacija' ,fi: 'Operaatio' ,ru: 'Операция' ,sk: 'Operácia' @@ -9629,6 +9386,7 @@ function init() { ,sv: 'Flytta' ,nb: 'Flytt' ,bg: 'Премести' + ,hr: 'Pomakni' ,fi: 'Liikuta' ,ru: 'Переместить' ,sk: 'Presunúť' @@ -9652,6 +9410,7 @@ function init() { ,sv: 'Ta bort' ,nb: 'Slett' ,bg: 'Изтрий' + ,hr: 'Obriši' ,fi: 'Poista' ,sk: 'Zmazať' ,ru: 'Удалить' @@ -9676,6 +9435,7 @@ function init() { ,sv: 'Flytta insulin' ,nb: 'Flytt insulin' ,bg: 'Премести инсулин' + ,hr: 'Premjesti inzulin' ,fi: 'Liikuta insuliinia' ,ru: 'Переместить инсулин' ,sk: 'Presunúť inzulín' @@ -9699,6 +9459,7 @@ function init() { ,sv: 'Flytta kolhydrater' ,nb: 'Flytt karbohydrater' ,bg: 'Премести ВХ' + ,hr: 'Premejsti UGH' ,fi: 'Liikuta hiilihydraatteja' ,ru: 'Переместить углеводы' ,sk: 'Presunúť sacharidy' @@ -9722,6 +9483,7 @@ function init() { ,sv: 'Ta bort insulin' ,nb: 'Fjern insulin' ,bg: 'Изтрий инсулин' + ,hr: 'Obriši inzulin' ,fi: 'Poista insuliini' ,ru: 'Удалить инсулин' ,sk: 'Odstrániť inzulín' @@ -9745,6 +9507,7 @@ function init() { ,sv: 'Ta bort kolhydrater' ,nb: 'Fjern karbohydrater' ,bg: 'Изтрий ВХ' + ,hr: 'Obriši UGH' ,fi: 'Poista hiilihydraatit' ,ru: 'Удалить углеводы' ,sk: 'Odstrániť sacharidy' @@ -9768,6 +9531,7 @@ function init() { ,sv: 'Ändra behandlingstid till %1 ?' ,nb: 'Endre behandlingstid til %1 ?' ,bg: 'Да променя ли времето на събитието с %1?' + ,hr: 'Promijeni vrijeme tretmana na %1?' ,fi: 'Muuta hoidon aika? Uusi: %1' ,ru: 'Изменить время события на %1?' ,sk: 'Zmeniť čas ošetrenia na %1 ?' @@ -9791,6 +9555,7 @@ function init() { ,sv: 'Ändra kolhydratstid till %1 ?' ,nb: 'Endre Karbohydrattid til %1 ?' ,bg: 'Да променя ли времето на ВХ с %1?' + ,hr: 'Promijeni vrijeme UGH na %1?' ,fi: 'Muuta hiilihydraattien aika? Uusi: %1' ,ru: 'Изменить время подачи углеводов на %?' ,sk: 'Zmeniť čas sacharidov na %1 ?' @@ -9814,6 +9579,7 @@ function init() { ,sv: 'Ändra insulintid till %1 ?' ,nb: 'Endre insulintid til %1 ?' ,bg: 'Да променя ли времето на инсулина с %1?' + ,hr: 'Promijeni vrijeme inzulina na %1?' ,fi: 'Muuta insuliinin aika? Uusi: %1' ,ru: 'Изменить время подачи инсулина на %?' ,sk: 'Zmeniť čas inzulínu na %1 ?' @@ -9837,6 +9603,7 @@ function init() { ,sv: 'Ta bort behandling ?' ,nb: 'Fjern behandling ?' ,bg: 'Изтрий събитието' + ,hr: 'Obriši tretman?' ,fi: 'Poista hoito?' ,ru: 'Удалить событие?' ,sk: 'Odstrániť ošetrenie?' @@ -9860,6 +9627,7 @@ function init() { ,sv: 'Ta bort insulin från behandling ?' ,nb: 'Fjern insulin fra behandling ?' ,bg: 'Да изтрия ли инсулина от събитието?' + ,hr: 'Obriši inzulin iz tretmana?' ,fi: 'Poista insuliini hoidosta?' ,ru: 'Удалить инсулин из событий?' ,sk: 'Odstrániť inzulín z ošetrenia?' @@ -9883,6 +9651,7 @@ function init() { ,sv: 'Ta bort kolhydrater från behandling ?' ,nb: 'Fjern karbohydrater fra behandling ?' ,bg: 'Да изтрия ли ВХ от събитието?' + ,hr: 'Obriši UGH iz tretmana?' ,fi: 'Poista hiilihydraatit hoidosta?' ,ru: 'Удалить углеводы из событий?' ,sk: 'Odstrániť sacharidy z ošetrenia?' @@ -9906,6 +9675,7 @@ function init() { ,sv: 'Rendering' ,nb: 'Rendering' ,bg: 'Показване на графика' + ,hr: 'Iscrtavanje' ,fi: 'Piirrän graafeja' ,ru: 'Построение графика' ,sk: 'Vykresľujem' @@ -9929,6 +9699,7 @@ function init() { ,sv: 'Laddar OpenAPS data för' ,nb: 'Laster OpenAPS data for' ,bg: 'Зареждане на OpenAPS данни от' + ,hr: 'Učitavanje OpenAPS podataka od' ,fi: 'Lataan OpenAPS tietoja' ,ru: 'Загрузка данных OpenAPS от' ,sk: 'Nahrávam OpenAPS dáta z' @@ -9952,6 +9723,7 @@ function init() { ,sv: 'Laddar ny profildata' ,nb: 'Laster nye profildata' ,bg: 'Зареждане на данни от сменения профил' + ,hr: 'Učitavanje podataka promjene profila' ,fi: 'Lataan profiilinvaihtotietoja' ,ru: 'Загрузка данных нового профиля' ,sk: 'Nahrávam dáta prepnutia profilu' @@ -9965,7 +9737,7 @@ function init() { } ,'Profile is going to be saved in newer format used in Nightscout 0.9.0 and above and will not be usable in older versions anymore.\nAre you sure?' : { cs: 'Profil bude uložen v novějším formátu používaném v Nightscoutu 0.9.0 a novějších. Již nebude použitelný se starší verzí.\nJste si jistý?' - ,he: 'הפרופיל עומד להישמר בתבנית חדשה יותר בשימוש ב- Nightscout 0.9.0 ומעלה ולא יהיה ניתן להשתמש בו בגרסאות ישנות יותר. \ האם אתה בטוח? ' + ,he: 'הפרופיל עומד להישמר בתבנית חדשה יותר בשימוש ב- Nightscout 0.9.0 ומעלה ולא יהיה ניתן להשתמש בו בגרסאות ישנות יותר. \n האם אתה בטוח? ' ,el: 'Το προφίλ πρόκειται να αποθηκευτεί με τη νέα του μορφή (έκδοση Nighscout 0.9.0 και πάνω) και δεν πρόκειται να μπορεί να χρησιμοποιηθεί σε παλαιότερες εκδόσεις. \nΕίστε σίγουροι?' ,fr: 'Le profil va être sauvegardé dans un nouveau format utilisé par Nightscout 0.9.0 et suivants, et il ne pourra plus être utilisé par les versions antérieures. \nÊtes-vous sûr?' ,ro: 'Profilul va fi salvat într-un format nou, folosit în Nightscout 0.9.0 și superior și nu va mai fi posibilă folosirea pentru versiunile mai vechi.\nSunteți de acord?' @@ -9975,6 +9747,7 @@ function init() { ,sv: 'Profilen sparas i ett nyare format som ej kommer fungera i tidigare versioner av Nightscout (<0.9.0). \nÄr du säker?' ,nb: 'Profilen lagres i ett nyere format som ikke kommer til å fungera i tidigere versioner av Nightscout (<0.9.0). \nEr du sikker?' ,bg: 'Профилът ще бъде запаметен в нов формат, който се ползва от Nightscout 0.9.0 и нагоре и няма да бъде съвместим с по-стари версии. \nСигурен ли си ?' + ,hr: 'Profil će biti spremljen u novijem formatu korištenom u Nightscout 0.9.0 i kasnije te neće više biti upotrebljiv u starijim verzijama.\nJeste li sigurni?' ,fi: 'Profiili tallennetaan uuteen Nightscout 0.9.0 käyttämään muotoon, eikä sitä voi enää käyttää vanhempien versioiden kanssa.\nOletko varma?' ,ru: 'Профиль будет сохранен в более позднем формате Nightscout 0.9.0 и выше и не сможет более использоваться в старых версиях. Вы согласны? ' ,sk: 'Profil bude uložený v novšom formáte používanom od verzie Nightscout 0.9.0 a novších. Nebude už použiteľný v starších verziách.\nSte si istý?' @@ -9988,13 +9761,14 @@ function init() { } ,'Wrong profile setting.\nNo profile defined to displayed time.\nRedirecting to profile editor to create new profile.' : { cs: 'Chybě nastavený profil.\nNení definovaný žádný platný profil k času zobrazení.\nProvádím přesměrování na editor profilu.' - ,he: 'הגדרת פרופיל שגוי. \ N פרופיל מוגדר לזמן המוצג. מפנה מחדש לעורך פרופיל כדי ליצור פרופיל חדש. ' + ,he: 'הגדרת פרופיל שגוי. \n פרופיל מוגדר לזמן המוצג. מפנה מחדש לעורך פרופיל כדי ליצור פרופיל חדש. ' ,el: 'Λάθος προφίλ. Παρακαλώ δημιουργήστε ένα νέο προφίλ' ,fr: 'Erreur de réglage de profil. \nAucun profil défini pour indiquer l\'heure. \nRedirection vers la création d\'un nouveau profil. ' ,de: 'Falsche Profileinstellung.\nKein Profil festgelegt zur angezeigten Zeit.\n Weiter zum Profileditor, um ein neues Profil zu erstellen.' ,dk: 'Forkert profilindstilling.\nIngen profil defineret til at vise tid.\nOmdirigere til profil editoren for at lave en ny profil.' ,es: 'Configuración incorrecta del perfil. \n No establecido ningún perfil en el tiempo mostrado. \n Continuar en editor de perfil para crear perfil nuevo.' ,bg: 'Грешни настройки на профила. \nНяма определен профил към избраното време. \nПрепращане към редактора на профила, за създаване на нов профил.' + ,hr: 'Krive postavke profila.\nNiti jedan profil nije definiran za prikazano vrijeme.\nPreusmjeravanje u editor profila kako biste stvorili novi.' ,ro: 'Setare de profil eronată.\nNu este definit niciun profil pentru perioada afișată.\nMergeți la editorul de profiluri pentru a defini unul nou.' ,sv: 'Fel profilinställning.\nIngen profil vald för vald tid.\nOmdirigerar för att skapa ny profil.' ,nb: 'Feil profilinstilling.\nIngen profil valgt for valgt tid.\nVideresender for å lage ny profil.' @@ -10021,6 +9795,7 @@ function init() { ,dk: 'Pumpe' ,es: 'Bomba' ,bg: 'Помпа' + ,hr: 'Pumpa' ,ro: 'Pompă' ,ru: 'Помпа' ,nl: 'Pomp' @@ -10044,6 +9819,7 @@ function init() { ,dk: 'Sensor alder (SAGE)' ,es: 'Días uso del sensor' ,bg: 'Възраст на сензора (ВС)' + ,hr: 'Starost senzora' ,ro: 'Vechimea senzorului' ,ru: 'Сенсор проработал' ,nl: 'Sensor leeftijd' @@ -10068,6 +9844,7 @@ function init() { ,dk: 'Insulinalder (IAGE)' ,es: 'Días uso cartucho insulina' ,bg: 'Възраст на инсулина (ВИ)' + ,hr: 'Starost inzulina' ,ro: 'Vechimea insulinei' ,ru: 'инсулин проработал' ,ko: '인슐린 사용 기간' @@ -10092,6 +9869,7 @@ function init() { ,sv: 'Tillfälligt mål' ,nb: 'Mildertidig mål' ,bg: 'Временна граница' + ,hr: 'Privremeni cilj' ,ro: 'Țintă temporară' ,ru: 'Временная цель' ,nl: 'Tijdelijk doel' @@ -10114,6 +9892,7 @@ function init() { ,dk: 'Årsag' ,es: 'Razonamiento' ,bg: 'Причина' + ,hr: 'Razlog' ,nl: 'Reden' ,ro: 'Motiv' ,ru: 'Причина' @@ -10136,6 +9915,7 @@ function init() { ,dk: 'Spiser snart' ,es: 'Comer pronto' ,bg: 'Ядене скоро' + ,hr: 'Uskoro jelo' ,ro: 'Mâncare în curând' ,ru: 'Скоро еда' ,nl: 'Binnenkort eten' @@ -10159,6 +9939,7 @@ function init() { ,dk: 'Toppen' ,es: 'Superior' ,bg: 'Горе' + ,hr: 'Vrh' ,ro: 'Deasupra' ,ru: 'Верх' ,nl: 'Boven' @@ -10182,6 +9963,7 @@ function init() { ,dk: 'Bunden' ,es: 'Inferior' ,bg: 'Долу' + ,hr: 'Dno' ,ro: 'Sub' ,ru: 'Низ' ,nl: 'Beneden' @@ -10205,6 +9987,7 @@ function init() { ,dk: 'Aktivitet' ,es: 'Actividad' ,bg: 'Активност' + ,hr: 'Aktivnost' ,ro: 'Activitate' ,ru: 'Активность' ,nl: 'Activiteit' @@ -10228,6 +10011,7 @@ function init() { ,sv: 'Mål' ,nb: 'Mål' ,bg: 'Граници' + ,hr: 'Ciljevi' ,ro: 'Ținte' ,ru: 'Цели' ,nl: 'Doelen' @@ -10250,6 +10034,7 @@ function init() { ,ru: 'Болюс инсулин' ,sv: 'Bolusinsulin:' ,nb: 'Bolusinsulin:' + ,hr: 'Bolus:' ,ko: 'Bolus 인슐린' ,fi: 'Bolusinsuliini:' ,de: 'Bolus Insulin:' @@ -10273,6 +10058,7 @@ function init() { ,ru: 'Основной базал инсулин' ,sv: 'Basalinsulin:' ,nb: 'Basalinsulin:' + ,hr: 'Osnovni bazal:' ,ko: '기본 basal 인슐린' ,fi: 'Basaalin perusannos:' ,de: 'Basis Basal Insulin:' @@ -10296,6 +10082,7 @@ function init() { ,ru: 'Положит знач временн базал инс ' ,sv: 'Positiv tempbasal insulin:' ,nb: 'Positiv midlertidig basalinsulin:' + ,hr: 'Pozitivni temp bazal:' ,ko: '초과된 임시 basal 인슐린' ,fi: 'Positiivinen tilapäisbasaali:' ,de: 'Positives temporäres Basal Insulin:' @@ -10319,6 +10106,7 @@ function init() { ,sv: 'Negativ tempbasal för insulin:' ,es: 'Insulina basal temporal negativa:' ,nb: 'Negativ midlertidig basalinsulin:' + ,hr: 'Negativni temp bazal:' ,ko: '남은 임시 basal 인슐린' ,fi: 'Negatiivinen tilapäisbasaali:' ,de: 'Negatives temporäres Basal Insulin:' @@ -10342,6 +10130,7 @@ function init() { ,ru: 'Всего базал инсулина' ,sv: 'Total dagsdos basalinsulin:' ,nb: 'Total daglig basalinsulin:' + ,hr: 'Ukupno bazali:' ,ko: '전체 basal 인슐린' ,fi: 'Basaali yhteensä:' ,de: 'Gesamt Basal Insulin:' @@ -10364,6 +10153,7 @@ function init() { ,ru: 'Всего суточн базал инсулина' ,sv: 'Total dagsdos insulin' ,nb: 'Total daglig insulin' + ,hr: 'Ukupno dnevni inzulin:' ,ko: '하루 인슐린 총량' ,fi: 'Päivän kokonaisinsuliiniannos' ,de: 'Gesamtes tägliches Insulin:' @@ -10381,6 +10171,7 @@ function init() { cs: 'Chyba volání %1 Role:' ,he: 'לא יכול תפקיד %1' ,bg: 'Невъзможно да %1 Роля' + ,hr: 'Unable to %1 Role' ,fr: 'Incapable de %1 rôle' ,ro: 'Imposibil de %1 Rolul' ,es: 'Incapaz de %1 Rol' @@ -10403,6 +10194,7 @@ function init() { cs: 'Nelze odstranit Roli:' ,he: 'לא יכול לבטל תפקיד ' ,bg: 'Невъзможно изтриването на Роля' + ,hr: 'Ne mogu obrisati ulogu' ,ro: 'Imposibil de șters Rolul' ,fr: 'Effacement de rôle impossible' ,ru: 'Невозможно удалить Роль' @@ -10425,6 +10217,7 @@ function init() { cs: 'Databáze obsahuje %1 rolí' ,he: 'בסיס הנתונים מכיל %1 תפקידים ' ,bg: 'Базата данни съдържа %1 роли' + ,hr: 'baza sadrži %1 uloga' ,ro: 'Baza de date conține %1 rol(uri)' ,fr: 'La base de données contient %1 rôles' ,ru: 'База данных содержит %1 Ролей' @@ -10447,6 +10240,7 @@ function init() { cs:'Editovat roli' ,he: 'ערוך תפקיד ' ,bg: 'Промени Роля' + ,hr: 'Uredi ulogu' ,ro: 'Editează Rolul' ,fr: 'Éditer le rôle' ,ru: 'Редактировать Роль' @@ -10469,6 +10263,7 @@ function init() { cs: 'administrátor, škola, rodina atd...' ,he: 'מנהל, בית ספר, משפחה, וכו ' ,bg: 'администратор,училище,семейство и т.н.' + ,hr: 'admin, škola, obitelj, itd.' ,fr: 'Administrateur, école, famille, etc' ,ro: 'administrator, școală, familie, etc' ,ru: 'админ, школа, семья и т д' @@ -10491,6 +10286,7 @@ function init() { cs: 'Oprávnění' ,he: 'הרשאות ' ,bg: 'Права' + ,hr: 'Prava' ,ro: 'Permisiuni' ,fr: 'Permissions' ,ru: 'Разрешения' @@ -10513,6 +10309,7 @@ function init() { cs: 'Opravdu vymazat: ' ,he: 'אתה בטוח שאתה רוצה למחוק' ,bg: 'Потвърдете изтриването' + ,hr: 'Sigurno želite obrisati?' ,ro: 'Confirmați ștergerea: ' ,fr: 'Êtes-vous sûr de vouloir effacer:' ,ru: 'Вы уверены, что хотите удалить' @@ -10534,15 +10331,15 @@ function init() { ,'Each role will have a 1 or more permissions. The * permission is a wildcard, permissions are a hierarchy using : as a separator.' : { cs: 'Každá role má 1 nebo více oprávnění. Oprávnění * je zástupný znak, oprávnění jsou hiearchie používající : jako oddělovač.' ,bg: 'Всяка роля ще има 1 или повече права. В * правото е маска, правата са йерархия използвайки : като разделител' + ,hr: 'Svaka uloga ima 1 ili više prava. Pravo * je univerzalno, a prava su hijerarhija koja koristi znak : kao graničnik.' ,fr: 'Chaque rôle aura une ou plusieurs permissions. La permission * est un joker (permission universelle), les permissions sont une hierarchie utilisant : comme séparatuer' ,ro: 'Fiecare rol va avea cel puțin o permisiune. Permisiunea * este totală, permisiunile sunt ierarhice utilizând : pe post de separator.' ,ru: 'Каждая роль имеет 1 или более разрешений. Разрешение * это подстановочный символ, разрешения это иерархия, использующая : как разделитель.' ,sv: 'Varje roll kommer få en eller flera rättigheter. * är en wildcard, rättigheter sätts hirarkiskt med : som avgränsare.' - ,dk: 'Hver rolle vil have en eller flere rettigheder. Rollen * fungere som wildcard / joker, rettigheder sættes hierakisk med : som skilletegn.' + ,dk: 'Hver rolle vil have en eller flere rettigheder. Rollen * fungere som wildcard / joker, rettigheder sættes hierakisk med : som skilletegn.' ,nb: 'Hver enkelt rolle vil ha en eller flere rettigheter. *-rettigheten er wildcard. Rettigheter settes hierarkisk med : som separator.' ,fi: 'Jokaisella roolilla on yksi tai useampia oikeuksia. * on jokeri (tunnistuu kaikkina oikeuksina), oikeudet ovat hierarkia joka käyttää : merkkiä erottimena.' ,de: 'Jede Rolle hat eine oder mehrere Berechtigungen. Die * Berechtigung ist ein Platzhalter, Berechtigungen sind hierachrchisch mit : als Separator.' - ,sv: 'Hver rolle vil have en eller flere rettigheder. * er en joker, rettigheder sættes hierakisk med : som skilletegn.' ,es: 'Cada Rol tiene uno o más permisos. El permiso * es un marcador de posición y los permisos son jerárquicos con : como separador.' ,pt: 'Cada função terá uma ou mais permissões. A permissão * é um wildcard, permissões são uma hierarquia utilizando * como um separador.' ,sk: 'Každá rola má 1 alebo viac oprávnení. Oprávnenie * je zástupný znak, oprávnenia sú hierarchie používajúce : ako oddelovač.' @@ -10557,6 +10354,7 @@ function init() { cs: 'Přidat novou roli' ,he: 'הוסף תפקיד חדש ' ,bg: 'Добавете нова роля' + ,hr: 'Dodaj novu ulogu' ,fr: 'Ajouter un nouveau rôle' ,ro: 'Adaugă un Rol nou' ,ru: 'Добавить новую Роль' @@ -10579,6 +10377,7 @@ function init() { cs: 'Role - Skupiny lidí, zařízení atd.' ,he: 'תפקידים - קבוצות של אנשים, התקנים, וכו ' ,bg: 'Роли - Група хора,устройства,т.н.' + ,hr: 'Uloge - Grupe ljudi, uređaja, itd.' ,fr: 'Rôles - Groupe de Personnes ou d\'appareils' ,ro: 'Roluri - Grupuri de persoane, dispozitive, etc' ,es: 'Roles - Grupos de Gente, Dispositivos, etc.' @@ -10601,6 +10400,7 @@ function init() { cs: 'Editovat tuto roli' ,he: 'ערוך תפקיד זה ' ,bg: 'Промени тази роля' + ,hr: 'Uredi ovu ulogu' ,fr: 'Editer ce rôle' ,ro: 'Editează acest rol' ,ru: 'Редактировать эту роль' @@ -10623,6 +10423,7 @@ function init() { cs: 'Admin autorizován' ,he: 'מנהל אושר ' ,bg: 'Оторизиран като администратор' + ,hr: 'Administrator ovlašten' ,fr: 'Administrateur autorisé' ,ro: 'Autorizat de admin' ,es: 'Administrador autorizado' @@ -10646,6 +10447,7 @@ function init() { cs: 'Subjekty - Lidé, zařízení atd.' ,he: 'נושאים - אנשים, התקנים וכו ' ,bg: 'Субекти - Хора,Устройства,т.н.' + ,hr: 'Subjekti - Ljudi, uređaji, itd.' ,fr: 'Utilisateurs - Personnes, Appareils, etc' ,ro: 'Subiecte - Persoane, dispozitive, etc' ,es: 'Sujetos - Personas, Dispositivos, etc' @@ -10668,6 +10470,7 @@ function init() { cs: 'Každý subjekt má svůj unikátní token a 1 nebo více rolí. Klikem na přístupový token se otevře nové okno pro tento subjekt. Tento link je možné sdílet.' ,he: 'לכל נושא תהיה אסימון גישה ייחודי ותפקיד אחד או יותר. לחץ על אסימון הגישה כדי לפתוח תצוגה חדשה עם הנושא הנבחר, קישור סודי זה יכול להיות משותף ' ,bg: 'Всеки обект ще има уникален ключ за достъп и 1 или повече роли. Кликнете върху ключа за достъп, за да отворите нов изглед с избрания обект, тази секретна връзка може след това да се споделя' + ,hr: 'Svaki subjekt će dobiti jedinstveni pristupni token i jednu ili više uloga. Kliknite na pristupni token kako bi se otvorio novi pogled sa odabranim subjektom, a tada se tajni link može podijeliti.' ,fr: 'Chaque utilisateur aura un identificateur unique et un ou plusieurs rôles. Cliquez sur l\'identificateur pour révéler l\'utilisateur, ce lien secret peut être partagé.' ,ro: 'Fiecare subiect va avea o cheie unică de acces și unul sau mai multe roluri. Apăsați pe cheia de acces pentru a vizualiza subiectul selectat, acest link poate fi distribuit.' ,ru: 'Каждый субъект получает уникальный код доступа и 1 или более ролей. Нажмите на иконку кода доступа чтобы открыть новое окно с выбранным субъектом, эту секретную ссылку можно переслать.' @@ -10676,7 +10479,7 @@ function init() { ,nb: 'Hver enkelt ressurs får en unik sikkerhetsnøkkel og en eller flere roller. Klikk på sikkerhetsnøkkelen for å åpne valgte ressurs, den hemmelige lenken kan så deles.' ,fi: 'Jokaisella käyttäjällä on uniikki pääsytunniste ja yksi tai useampi rooli. Klikkaa pääsytunnistetta nähdäksesi käyttäjän, jolloin saat jaettavan osoitteen tämän käyttäjän oikeuksilla.' ,de: 'Jedes Subjekt erhält einen einzigartigen Zugriffsschlüssel und eine oder mehrere Rollen. Klicke auf den Zugriffsschlüssel, um eine neue Ansicht mit dem ausgewählten Subjekt zu erhalten. Dieser geheime Link kann geteilt werden.' - ,dk: 'Hvert emne vil have en unik sikkerhedsnøgle samt en eller flere roller. Klik på sikkerhedsnøglen for at åbne et nyt view med det valgte emne, dette hemmelige link kan derefter blive delt.' + ,dk: 'Hvert emne vil have en unik sikkerhedsnøgle samt en eller flere roller. Klik på sikkerhedsnøglen for at åbne et nyt view med det valgte emne, dette hemmelige link kan derefter blive delt.' ,pt: 'Cada assunto terá um único token de acesso e uma ou mais Funções. Clique no token de acesso para abrir uma nova visualização com o assunto selecionado. Este link secreto poderá então ser compartilhado' ,sk: 'Každý objekt má svoj unikátny prístupový token a 1 alebo viac rolí. Klikni na prístupový token pre otvorenie nového okna pre tento subjekt. Tento link je možné zdielať.' ,ko: '각 주제는 유일한 access token을 가지고 1 또는 그 이상의 역할을 가질 것이다. 선택된 주제와 새로운 뷰를 열기 위해 access token을 클릭하세요. 이 비밀 링크는 공유되어질 수 있다.' @@ -10690,6 +10493,7 @@ function init() { cs: 'Přidat nový subjekt' ,he: 'הוסף נושא חדש ' ,bg: 'Добави нов субект' + ,hr: 'Dodaj novi subjekt' ,fr: 'Ajouter un nouvel Utilisateur' ,ro: 'Adaugă un Subiect nou' ,ru: 'Добавить нового субъекта' @@ -10712,6 +10516,7 @@ function init() { cs: 'Chyba volání %1 Subjektu:' ,en: 'לא יכול ל %1 נושאי' ,bg: 'Невъзможно %1 субект' + ,hr: 'Ne mogu %1 subjekt' ,ro: 'Imposibil de %1 Subiectul' ,fr: 'Impossible de créer l\'Utilisateur %1' ,ru: 'Невозможно %1 субъекта' @@ -10734,6 +10539,7 @@ function init() { cs: 'Nelze odstranit Subjekt:' ,he: 'לא יכול לבטל נושא ' ,bg: 'Невъзможно изтриването на субекта' + ,hr: 'Ne mogu obrisati subjekt' ,ro: 'Imposibil de șters Subiectul' ,fr: 'Impossible d\'effacer l\'Utilisateur' ,ru: 'Невозможно удалить ' @@ -10756,6 +10562,7 @@ function init() { cs: 'Databáze obsahuje %1 subjektů' ,he: 'מסד נתונים מכיל %1 נושאים ' ,bg: 'Базата данни съдържа %1 субекти' + ,hr: 'Baza sadrži %1 subjekata' ,fr: 'La base de données contient %1 utilisateurs' ,fi: 'Tietokanta sisältää %1 käyttäjää' ,ru: 'База данных содержит %1 субъект(а/ов)' @@ -10778,6 +10585,7 @@ function init() { cs:'Editovat subjekt' ,he: 'ערוך נושא ' ,bg: 'Промени субект' + ,hr: 'Uredi subjekt' ,ro: 'Editează Subiectul' ,es: 'Editar sujeto' ,fr: 'Éditer l\'Utilisateur' @@ -10800,6 +10608,7 @@ function init() { cs:'osoba, zařízeni atd.' ,he: 'אדם, מכשיר, וכו ' ,bg: 'човек,устройство,т.н.' + ,hr: 'osoba, uređaj, itd.' ,ro: 'persoană, dispozitiv, etc' ,fr: 'personne, appareil, etc' ,ru: 'лицо, устройство и т п' @@ -10822,6 +10631,7 @@ function init() { cs:'role1, role2' ,he: 'תפקיד1, תפקיד2 ' ,bg: 'Роля1, Роля2' + ,hr: 'uloga1, uloga2' ,ro: 'Rol1, Rol2' ,fr: 'rôle1, rôle2' ,ru: 'Роль1, Роль2' @@ -10844,6 +10654,7 @@ function init() { cs:'Editovat tento subjekt' ,he: 'ערוך נושא זה ' ,bg: 'Промени този субект' + ,hr: 'Uredi ovaj subjekt' ,ro: 'Editează acest subiect' ,fr: 'Éditer cet utilisateur' ,ru: 'Редактировать этого субъекта' @@ -10866,6 +10677,7 @@ function init() { cs:'Smazat tento subjekt' ,he: 'בטל נושא זה ' ,bg: 'Изтрий този субект' + ,hr: 'Obriši ovaj subjekt' ,ro: 'Șterge acest subiect' ,fr: 'Effacer cet utilisateur:' ,ru: 'Удалить этого субъекта' @@ -10888,6 +10700,7 @@ function init() { cs:'Role' ,he: 'תפקידים ' ,bg: 'Роли' + ,hr: 'Uloge' ,ro: 'Roluri' ,fr: 'Rôles' ,ru: 'Роли' @@ -10910,6 +10723,7 @@ function init() { cs:'Přístupový token' ,he: 'אסימון גישה ' ,bg: 'Ключ за достъп' + ,hr: 'Pristupni token' ,ro: 'Cheie de acces' ,fr: 'Identificateur unique' ,ru: 'Код доступа' @@ -10932,6 +10746,7 @@ function init() { cs:'hodina zpět' ,he: 'לפני שעה ' ,bg: 'Преди час' + ,hr: 'sat ranije' ,fr: 'heure avant' ,ro: 'oră în trecut' ,ru: 'час назад' @@ -10954,6 +10769,7 @@ function init() { cs:'hodin zpět' ,he: 'לפני שעות ' ,bg: 'Преди часове' + ,hr: 'sati ranije' ,fr: 'heures avant' ,ro: 'ore în trecut' ,ru: 'часов назад' @@ -10968,7 +10784,7 @@ function init() { ,ko: '시간 후' ,it: 'ore fa' ,nl: 'uren geleden' - ,tr: 'saatler önce' + ,tr: 'saat önce' ,zh_cn: '小时前' ,pl: 'Godzin temu' } @@ -10976,6 +10792,7 @@ function init() { cs:'Ztlumit na %1 minut' ,he: 'שקט ל %1 דקות ' ,bg: 'Заглушаване за %1 минути' + ,hr: 'Utišaj na %1 minuta' ,ro: 'Liniște pentru %1 minute' ,fr: 'Silence pour %1 minutes' ,ru: 'Молчание %1 минут' @@ -11010,6 +10827,7 @@ function init() { ,fi: 'Tarkista VS' ,pt: 'Verifique a glicemia' ,bg: 'Проверка КЗ' + ,hr: 'Provjeri GUK' ,ko: '혈당 체크' ,it: 'Controllare BG' ,nl: 'Controleer BG' @@ -11031,6 +10849,7 @@ function init() { ,fi: 'Basaali' ,pt: 'BASAL' ,bg: 'Базал' + ,hr: 'Bazal' ,ko: 'BASAL' ,es: 'BASAL' ,it: 'BASALE' @@ -11055,6 +10874,7 @@ function init() { ,pt: 'Basal atual' ,es: 'Basal actual' ,bg: 'Актуален базал' + ,hr: 'Trenutni bazal' ,ko: '현재 basal' ,it: 'Basale corrente' ,nl: 'Huidige basaal' @@ -11077,6 +10897,7 @@ function init() { ,es: 'Sensibilidad' ,pt: 'Fator de sensibilidade' ,bg: 'Инсулинова чувствителност (ISF)' + ,hr: 'Osjetljivost' ,ko: '인슐린 민감도(ISF)' ,it: 'ISF - sensibilità' ,nl: 'Gevoeligheid' @@ -11099,6 +10920,7 @@ function init() { ,pt: 'Relação insulina:carboidrato atual' ,fi: 'Nykyinen hiilihydraattiherkkyys' ,bg: 'Актуално Въглехидратно Съотношение' + ,hr: 'Trenutni I:C' ,ko: '현재 탄수화물 비율(ICR)' ,it: 'Attuale rapporto I:C' ,nl: 'Huidige KH ratio' @@ -11121,6 +10943,7 @@ function init() { ,pt: 'Fuso horário da basal' ,fi: 'Aikavyöhyke' ,bg: 'Базална часова зона' + ,hr: 'Vremenska zona bazala' ,ko: 'Basal 타임존' ,it: 'fuso orario basale' ,nl: 'Basaal tijdzone' @@ -11143,6 +10966,7 @@ function init() { ,es: 'Perfil activo' ,fi: 'Aktiivinen profiili' ,bg: 'Активен профил' + ,hr: 'Aktivni profil' ,ko: '활성 프로파일' ,it: 'Attiva profilo' ,nl: 'Actief profiel' @@ -11165,6 +10989,7 @@ function init() { ,es: 'Basal temporal activa' ,fi: 'Aktiivinen tilapäisbasaali' ,bg: 'Активен временен базал' + ,hr: 'Aktivni temp bazal' ,ko: '활성 임시 basal' ,it: 'Attiva Basale Temp' ,nl: 'Actieve tijdelijke basaal' @@ -11187,6 +11012,7 @@ function init() { ,es: 'Inicio Basal temporal activa' ,fi: 'Aktiivisen tilapäisbasaalin aloitus' ,bg: 'Старт на активен временен базал' + ,hr: 'Početak aktivnog tamp bazala' ,ko: '활성 임시 basal 시작' ,it: 'Attiva Inizio Basale temp' ,nl: 'Actieve tijdelijke basaal start' @@ -11209,6 +11035,7 @@ function init() { ,es: 'Duración Basal Temporal activa' ,fi: 'Aktiivisen tilapäisbasaalin kesto' ,bg: 'Продължителност на Активен временен базал' + ,hr: 'Trajanje aktivnog temp bazala' ,ko: '활성 임시 basal 시간' ,it: 'Attiva durata basale temp' ,nl: 'Actieve tijdelijk basaal duur' @@ -11231,6 +11058,7 @@ function init() { ,es: 'Basal temporal activa restante' ,fi: 'Aktiivista tilapäisbasaalia jäljellä' ,bg: 'Оставащ Активен временен базал' + ,hr: 'Prestali aktivni temp bazal' ,ko: '남아 있는 활성 임시 basal' ,it: 'Attiva residuo basale temp' ,nl: 'Actieve tijdelijke basaal resteert' @@ -11253,6 +11081,7 @@ function init() { ,pt: 'Valor do perfil basal' ,sk: 'Základná hodnota bazálu' ,bg: 'Базален профил стойност' + ,hr: 'Profilna vrijednost bazala' ,ko: 'Basal 프로파일 값' ,it: 'Valore profilo basale' ,nl: 'Basaal profiel waarde' @@ -11275,6 +11104,7 @@ function init() { ,es: 'Activo combo-bolo' ,sk: 'Aktívny kombinovaný bolus' ,bg: '' + ,hr: 'Aktivni dual bolus' ,ko: '활성 콤보 bolus' ,it: 'Attiva Combo bolo' ,nl: 'Actieve combo bolus' @@ -11297,6 +11127,7 @@ function init() { ,es: 'Inicio del combo-bolo activo' ,sk: 'Štart kombinovaného bolusu' ,bg: 'Активен комбиниран болус' + ,hr: 'Početak aktivnog dual bolusa' ,ko: '활성 콤보 bolus 시작' ,it: 'Attivo inizio Combo bolo' ,nl: 'Actieve combo bolus start' @@ -11319,6 +11150,7 @@ function init() { ,pt: 'Duração de bolus duplo em atividade' ,sk: 'Trvanie kombinovaného bolusu' ,bg: 'Продължителност на активния комбиниран болус' + ,hr: 'Trajanje aktivnog dual bolusa' ,ko: '활성 콤보 bolus 기간' ,it: 'Attivo durata Combo bolo' ,nl: 'Actieve combo bolus duur' @@ -11341,6 +11173,7 @@ function init() { ,pt: 'Restante de bolus duplo em atividade' ,sk: 'Zostávajúci kombinovaný bolus' ,bg: 'Оставащ активен комбиниран болус' + ,hr: 'Preostali aktivni dual bolus' ,ko: '남아 있는 활성 콤보 bolus' ,it: 'Attivo residuo Combo bolo' ,nl: 'Actieve combo bolus resteert' @@ -11363,6 +11196,7 @@ function init() { ,es: 'Diferencia de glucemia' ,sk: 'Zmena glykémie' ,bg: 'Изменение КЗ' + ,hr: 'GUK razlika' ,ko: '혈당 차이' ,it: 'BG Delta' ,nl: 'BG Delta' @@ -11386,6 +11220,7 @@ function init() { ,es: 'Tiempo transcurrido' ,sk: 'Uplynutý čas' ,bg: 'Изминало време' + ,hr: 'Proteklo vrijeme' ,ko: '경과 시간' ,it: 'Tempo Trascorso' ,nl: 'Verstreken tijd' @@ -11409,6 +11244,7 @@ function init() { ,es: 'Diferencia absoluta' ,sk: 'Absolútny rozdiel' ,bg: 'Абсолютно изменение' + ,hr: 'Apsolutna razlika' ,ko: '절대적인 차이' ,it: 'Delta Assoluto' ,nl: 'Abslute delta' @@ -11432,6 +11268,7 @@ function init() { ,es: 'Interpolado' ,sk: 'Interpolované' ,bg: 'Интерполирано' + ,hr: 'Interpolirano' ,ko: '삽입됨' ,it: 'Interpolata' ,nl: 'Geinterpoleerd' @@ -11451,6 +11288,7 @@ function init() { ,sv: 'Boluskalkylator' ,es: 'VistaPreviaCalculoBolo (BWP)' ,nb: 'Boluskalkulator' + ,hr: 'Čarobnjak bolusa' ,fi: 'Annoslaskuri' ,pt: 'Ajuda de bolus' ,sk: 'BK' @@ -11478,6 +11316,7 @@ function init() { ,pt: 'Urgente' ,sk: 'Urgentné' ,bg: 'Спешно' + ,hr: 'Hitno' ,ko: '긴급' ,it: 'Urgente' ,ja: '緊急' @@ -11502,6 +11341,7 @@ function init() { ,es: 'Aviso' ,sk: 'Varovanie' ,bg: 'Предупреждение' + ,hr: 'Upozorenje' ,ko: '경고' ,it: 'Avviso' ,nl: 'Waarschuwing' @@ -11525,6 +11365,7 @@ function init() { ,es: 'Información' ,sk: 'Info' ,bg: 'Информация' + ,hr: 'Info' ,ko: '정보' ,it: 'Info' ,nl: 'Info' @@ -11548,6 +11389,7 @@ function init() { ,pt: 'Mais baixo' ,sk: 'Najnižsie' ,bg: 'Най-ниско' + ,hr: 'Najniže' ,ko: '가장 낮은' ,it: 'Minore' ,nl: 'Laagste' @@ -11564,6 +11406,7 @@ function init() { ,ro: 'Ignoră alarma de hiper deoarece este suficientă insulină activă IOB' ,fr: 'Alarme haute ignorée car suffisamment d\'insuline à bord (IOB)' ,bg: 'Изключване на аларма за висока КЗ, тъй като има достатъчно IOB' + ,hr: 'Stišan alarm za hiper pošto ima dovoljno aktivnog inzulina' ,es: 'Ignorar alarma de Hiperglucemia al tener suficiente insulina activa' ,ru: 'Отключение предупреждение о высоком СК ввиду достаточности инсулина в организме' ,sv: 'Snoozar höglarm då aktivt insulin är tillräckligt' @@ -11571,6 +11414,7 @@ function init() { ,fi: 'Korkean sokerin varoitus poistettu riittävän insuliinin vuoksi' ,pt: 'Ignorar alarme de hiper em função de IOB suficiente' ,sk: 'Odloženie alarmu vysokej glykémie, pretože je dostatok IOB' + ,ko: '충분한 IOB가 남아 있기 때문에 고혈당 알람을 스누즈' ,it: 'Addormenta allarme alto poiché non vi è sufficiente IOB' ,nl: 'Snooze hoog alarm, er is genoeg IOB' ,tr: 'Yeterli IOB(Aktif İnsülin) olduğundan KŞ yüksek uyarımını ertele' @@ -11585,6 +11429,7 @@ function init() { ,ro: 'Verifică glicemia, poate este necesar un bolus?' ,fr: 'Vérifier la glycémie, bolus nécessaire ?' ,bg: 'Провери КЗ, не е ли време за болус?' + ,hr: 'Provjeri GUK, vrijeme je za bolus?' ,ru: 'Проверьте СК, не пора ли ввести болюс?' ,sv: 'Kontrollera BS, dags att ge bolus?' ,nb: 'Sjekk blodsukker, på tide med bolus?' @@ -11592,6 +11437,7 @@ function init() { ,pt: 'Meça a glicemia, hora de bolus de correção?' ,es: 'Controle su glucemia, ¿quizás un bolo Insulina?' ,sk: 'Skontrolovať glykémiu, čas na bolus?' + ,ko: 'Bolus를 주입할 시간입니다. 혈당 체크 하시겠습니까?' ,it: 'Controllare BG, il tempo del bolo?' ,nl: 'Controleer BG, tijd om te bolussen?' ,tr: 'KŞine bakın, gerekirse bolus verin?' @@ -11607,6 +11453,7 @@ function init() { ,ru: 'Заметка' ,fr: 'Notification' ,bg: 'Известие' + ,hr: 'Poruka' ,sv: 'Notering' ,es: 'Nota' ,nb: 'NB' @@ -11614,6 +11461,7 @@ function init() { ,nl: 'Notitie' ,pt: 'Nota' ,sk: 'Poznámka' + ,ko: '알림' ,it: 'Preavviso' ,tr: 'Not' ,zh_cn: '提示' @@ -11628,12 +11476,14 @@ function init() { ,fr: 'Information nécessaire manquante' ,ru: 'Отсутствует необходимая информация' ,bg: 'Липсва необходима информация' + ,hr: 'nedostaju potrebne informacije' ,sv: 'Nödvändig information saknas' ,nb: 'Nødvendig informasjon mangler' ,es: 'Falta información requerida' ,fi: 'tarvittava tieto puuttuu' ,pt: 'Informação essencial faltando' ,sk: 'chýbajúca informácia' + ,ko: '요청한 정보 손실' ,it: 'richiesta informazioni mancanti' ,nl: 'vereiste gegevens ontbreken' ,tr: 'gerekli bilgi eksik' @@ -11649,12 +11499,14 @@ function init() { ,fr: 'Insuline à bord (IOB)' ,ru: 'Активный инсулин (IOB)' ,bg: 'Активен Инсулин (IOB)' + ,hr: 'Aktivni inzulín' ,sv: 'Aktivt insulin (IOB)' ,nb: 'Aktivt insulin (IOB)' ,fi: 'Aktiivinen insuliini' ,pt: 'Insulina ativa' ,es: 'Insulina activa (IOB)' ,sk: 'Aktívny inzulín (IOB)' + ,ko: '활성 인슐린(IOB)' ,it: 'IOB - Insulina Attiva' ,nl: 'IOB - Inuline on board' ,tr: '(IOB) Aktif İnsülin' @@ -11670,12 +11522,14 @@ function init() { ,fr: 'Cible actuelle' ,ru: 'Актуальное целевое значение' ,bg: 'Настояща целева КЗ' + ,hr: 'Trenutni cilj' ,sv: 'Aktuellt mål' ,nb: 'Gjeldende mål' ,fi: 'Tämänhetkinen tavoite' ,es: 'Objetivo actual' ,pt: 'Meta atual' ,sk: 'Aktuálny cieľ' + ,ko: '현재 목표' ,it: 'Obiettivo attuale' ,nl: 'huidig doel' ,tr: 'Mevcut hedef' @@ -11691,12 +11545,14 @@ function init() { ,fr: 'Effect escompté' ,ru: 'Ожидаемый эффект' ,bg: 'Очакван ефект' + ,hr: 'Očekivani efekt' ,sv: 'Förväntad effekt' ,nb: 'Forventet effekt' ,fi: 'Oletettu vaikutus' ,pt: 'Efeito esperado' ,es: 'Efecto previsto' ,sk: 'Očakávaný efekt' + ,ko: '예상 효과' ,it: 'Effetto Previsto' ,nl: 'verwacht effect' ,tr: 'Beklenen etki' @@ -11712,12 +11568,14 @@ function init() { ,fr: 'Résultat escompté' ,ru: 'Ожидаемый результат' ,bg: 'Очакван резултат' + ,hr: 'Očekivani ishod' ,sv: 'Förväntat resultat' ,nb: 'Forventet resultat' ,fi: 'Oletettu lopputulos' ,pt: 'Resultado esperado' ,es: 'Resultado previsto' ,sk: 'Očakávaný výsledok' + ,ko: '예상 결과' ,it: 'Risultato previsto' ,nl: 'Veracht resultaat' ,tr: 'Beklenen sonuç' @@ -11733,6 +11591,7 @@ function init() { ,fr: 'Equivalent glucidique' ,ru: 'Эквивалент в углеводах' ,bg: 'Равностойност във ВХ' + ,hr: 'Ekvivalent u UGH' ,sv: 'Kolhydratsinnehåll' ,nb: 'Karbohydratekvivalent' ,nl: 'Koolhydraat equivalent' @@ -11740,6 +11599,7 @@ function init() { ,es: 'Equivalencia en Carbohidratos' ,pt: 'Equivalente em carboidratos' ,sk: 'Sacharidový ekvivalent' + ,ko: '탄수화물 양' ,it: 'Carb equivalenti' ,tr: 'Karbonhidrat eşdeğeri' ,zh_cn: '碳水当量' @@ -11754,6 +11614,7 @@ function init() { ,ro: 'Insulină în exces: %1U mai mult decât este necesar pentru a atinge ținta inferioară, fără a ține cont de carbohidrați' ,fr: 'Insuline en excès: %1U de plus que nécessaire pour atteindre la cible inférieure, sans prendre en compte les glucides' ,bg: 'Излишният инсулин %1U е повече от необходимия за достигане до долната граница, ВХ не се вземат под внимание' + ,hr: 'Višak inzulina je %1U više nego li je potrebno da se postigne donja ciljana granica, ne uzevši u obzir UGH' ,ru: 'Избыток инсулина равного %1U, необходимого для достижения нижнего целевого значения, углеводы не учитываются' ,sv: 'Överskott av insulin motsvarande %1U mer än nödvändigt för att nå lågt målvärde, kolhydrater ej medräknade' ,nb: 'Insulin tilsvarende %1U mer enn det trengs for å nå lavt mål, karbohydrater ikke medregnet' @@ -11761,8 +11622,8 @@ function init() { ,fi: 'Liikaa insuliinia: %1U enemmän kuin tarvitaan tavoitteeseen pääsyyn (huomioimatta hiilihydraatteja)' ,pt: 'Excesso de insulina equivalente a %1U além do necessário para atingir a meta inferior, sem levar em conta carboidratos' ,sk: 'Nadbytok inzulínu o %1U viac ako je potrebné na dosiahnutie spodnej cieľovej hranice. Neráta sa so sacharidmi.' + ,ko: '낮은 혈당 목표에 도달하기 위해 필요한 인슐린양보다 %1U의 인슐린 양이 초과 되었고 탄수화물 양이 초과되지 않았습니다.' ,it: 'L\'eccesso d\'insulina equivalente %1U più che necessari per raggiungere l\'obiettivo basso, non rappresentano i carboidrati.' - ,nl: 'Overschot insuline %1U meer dan nodig om het laag doel te bereiken, geen rekening gehouden met KH' ,tr: 'Fazla insülin: Karbonhidratları dikkate alınmadan, alt hedefe ulaşmak için gerekenden %1U\'den daha fazla' //??? ,zh_cn: '胰岛素超过至血糖下限目标所需剂量%1单位,不计算碳水化合物' , pl: 'Nadmiar insuliny, %1J więcej niż potrzeba, aby osiągnąć cel dolnej granicy, nie biorąc pod uwagę węglowodanów' @@ -11775,6 +11636,7 @@ function init() { ,ro: 'Insulină în exces: %1U mai mult decât este necesar pentru a atinge ținta inferioară, ASIGURAȚI-VĂ CĂ INSULINA ESTE ACOPERITĂ DE CARBOHIDRAȚI' ,fr: 'Insuline en excès: %1U de plus que nécessaire pour atteindre la cible inférieure, ASSUREZ UN APPORT SUFFISANT DE GLUCIDES' ,bg: 'Излишният инсулин %1U е повече от необходимия за достигане до долната граница, ПРОВЕРИ ДАЛИ IOB СЕ ПОКРИВА ОТ ВЪГЛЕХИДРАТИТЕ' + ,hr: 'Višak inzulina je %1U više nego li je potrebno da se postigne donja ciljana granica, OBAVEZNO POKRIJTE SA UGH' ,ru: 'Избыток инсулина, равного %1U, необходимого для достижения нижнего целевого значения, ПОКРОЙТЕ IOB ИНСУЛИН В ОРГАНИЗМЕ УГЛЕВОДАМИ' ,sv: 'Överskott av insulin motsvarande %1U mer än nödvändigt för att nå lågt målvärde, SÄKERSTÄLL ATT IOB TÄCKS AV KOLHYDRATER' ,es: 'Exceso de insulina en %1U más de la necesaria para alcanzar objetivo inferior. ASEGÚRESE QUE LA INSULINA ACTIVA IOB ESTA CUBIERTA POR CARBOHIDRATOS' @@ -11783,6 +11645,7 @@ function init() { ,fi: 'Liikaa insuliinia: %1U enemmän kuin tarvitaan tavoitteeseen pääsyyn, VARMISTA RIITTÄVÄ HIILIHYDRAATTIEN SAANTI' ,pt: 'Excesso de insulina equivalente a %1U além do necessário para atingir a meta inferior. ASSEGURE-SE DE QUE A IOB ESTEJA COBERTA POR CARBOIDRATOS' ,sk: 'Nadbytok inzulínu o %1U viac ako je potrebné na dosiahnutie spodnej cieľovej hranice. UISTITE SA, ŽE JE TO POKRYTÉ SACHARIDMI' + ,ko: '낮은 혈당 목표에 도달하기 위해 필요한 인슐린양보다 %1U의 인슐린 양이 초과 되었습니다. 탄수화물로 IOB를 커버하세요.' ,it: 'L\'eccesso d\'insulina equivalente %1U più che necessario per raggiungere l\'obiettivo basso, ASSICURARSI IOB SIA COPERTO DA CARBOIDRATI' ,tr: 'Fazla insülin: Alt KŞ hedefine ulaşmak için gerekenden %1 daha fazla insülin.IOB(Aktif İnsülin) Karbonhidrat tarafından karşılandığından emin olun.' ,zh_cn: '胰岛素超过至血糖下限目标所需剂量%1单位,确认IOB(活性胰岛素)被碳水化合物覆盖' @@ -11796,6 +11659,7 @@ function init() { ,ro: '%1U sunt în plus ca insulină activă pentru a atinge ținta inferioară, bazala este prea mare?' ,fr: 'Réduction d\'insuline active nécessaire pour atteindre la cible inférieure. Débit basal trop élevé ?' ,bg: '%1U намаляне е необходимо в активния инсулин до достигане до долната граница, прекалено висок базал?' + ,hr: 'Potrebno je smanjiti aktivni inzulin za %1U kako bi se dostigla donja ciljana granica, previše bazala? ' ,ru: 'Для достижения нижнего целевого значения необходимо понизить величину активного инсулина на %1U, велика база?' ,sv: '%1U minskning nödvändig i aktivt insulin för att nå lågt målvärde, för hög basal?' ,nb: '%1U reduksjon trengs i aktivt insulin for å nå lavt mål, for høy basal?' @@ -11804,6 +11668,7 @@ function init() { ,pt: 'Necessária redução de %1U na insulina ativa para atingir a meta inferior, excesso de basal?' ,nl: '%1U reductie vereist in actieve insuline om laag doel te bereiken, teveel basaal?' ,sk: 'Nutné zníženie aktívneho inzulínu o %1U pre dosiahnutie spodnej cieľovej hranice. Príliš veľa bazálu?' + ,ko: '낮은 혈당 목표에 도달하기 위해 활성 인슐린 양을 %1U 줄일 필요가 있습니다. basal양이 너무 많습니까?' ,it: 'Riduzione 1U% necessaria d\'insulina attiva per raggiungere l\'obiettivo basso, troppa basale?' ,tr: 'Alt KŞ hedefi için %1U aktif insülin azaltılmalı, bazal oranı çok mu yüksek?' ,zh_cn: '活性胰岛素已可至血糖下限目标,需减少%1单位,基础率过高?' @@ -11817,6 +11682,7 @@ function init() { ,ro: 'ajustarea bazalei duce în afara intervalului țintă. Suplimentați carbohirații?' ,fr: 'ajustement de débit basal hors de limites, prenez des glucides?' ,bg: 'Корекция на базала не е възможна, добавка на въглехидрати? ' + ,hr: 'prilagodba bazala je izvan raspona, dodati UGH?' ,ru: 'Корректировка базы вне диапазона, добавить углеводов?' ,sv: 'basaländring utanför gräns, ge kolhydrater?' ,es: 'ajuste basal fuera de rango, dar carbohidratos?' @@ -11824,6 +11690,7 @@ function init() { ,fi: 'säätö liian suuri, anna hiilihydraatteja?' ,pt: 'ajuste de basal fora da meta, dar carboidrato?' ,sk: 'úprava pomocou zmeny bazálu nie je možná. Podať sacharidy?' + ,ko: '적정 basal 양의 범위를 초과했습니다. 탄수화물 보충 하시겠습니까?' ,it: 'regolazione basale fuori campo, dare carboidrati?' ,nl: 'basaal aanpassing buiten bereik, geef KH?' ,tr: 'Bazal oran ayarlaması limit dışı, karbonhidrat alınsın mı?' @@ -11838,6 +11705,7 @@ function init() { ,ro: 'ajustarea bazalei duce în afara intervalului țintă. Suplimentați insulina?' ,fr: 'ajustement de débit basal hors de limites, prenez un bolus?' ,bg: 'Корекция на базала не е възможна, добавка на болус? ' + ,hr: 'prilagodna bazala je izvan raspona, dati bolus?' ,ru: 'Корректировка базы вне диапазона, добавить болюс?' ,sv: 'basaländring utanför gräns, ge bolus?' ,nb: 'basaljustering utenfor tillatt område, gi bolus?' @@ -11845,6 +11713,7 @@ function init() { ,es: 'Ajuste de basal fuera de rango, corregir con insulina?' ,pt: 'ajuste de basal fora da meta, dar bolus de correção?' ,sk: 'úprava pomocou zmeny bazálu nie je možná. Podať bolus?' + ,ko: '적정 basal 양의 범위를 초과했습니다. bolus를 추가하시겠습니까?' ,it: 'regolazione basale fuori campo, dare bolo?' ,nl: 'basaal aanpassing buiten bereik, bolus?' ,tr: 'Bazal oran ayarlaması limit dışı, bolus alınsın mı?' @@ -11860,12 +11729,14 @@ function init() { ,fr: 'plus haut que la limite supérieure' ,ru: 'Выше верхнего' ,bg: 'над горната' + ,hr: 'iznad gornje granice' ,sv: 'över hög nivå' ,nb: 'over høy grense' ,fi: 'yli korkean' ,pt: 'acima do limite superior' ,sk: 'nad horným' ,es: 'por encima límite superior' + ,ko: '고혈당 초과' ,it: 'sopra alto' ,nl: 'boven hoog' ,tr: 'üzerinde yüksek' @@ -11881,6 +11752,7 @@ function init() { ,ro: 'sub ținta inferioară' ,fr: 'plus bas que la limite inférieure' ,bg: 'под долната' + ,hr: 'ispod donje granice' ,ru: 'Ниже нижнего' ,sv: 'under låg nivå' ,nb: 'under lav grense' @@ -11888,6 +11760,7 @@ function init() { ,es: 'por debajo límite inferior' ,pt: 'abaixo do limite inferior' ,sk: 'pod spodným' + ,ko: '저혈당 미만' ,it: 'sotto bassa' ,nl: 'onder laag' ,tr: 'altında düşük' @@ -11903,12 +11776,14 @@ function init() { ,ro: 'Glicemie estimată %1 în țintă' ,fr: 'Glycémie cible projetée %1 ' ,bg: 'Предполагаемата КЗ %1 в граници' + ,hr: 'Procjena GUK %1 cilja' ,ru: 'Расчетная гликемия %1' ,sv: 'Önskat BS %1 mål' ,nb: 'Ønsket BS %1 mål' ,fi: 'Laskettu VS %1 tavoitteen' ,pt: 'Meta de glicemia estimada %1' ,sk: 'Predpokladaná glykémia %1 cieľ' + ,ko: '목표된 혈당 %1' ,it: 'Proiezione BG %1 obiettivo' ,es: 'Glucemia estimada %1 en objetivo' ,nl: 'Verwachte BG %1 doel' @@ -11925,12 +11800,14 @@ function init() { ,ro: 'ținta este' ,ru: 'цель на' ,bg: 'цел към' + ,hr: 'ciljano' ,sv: 'önskad utgång' ,nb: 'sikter på' ,fi: 'tavoitellaan' ,es: 'resultado deseado' ,pt: 'meta' ,sk: 'cieľom' + ,ko: '목표' ,it: 'puntare a' ,nl: 'doel is' ,tr: 'istenen sonuç' @@ -11945,6 +11822,7 @@ function init() { ,ro: 'Bolus de %1 unități' ,fr: 'Bolus %1 unités' ,bg: 'Болус %1 единици' + ,hr: 'Bolus %1 jedinica' ,ru: 'Болюс %1 единиц' ,sv: 'Bolus %1 enheter' ,nb: 'Bolus %1 enheter' @@ -11952,6 +11830,7 @@ function init() { ,pt: 'Bolus %1 unidades' ,es: 'Bolus %1 unidades' ,sk: 'Bolus %1 jednotiek' + ,ko: 'Bolus %1 단위' ,it: 'Bolo %1 unità' ,nl: 'Bolus %1 eenheden' ,tr: 'Bolus %1 Ünite' @@ -11966,6 +11845,7 @@ function init() { ,ro: 'sau ajustează bazala' ,fr: 'ou ajuster le débit basal' ,bg: 'или корекция на базала' + ,hr: 'ili prilagodba bazala' ,ru: 'или корректировать базу' ,sv: 'eller justera basal' ,nb: 'eller justere basal' @@ -11973,6 +11853,7 @@ function init() { ,pt: 'ou ajuste basal' ,es: 'o ajustar basal' ,sk: 'alebo úprava bazálu' + ,ko: '또는 조절 basal' ,it: 'o regolare basale' ,nl: 'of pas basaal aan' ,tr: 'ya da bazal ayarlama' @@ -11987,6 +11868,7 @@ function init() { ,ro: 'Verifică glicemia cu glucometrul înainte de a face o corecție!' ,fr: 'Vérifier la glycémie avec un glucomètre avant de corriger!' ,bg: 'Провери КЗ с глюкомер, преди кореция!' + ,hr: 'Provjeri GUK glukometrom prije korekcije!' ,ru: 'Перед корректировкой сверьте СК с глюкометром' ,sv: 'Kontrollera blodglukos med fingerstick före korrigering!' ,nb: 'Sjekk blodsukker før korrigering!' @@ -11994,6 +11876,7 @@ function init() { ,pt: 'Verifique glicemia de ponta de dedo antes de corrigir!' ,es: 'Verifique glucemia antes de corregir!' ,sk: 'Pred korekciou skontrolujte glykémiu glukometrom!' + ,ko: '수정하기 전에 혈당체크기를 사용하여 혈당을 체크하세요!' ,it: 'Controllare BG utilizzando glucometro prima di correggere!' ,nl: 'Controleer BG met bloeddruppel voor correctie!' ,zh_cn: '校正前请使用血糖仪测量血糖!' @@ -12008,6 +11891,7 @@ function init() { ,ro: 'Reducere bazală pentru a compensa %1 unități:' ,fr: 'Réduction du débit basal pour obtenir l\'effet d\' %1 unité' ,bg: 'Намаляне на базала с %1 единици' + ,hr: 'Smanjeni bazal da uračuna %1 jedinica:' ,ru: 'Снижение базы на %1 единиц' ,sv: 'Basalsänkning för att nå %1 enheter' ,nb: 'Basalredusering for å nå %1 enheter' @@ -12015,6 +11899,7 @@ function init() { ,pt: 'Redução de basal para compensar %1 unidades:' ,es: 'Reducir basal para compesar %1 unidades:' ,sk: 'Úprava bazálu pre výpočet %1 jednotiek:' + ,ko: '%1 단위로 계산하기 위해 Basal 감소' ,it: 'Riduzione basale per conto %1 unità:' ,nl: 'Basaal verlaagd voor %1 eenheden' ,zh_cn: '基础率减少到%1单位' @@ -12029,6 +11914,7 @@ function init() { ,ro: 'bazală temporară de 30 minute' ,fr: 'débit basal temporaire de 30 min' ,bg: '30м временен базал' + ,hr: '30m temp bazal' ,ru: '30 мин врем базал' ,sv: '30 minuters temporär basal' ,nb: '30 minutters midlertidig basal' @@ -12036,6 +11922,7 @@ function init() { ,pt: 'Basal temp 30m' ,es: '30 min. temporal basal' ,sk: '30 minutový dočasný bazál' + ,ko: '30분 임시 basal' ,it: '30m basale temp' ,nl: '30 minuten tijdelijke basaal' ,zh_cn: '30分钟临时基础率' @@ -12050,6 +11937,7 @@ function init() { ,ro: 'bazală temporară de 1 oră' ,fr: 'débit basal temporaire de 1 heure' ,bg: '1 час временен базал' + ,hr: '1h temp bazal' ,ru: '1 час врем базал' ,sv: '60 minuters temporär basal' ,nb: '60 minutters midlertidig basal' @@ -12057,6 +11945,7 @@ function init() { ,es: '1h temporal Basasl' ,pt: 'Basal temp 1h' ,sk: 'hodinový dočasný bazál' + ,ko: '1시간 임시 basal' ,it: '1h basale temp' ,nl: '1 uur tijdelijke basaal' ,zh_cn: '1小时临时基础率' @@ -12070,6 +11959,7 @@ function init() { ,dk: 'Tid for skift af Infusionssæt overskredet!' ,ro: 'Depășire termen schimbare canulă!' ,bg: 'Времето за смяна на сет просрочено' + ,hr: 'Prošao rok za zamjenu kanile!' ,fr: 'Dépassement de date de changement de canule!' ,ru: 'Срок работы катеттера истек' ,sv: 'Infusionsset, bytestid överskriden' @@ -12078,6 +11968,7 @@ function init() { ,pt: 'Substituição de catéter vencida!' ,es: '¡Cambio de agujas vencido!' ,sk: 'Výmena kanyli po lehote!' + ,ko: '주입세트(cannula) 기한이 지났습니다. 변경하세요!' ,it: 'Cambio Cannula in ritardo!' ,nl: 'Cannule te oud!' ,zh_cn: '超过更换管路的时间' @@ -12092,6 +11983,7 @@ function init() { ,fr: 'Le moment est venu de changer de canule' ,ro: 'Este vremea să schimbați canula' ,bg: 'Време за смяна на сет' + ,hr: 'Vrijeme za zamjenu kanile' ,ru: 'Пора заменить катеттер' ,sv: 'Dags att byta infusionsset' ,nb: 'På tide å bytte infusjonssett' @@ -12099,6 +11991,7 @@ function init() { ,es:' Hora sustituir cánula' ,pt: 'Hora de subistituir catéter' ,sk: 'Čas na výmenu kanyli' + ,ko: '주입세트(cannula)를 변경할 시간' ,it: 'Tempo di cambiare la cannula' ,nl: 'Verwissel canule' ,zh_cn: '已到更换管路的时间' @@ -12113,12 +12006,14 @@ function init() { ,ro: 'Schimbați canula în curând' ,fr: 'Changement de canule bientòt' ,bg: 'Смени сета скоро' + ,hr: 'Zamijena kanile uskoro' ,ru: 'Подходит время замены катеттера' ,sv: 'Byt infusionsset snart' ,nb: 'Bytt infusjonssett snart' ,fi: 'Vaihda kanyyli pian' ,pt: 'Substituir catéter em breve' ,sk: 'Čoskoro bude potrebné vymeniť kanylu' + ,ko: '주입세트(cannula)를 곧 변경하세요.' ,it: 'Cambio cannula prossimamente' ,nl: 'Verwissel canule binnenkort' ,zh_cn: '接近更换管路的时间' @@ -12133,6 +12028,7 @@ function init() { ,fr: 'âge de la canule %1 heures' ,ro: 'Vechimea canulei în ore: %1' ,bg: 'Сетът е на %1 часове' + ,hr: 'Staros kanile %1 sati' ,ru: 'Возраст катеттера %1 час' ,sv: 'Infusionsset tid %1 timmar' ,nb: 'infusjonssett alder %1 timer' @@ -12140,6 +12036,7 @@ function init() { ,pt: 'Idade do catéter %1 horas' ,es: 'Cánula usada %1 horas' ,sk: 'Vek kanyli %1 hodín' + ,ko: '주입세트(cannula) %1시간 사용' ,it: 'Durata Cannula %1 ore' ,nl: 'Canule leeftijd %1 uren' ,zh_cn: '管路已使用%1小时' @@ -12154,13 +12051,15 @@ function init() { ,ro: 'Inserat' ,fr: 'Insérée' ,bg: 'Поставен' + ,hr: 'Postavljanje' ,ru: 'Введено' ,sv: 'Applicerad' ,nb: 'Satt inn' ,fi: 'Asetettu' - ,es: 'Insertar' + ,es: 'Insertado' ,pt: 'Inserido' ,sk: 'Zavedený' + ,ko: '삽입된' ,it: 'Inserito' ,nl: 'Ingezet' ,zh_cn: '已植入' @@ -12176,14 +12075,16 @@ function init() { ,dk: 'Indstik alder' ,ro: 'VC' ,bg: 'ВС' + ,hr: 'Starost kanile' ,fr: 'CAGE' ,ru: 'ВозрКат' ,sv: 'Nål' ,nb: 'Nål alder' ,fi: 'KIKÄ' ,pt: 'ICAT' - ,es: 'Carb.desde' + ,es: 'Cánula desde' ,sk: 'SET' + ,ko: '주입세트사용기간' ,it: 'CAGE' ,nl: 'CAGE' ,zh_cn: '管路' @@ -12198,14 +12099,16 @@ function init() { ,dk: 'COB' ,ro: 'COB' ,bg: 'АВХ' + ,hr: 'Aktivni UGH' ,fr: 'COB' ,ru: 'Активн углеводы' ,sv: 'COB' ,nb: 'Aktive karbohydrater' ,fi: 'AH' ,pt: 'COB' - ,es: 'Carbohidratos activos' + ,es: 'Carb. activos' ,sk: 'SACH' + ,ko: 'COB' ,it: 'COB' ,nl: 'COB' ,zh_cn: '活性碳水COB' @@ -12220,6 +12123,7 @@ function init() { ,ro: 'Ultimii carbohidrați' ,fr: 'Derniers glucides' ,bg: 'Последни ВХ' + ,hr: 'Posljednji UGH' ,ru: 'Новые углеводы' ,sv: 'Senaste kolhydrater' ,nb: 'Siste karbohydrater' @@ -12227,6 +12131,7 @@ function init() { ,pt: 'Último carboidrato' ,es: 'último carbohidrato' ,sk: 'Posledné sacharidy' + ,ko: '마지막 탄수화물' ,it: 'Ultimi carboidrati' ,nl: 'Laatse KH' ,zh_cn: '上次碳水' @@ -12241,6 +12146,7 @@ function init() { ,ro: 'VI' ,fr: 'IAGE' ,bg: 'ВИнс' + ,hr: 'Starost inzulina' ,ru: 'ВозрИнс' ,sv: 'Insulinålder' ,nb: 'Insulinalder' @@ -12248,6 +12154,7 @@ function init() { ,pt: 'IddI' ,es: 'Insul.desde' ,sk: 'INZ' + ,ko: '인슐린사용기간' ,it: 'IAGE' ,nl: 'IAGE' ,zh_cn: '胰岛素' @@ -12263,6 +12170,7 @@ function init() { ,fr: 'Dépassement de date de changement de réservoir d\'insuline!' ,ro: 'Termenul de schimbare a rezervorului de insulină a fost depășit' ,bg: 'Смянатата на резервоара просрочена' + ,hr: 'Prošao rok za zamjenu spremnika!' ,ru: 'Срок замены резервуара инсулина истек' ,sv: 'Insulinbytestid överskriden' ,nb: 'Insulinbyttetid overskrevet' @@ -12270,6 +12178,7 @@ function init() { ,pt: 'Substituição de reservatório vencida!' ,es: 'Excedido plazo del cambio depósito de insulina!' ,sk: 'Čas na výmenu inzulínu po lehote!' + ,ko: '레저보(펌프 주사기)의 사용기한이 지났습니다. 변경하세요!' ,it: 'Cambio serbatoio d\'insulina in ritardo!' ,nl: 'Verwissel insulinereservoir nu!' ,zh_cn: '超过更换胰岛素储液器的时间' @@ -12284,6 +12193,7 @@ function init() { ,ro: 'Este timpul pentru schimbarea rezervorului de insulină' ,fr: 'Le moment est venu de changer de réservoir d\'insuline' ,bg: 'Време е за смяна на резервоара' + ,hr: 'Vrijeme za zamjenu spremnika' ,ru: 'Наступил срок замены резервуара инсулина' ,sv: 'Dags att byta insulinreservoar' ,nb: 'På tide å bytte insulinreservoar' @@ -12291,6 +12201,7 @@ function init() { ,pt: 'Hora de substituir reservatório' ,es: 'Hora de sustituir depósito insulina' ,sk: 'Čas na výmenu inzulínu' + ,ko: '레저보(펌프 주사기)를 변경할 시간' ,it: 'Momento di cambiare serbatoio d\'insulina' ,nl: 'Verwissel insuline reservoir' ,zh_cn: '已到更换胰岛素储液器的时间' @@ -12305,6 +12216,7 @@ function init() { ,ro: 'Rezervorul de insulină trebuie schimbat în curând' ,fr: 'Changement de réservoir d\'insuline bientôt' ,bg: 'Смени резервоара скоро' + ,hr: 'Zamjena spremnika uskoro' ,ru: 'Наступает срок замены резервуара инсулина' ,sv: 'Byt insulinreservoar snart' ,nb: 'Bytt insulinreservoar snart' @@ -12312,6 +12224,7 @@ function init() { ,pt: 'Substituir reservatório em brave' ,es: 'Sustituir depósito insulina en breve' ,sk: 'Čoskoro bude potrebné vymeniť inzulín' + ,ko: '레저보(펌프 주사기)안의 인슐린을 곧 변경하세요.' ,it: 'Cambiare serbatoio d\'insulina prossimamente' ,nl: 'Verwissel insuline reservoir binnenkort' ,zh_cn: '接近更换胰岛素储液器的时间' @@ -12327,12 +12240,14 @@ function init() { ,ro: 'Vârsta reservorului de insulină %1 ore' ,ru: 'Картридж инсулина отработал %1часов' ,bg: 'Резервоарът е на %1 часа' + ,hr: 'Spremnik zamijenjen prije %1 sati' ,sv: 'Insulinreservoarsålder %1 timmar' ,nb: 'Insulinreservoaralder %1 timer' ,fi: 'Insuliinisäiliön ikä %1 tuntia' ,pt: 'Idade do reservatório %1 horas' ,sk: 'Vek inzulínu %1 hodín' ,es: 'Depósito insulina desde %1 horas' + ,ko: '레저보(펌프 주사기) %1시간 사용' ,it: 'IAGE - Durata Serbatoio d\'insulina %1 ore' ,nl: 'Insuline reservoir leeftijd %1 uren' ,zh_cn: '胰岛素储液器已使用%1小时' @@ -12348,12 +12263,14 @@ function init() { ,ro: 'Schimbat' ,ru: 'Замена произведена' ,bg: 'Сменен' + ,hr: 'Promijenjeno' ,sv: 'Bytt' ,nb: 'Byttet' ,fi: 'Vaihdettu' ,pt: 'Substituído' ,es: 'Cambiado' ,sk: 'Vymenený' + ,ko: '변경됨' ,it: 'Cambiato' ,nl: 'veranderd' ,zh_cn: '已更换' @@ -12369,12 +12286,14 @@ function init() { ,ru: 'Активный Инсулин IOB' ,fr: 'IOB' ,bg: 'АИ' + ,hr: 'Aktivni inzulin' ,sv: 'IOB' ,nb: 'Aktivt insulin' ,es: 'Insulina Activa IOB' ,fi: 'IOB' ,pt: 'IOB' ,sk: 'IOB' + ,ko: 'IOB' ,it: 'IOB' ,nl: 'IOB' ,zh_cn: '活性胰岛素IOB' @@ -12390,12 +12309,14 @@ function init() { ,ru: 'Активн Инс на портале назначений' ,fr: 'Careportal IOB' ,bg: 'АИ от Кеърпортал' + ,hr: 'Careportal IOB' ,sv: 'IOB i Careportal' ,nb: 'Aktivt insulin i Careportal' ,fi: 'Careportal IOB' ,es: 'Insulina activa en Careportal' ,pt: 'IOB do Careportal' ,sk: 'IOB z portálu starostlivosti' + ,ko: '케어포털 IOB' ,it: 'IOB Somministrazioni' ,nl: 'Careportal IOB' ,zh_cn: '服务面板IOB(活性胰岛素)' @@ -12411,12 +12332,14 @@ function init() { ,ro: 'Ultimul bolus' ,ru: 'Прошлый болюс' ,bg: 'Последен болус' + ,hr: 'Prethodni bolus' ,sv: 'Senaste Bolus' ,nb: 'Siste Bolus' ,fi: 'Viimeisin bolus' ,pt: 'Último bolus' ,es: 'Último bolo' ,sk: 'Posledný bolus' + ,ko: '마지막 Bolus' ,it: 'Ultimo bolo' ,nl: 'Laatste bolus' ,zh_cn: '上次大剂量' @@ -12432,12 +12355,14 @@ function init() { ,ru: 'Активн Базал IOB' ,fr: 'IOB du débit basal' ,bg: 'Базален АИ' + ,hr: 'Bazalni aktivni inzulin' ,sv: 'Basal IOB' ,nb: 'Basal Aktivt Insulin' ,fi: 'Basaalin IOB' ,pt: 'IOB basal' ,es: 'Basal Insulina activa' ,sk: 'Bazálny IOB' + ,ko: 'Basal IOB' ,it: 'Basale IOB' ,nl: 'Basaal IOB' ,zh_cn: '基础率IOB(活性胰岛素)' @@ -12453,12 +12378,14 @@ function init() { ,fr: 'Source' ,ru: 'Источник' ,bg: 'Източник' + ,hr: 'Izvor' ,sv: 'Källa' ,nb: 'Kilde' ,fi: 'Lähde' ,pt: 'Fonte' ,es: 'Fuente' ,sk: 'Zdroj' + ,ko: '출처' ,it: 'Fonte' ,nl: 'bron' ,zh_cn: '来源' @@ -12474,12 +12401,14 @@ function init() { ,fr: 'Valeurs trop anciennes, vérifier l\'uploadeur' ,ru: 'Устаревшие данные, проверьте загрузчик' ,bg: 'Стари данни, провери телефона' + ,hr: 'Nedostaju podaci, provjera opreme?' ,es: 'Datos desactualizados, controlar la subida?' ,sv: 'Gammal data, kontrollera rigg?' ,nb: 'Gamle data, sjekk rigg?' ,fi: 'Tiedot vanhoja, tarkista lähetin?' ,pt: 'Dados antigos, verificar uploader?' ,sk: 'Zastaralé dáta, skontrolujte uploader' + ,ko: '오래된 데이터입니다. 확인해 보시겠습니까?' ,it: 'dati non aggiornati, controllare il telefono?' ,nl: 'Geen data, controleer uploader' ,zh_cn: '数据过期,检查一下设备?' @@ -12495,12 +12424,14 @@ function init() { ,ro: 'Ultimile date:' ,ru: 'Предыдущий полученный' ,bg: 'Последно получени' + ,hr: 'Zadnji podaci od:' ,sv: 'Senast mottagen:' ,nb: 'Sist mottatt:' ,fi: 'Viimeksi vastaanotettu:' ,pt: 'Último recebido:' ,es: 'Último recibido:' ,sk: 'Naposledy prijaté:' + ,ko: '마지막 수신' ,it: 'Ultime ricevute:' ,nl: 'laatste ontvangen' ,zh_cn: '上次接收:' @@ -12516,12 +12447,14 @@ function init() { ,fr: 'il y a %1 min' ,ru: 'мин назад' ,bg: 'преди %1 мин.' + ,hr: 'prije %1m' ,sv: '%1m sedan' ,nb: '%1m siden' ,fi: '%1m sitten' ,es: '%1min. atrás' ,pt: '%1m atrás' ,sk: 'pred %1m' + ,ko: '%1분 전' ,it: '%1m fa' ,nl: '%1m geleden' ,zh_cn: '%1分钟前' @@ -12537,12 +12470,14 @@ function init() { ,fr: '%1 heures plus tôt' ,ru: 'час назад' ,bg: 'преди %1 час' + ,hr: 'prije %1 sati' ,sv: '%1h sedan' ,nb: '%1h siden' ,fi: '%1h sitten' ,pt: '%1h atrás' ,es: '%1h. atrás' ,sk: 'pred %1h' + ,ko: '%1시간 전' ,it: '%1h fa' ,nl: '%1u geleden' ,zh_cn: '%1小时前' @@ -12558,12 +12493,14 @@ function init() { ,fr: '%1 jours plus tôt' ,ru: 'дн назад' ,bg: 'преди %1 ден' + ,hr: 'prije %1 dana' ,sv: '%1d sedan' ,nb: '%1d siden' ,fi: '%1d sitten' ,pt: '%1d atrás' ,es: '%1d atrás' ,sk: 'pred %1d' + ,ko: '%1일 전' ,it: '%1d fa' ,nl: '%1d geleden' ,zh_cn: '%1天前' @@ -12578,6 +12515,7 @@ function init() { ,ro: 'VECHI' ,ru: 'РЕТРО' ,bg: 'РЕТРО' + ,hr: 'RETRO' ,fr: 'RETRO' ,sv: 'RETRO' ,nb: 'GAMMELT' @@ -12585,6 +12523,7 @@ function init() { ,pt: 'RETRO' ,es: 'RETRO' ,sk: 'RETRO' + ,ko: 'RETRO' ,it: 'RETRO' ,nl: 'RETRO' ,zh_cn: '历史数据' @@ -12600,12 +12539,14 @@ function init() { ,ru: 'Сенсор проработал' ,fr: 'SAGE' ,bg: 'ВС' + ,hr: 'Starost senzora' ,sv: 'Sensor' ,nb: 'Sensoralder' ,fi: 'SIKÄ' ,pt: 'IddS' ,sk: 'SENZ' ,es: 'Sensor desde' + ,ko: '센서사용기간' ,it: 'SAGE' ,nl: 'SAGE' ,zh_cn: '探头' @@ -12622,12 +12563,14 @@ function init() { ,fr: 'Changement/Redémarrage du senseur dépassé!' ,ru: 'Рестарт сенсора просрочен' ,bg: 'Смяната/рестартът на сензора са пресрочени' + ,hr: 'Prošao rok za zamjenu/restart senzora!' ,sv: 'Sensor byte/omstart överskriden!' ,nb: 'Sensor bytte/omstart overskredet!' ,fi: 'Sensorin vaihto/uudelleenkäynnistys yli määräajan!' ,pt: 'Substituição/reinício de sensor vencido' ,es: 'Sustituir/reiniciar, sensor vencido' ,sk: 'Čas na výmenu/reštart sensoru uplynul!' + ,ko: '센서 사용기한이 지났습니다. 센서를 교체/재시작 하세요!' ,it: 'Cambio/riavvio del sensore in ritardo!' ,nl: 'Sensor vevang/hertstart tijd gepasseerd' ,zh_cn: '超过更换/重启探头的时间' @@ -12643,12 +12586,14 @@ function init() { ,ru: 'Время замены/рестарта сенсора' ,fr: 'C\'est le moment de changer/redémarrer le senseur' ,bg: 'Време за смяна/рестарт на сензора' + ,hr: 'Vrijeme za zamjenu/restart senzora' ,sv: 'Dags att byta/starta om sensorn' ,nb: 'På tide å bytte/restarte sensoren' ,fi: 'Aika vaihtaa / käynnistää sensori uudelleen' ,pt: 'Hora de substituir/reiniciar sensor' ,es: 'Hora de sustituir/reiniciar sensor' ,sk: 'Čas na výmenu/reštart senzoru' + ,ko: '센서 교체/재시작 시간' ,it: 'Tempo di cambiare/riavvio sensore' ,nl: 'Sensor vervangen of herstarten' ,zh_cn: '已到更换/重启探头的时间' @@ -12664,12 +12609,14 @@ function init() { ,fr: 'Changement/Redémarrage du senseur bientôt' ,ru: 'Приближается срок замены/рестарта сенсора' ,bg: 'Смени/рестартирай сензора скоро' + ,hr: 'Zamijena/restart senzora uskoro' ,sv: 'Byt/starta om sensorn snart' ,nb: 'Bytt/restarta sensoren snart' ,fi: 'Vaihda/käynnistä sensori uudelleen pian' ,pt: 'Mudar/reiniciar sensor em breve' ,es: 'Cambiar/Reiniciar sensor en breve' ,sk: 'Čoskoro bude potrebné vymeniť/reštartovať senzor' + ,ko: '센서를 곧 교체/재시작 하세요' ,it: 'Modifica/riavvio sensore prossimamente' ,nl: 'Herstart of vervang sensor binnenkort' ,zh_cn: '接近更换/重启探头的时间' @@ -12685,12 +12632,14 @@ function init() { ,fr: 'Âge su senseur %1 jours et %2 heures' ,ru: 'Сенсор проработал % дн % час' ,bg: 'Сензорът е на %1 дни %2 часа ' + ,hr: 'Starost senzora %1 dana i %2 sati' ,sv: 'Sensorålder %1 dagar %2 timmar' ,nb: 'Sensoralder %1 dag %2 timer' ,fi: 'Sensorin ikä %1 päivää, %2 tuntia' ,pt: 'Idade do sensor %1 dias %2 horas' ,es: 'Sensor desde %1 días %2 horas' ,sk: 'Vek senzoru %1 dní %2 hodín' + ,ko: '센서사용기간 %1일 %2시간' ,it: 'Durata Sensore %1 giorni %2 ore' ,nl: 'Sensor leeftijd %1 dag(en) en %2 uur' ,zh_cn: '探头使用了%1天%2小时' @@ -12706,12 +12655,14 @@ function init() { ,fr: 'Insertion du senseur' ,ru: 'Установка сенсора' ,bg: 'Поставяне на сензора' + ,hr: 'Postavljanje senzora' ,sv: 'Sensor insättning' ,nb: 'Sensor satt inn' ,fi: 'Sensorin Vaihto' ,es: 'Insertar sensor' ,pt: 'Inserção de sensor' ,sk: 'Výmena senzoru' + ,ko: '센서삽입' ,it: 'SAGE - inserimento sensore' ,nl: 'Sensor ingebracht' ,zh_cn: '植入探头' @@ -12727,12 +12678,14 @@ function init() { ,ru: 'Запуск сенсора' ,fr: 'Démarrage du senseur' ,bg: 'Стартиране на сензора' + ,hr: 'Pokretanje senzora' ,sv: 'Sensorstart' ,nb: 'Sensorstart' ,fi: 'Sensorin Aloitus' ,pt: 'Início de sensor' ,es: 'Inicio del sensor' ,sk: 'Štart senzoru' + ,ko: '센서시작' ,it: 'SAGE - partenza sensore' ,nl: 'Sensor start' ,zh_cn: '启动探头' @@ -12748,12 +12701,14 @@ function init() { ,fr: 'jours' ,ru: 'дн' ,bg: 'дни' + ,hr: 'dana' ,sv: 'dagar' ,nb: 'dager' ,fi: 'päivää' ,pt: 'dias' ,es: 'días' ,sk: 'dní' + ,ko: '일' ,it: 'giorni' ,nl: 'dagen' ,zh_cn: '天' @@ -12770,11 +12725,13 @@ function init() { ,ru: 'распределение инсулина' ,fi: 'Insuliinijakauma' ,sv: 'Insulindistribution' + ,ko: '인슐린주입' ,it: 'Distribuzione di insulina' ,es: 'Distribución de la insulina' ,nl: 'Insuline verdeling' ,zh_cn: '胰岛素分布' ,bg: 'разпределение на инсулина' + ,hr: 'Raspodjela inzulina' ,pl: 'podawanie insuliny' ,tr: 'İnsülin dağılımı' } @@ -12787,12 +12744,14 @@ function init() { ,ro: 'Pentru a vedea acest raport, apăsați butonul SHOW' ,ru: 'чтобы увидеть отчет, нажмите show/показать' ,fi: 'Nähdäksesi tämän raportin, paina NÄYTÄ tässä näkymässä' + ,ko: '이 보고서를 보려면 "확인"을 누르세요' ,it: 'Per guardare questo report, premere SHOW all\'interno della finestra' ,es: 'Presione SHOW para mostrar el informe en esta vista' ,nl: 'Om dit rapport te zien, druk op "Laat zien"' ,zh_cn: '要查看此报告,请在此视图中按生成' ,sv: 'För att se denna rapport, klicka på "Visa"' ,bg: 'За да видите тази статистика, натиснете ПОКАЖИ' + ,hr: 'Za prikaz ovog izvješća, pritisnite PRIKAŽI na ovom prozoru' , pl: 'Aby wyświetlić ten raport, naciśnij przycisk POKAŻ w tym widoku' ,tr: 'Bu raporu görmek için bu görünümde GÖSTER düğmesine basın.' } @@ -12806,11 +12765,13 @@ function init() { ,ru: 'прогноз AR2' ,es: 'Pronóstico AR2' ,fi: 'AR2 Ennusteet' + ,ko: 'AR2 예측' ,it: 'Previsione AR2' ,nl: 'AR2 Voorspelling' ,zh_cn: 'AR2 预测' ,sv: 'AR2 Förutsägelse' ,bg: 'AR2 прогнози' + ,hr: 'AR2 procjena' ,pl: 'Prognoza AR2' ,tr: 'AR2 Tahmini' } @@ -12824,11 +12785,13 @@ function init() { ,ru: 'прогнозы OpenAPS' ,es: 'Pronóstico OpenAPS' ,fi: 'OpenAPS Ennusteet' + ,ko: 'OpenAPS 예측' ,it: 'Previsione OpenAPS' ,nl: 'OpenAPS Voorspelling' ,zh_cn: 'OpenAPS 预测' ,sv: 'OpenAPS Förutsägelse' ,bg: 'OpenAPS прогнози' + ,hr: 'OpenAPS prognoze' ,pl: 'Prognoza OpenAPS' ,tr: 'OpenAPS Tahminleri' } @@ -12842,11 +12805,13 @@ function init() { ,ru: 'промежуточная цель' ,fi: 'Tilapäinen tavoite' ,es: 'Objetivo temporal' + ,ko: '임시목표' ,it: 'Obbiettivo temporaneo' ,nl: 'Tijdelijk doel' ,zh_cn: '临时目标' ,sv: 'Tillfälligt mål' ,bg: 'временна цел' + ,hr: 'Privremeni cilj' ,pl: 'Cel tymczasowy' ,tr: 'Geçici Hedef' } @@ -12860,11 +12825,13 @@ function init() { ,ru: 'отмена промежуточной цели' ,fi: 'Peruuta tilapäinen tavoite' ,es: 'Objetivo temporal cancelado' + ,ko: '임시목표취소' ,it: 'Obbiettivo temporaneo cancellato' ,nl: 'Annuleer tijdelijk doel' ,zh_cn: '临时目标取消' ,sv: 'Avsluta tillfälligt mål' ,bg: 'Отмяна на временна цел' + ,hr: 'Otkaz privremenog cilja' ,pl: 'Zel tymczasowy anulowany' ,tr: 'Geçici Hedef İptal' } @@ -12877,12 +12844,14 @@ function init() { ,fr: 'OpenAPS déconnecté' ,ru: 'OpenAPS вне сети' ,fi: 'OpenAPS poissa verkosta' + ,ko: 'OpenAPS Offline' ,it: 'OpenAPS disconnesso' ,es: 'OpenAPS desconectado' ,nl: 'OpenAPS Offline' ,zh_cn: 'OpenAPS 离线' ,sv: 'OpenAPS Offline' ,bg: 'OpenAPS спрян' + ,hr: 'OpenAPS odspojen' ,pl: 'OpenAPS nieaktywny' ,tr: 'OpenAPS Offline (çevrimdışı)' } @@ -12895,12 +12864,14 @@ function init() { ,ro: 'Profile' ,ru: 'профили' ,fi: 'Profiilit' + ,ko: '프로파일' ,it: 'Profili' ,es: 'Perfil' ,nl: 'Profielen' ,zh_cn: '配置文件' ,sv: 'Profiler' ,bg: 'Профили' + ,hr: 'Profili' ,pl: 'Profile' ,tr: 'Profiller' } @@ -12909,6 +12880,7 @@ function init() { ,he: 'זמן בתנודות ' ,fi: 'Aika muutoksessa' ,fr: 'Temps passé en fluctuation' + ,ko: '변동시간' ,it: 'Tempo in fluttuazione' ,ro: 'Timp în fluctuație' ,es: 'Tiempo fluctuando' @@ -12919,6 +12891,7 @@ function init() { ,de: 'Zeit in Fluktuation (Schwankung)' ,dk: 'Tid i fluktation' ,bg: 'Време в промяна' + ,hr: 'Vrijeme u fluktuaciji' ,pl: 'Czas fluaktacji (odchyleń)' ,tr: 'Dalgalanmada geçen süre' } @@ -12927,6 +12900,7 @@ function init() { ,he: 'זמן בתנודות מהירות ' ,fi: 'Aika nopeassa muutoksessa' ,fr: 'Temps passé en fluctuation rapide' + ,ko: '빠른변동시간' ,it: 'Tempo in rapida fluttuazione' ,ro: 'Timp în fluctuație rapidă' ,es: 'Tiempo fluctuando rápido' @@ -12937,6 +12911,7 @@ function init() { ,de: 'Zeit in starker Fluktuation (Schwankung)' ,dk: 'Tid i hurtig fluktation' ,bg: 'Време в бърза промяна' + ,hr: 'Vrijeme u brzoj fluktuaciji' ,pl: 'Czas szybkich fluaktacji (odchyleń)' ,tr: 'Hızlı dalgalanmalarda geçen süre' } @@ -12945,6 +12920,7 @@ function init() { ,he: 'זוהי רק הערכה גסה שיכולה להיות מאוד לא מדויקת ואינה מחליפה את בדיקת הדם בפועל. הנוסחה המשמשת נלקחת מ: ' ,fi: 'Tämä on epätarkka arvio joka saattaa heittää huomattavasti mittaustuloksesta, eikä korvaa laboratoriotestiä. Laskentakaava on otettu artikkelista: ' ,fr: 'Ceci est seulement une estimation grossière qui peut être très imprécise et ne remplace pas une mesure sanguine adéquate. La formule est empruntée à l\'article:' + ,ko: '이것은 대충 예측한 것이기 때문에 부정확할 수 있고 실제 혈당으로 대체되지 않습니다. 사용된 공식:' ,it: 'Questa è solo un\'approssimazione che può essere molto inaccurata e che non sostituisce la misurazione capillare. La formula usata è presa da:' ,ro: 'Aceasta este doar o aproximare brută, care poate fi foarte imprecisă și nu ține loc de testare capilară. Formula matematică folosită este luată din:' ,es: 'Esto es sólo una estimación apróximada que puede ser muy inexacta y no reemplaza las pruebas de sangre reales. La fórmula utilizada está tomada de: ' @@ -12955,12 +12931,14 @@ function init() { ,de: 'Dies ist lediglich eine grobe Schätzung, die sehr ungenau sein kann und eine Überprüfung des tatsächlichen Blutzuckers nicht ersetzen kann. Die verwendete Formel wurde genommen von:' ,dk: 'Dette er kun en grov estimering som kan være misvisende. Det erstatter ikke en blodprøve. Formelen er hemtet fra:' ,bg: 'Това е само грубо изчисление, което може да е много неточно и не изключва реалния кръвен тест. Формулата, кокято е използвана е взета от:' + ,hr: 'Ovo je samo gruba procjena koja može biti neprecizna i ne mijenja testiranje iz krvi. Formula je uzeta iz:' ,pl: 'To tylko przybliżona ocena, która może być bardzo niedokładna i nie może zastąpić faktycznego poziomu cukru we krwi. Zastosowano formułę:' ,tr: 'Bu bir kaba tahmindir ve çok hata içerebilir gerçek kan şekeri testlerinin yerini tutmayacaktır. Kullanılan formülde buradandır:' } , 'Filter by hours' : { cs: ' Filtr podle hodin' ,fi: 'Huomioi raportissa seuraavat tunnit' + ,ko: '시간으로 정렬' ,it: 'Filtra per ore' ,fr: 'Filtrer par heures' ,ro: 'Filtrare pe ore' @@ -12972,6 +12950,7 @@ function init() { ,de: 'Filtern nach Stunden' ,dk: 'Filtrer per time' ,bg: 'Филтър по часове' + ,hr: 'Filter po satima' ,pl: 'Filtruj po godzinach' ,tr: 'Saatlere göre filtrele' } @@ -12979,6 +12958,7 @@ function init() { cs: 'Doba měnící se glykémie a rapidně se měnící glykémie měří % času ve zkoumaném období, během kterého se glykémie měnila relativně rychle nebo rapidně. Nižší hodnota je lepší.' ,fi: 'Aika Muutoksessa ja Aika Nopeassa Muutoksessa mittaa osuutta tarkkailtavasta aikaperiodista, jolloin glukoosi on ollut nopeassa tai hyvin nopeassa muutoksessa. Pienempi arvo on parempi.' ,fr: 'Le Temps passé en fluctuation et le temps passé en fluctuation rapide mesurent la part de temps durant la période examinée, pendant laquelle la glycémie a évolué relativement ou très rapidement. Les valeurs basses sont les meilleures.' + ,ko: '변동시간과 빠른 변동시간은 조사된 기간 동안 %의 시간으로 측정되었습니다.혈당은 비교적 빠르게 변화되었습니다. 낮을수록 좋습니다.' ,it: 'Tempo in fluttuazione e Tempo in rapida fluttuazione misurano la % di tempo durante il periodo esaminato, durante il quale la glicemia stà variando velocemente o rapidamente. Bassi valori sono migliori.' ,ro: 'Timpul în fluctuație și timpul în fluctuație rapidă măsoară procentul de timp, din perioada examinată, în care glicemia din sânge a avut o variație relativ rapidă sau rapidă. Valorile mici sunt de preferat.' ,es: 'Tiempo en fluctuación y Tiempo en fluctuación rápida miden el % de tiempo del período exáminado, durante la cual la glucosa en sangre ha estado cambiando relativamente rápido o rápidamente. Valores más bajos son mejores.' @@ -12989,6 +12969,7 @@ function init() { ,de: 'Zeit in Fluktuation und Zeit in starker Fluktuation messen den Teil der Zeit, in der sich der Blutzuckerwert relativ oder sehr schnell verändert hat. Niedrigere Werte sind besser.' ,dk: 'Tid i fluktuation og tid i hurtig fluktuation måler % af tiden i den undersøgte periode, under vilket blodsukkret har ændret sig relativt hurtigt. Lavere værdier er bedre.' ,bg: 'Време в промяна и време в бърза промяна измерват % от време в разгледания период, през който КЗ са се променяли бързо или много бързо. По-ниски стойности са по-добри.' + ,hr: 'Vrijeme u fluktuaciji i vrijeme u brzoj fluktuaciji mjere % vremena u gledanom periodu, tijekom kojeg se GUK mijenja relativno brzo ili brzo. Niže vrijednosti su bolje.' ,pl: 'Czas fluktuacji i szybki czas fluktuacji mierzą % czasu w badanym okresie, w którym poziom glukozy we krwi zmieniał się szybko lub bardzo szybko. Preferowane są wolniejsze zmiany' ,tr: 'Dalgalanmadaki zaman ve Hızlı dalgalanmadaki zaman, kan şekerinin nispeten hızlı veya çok hızlı bir şekilde değiştiği, incelenen dönemdeki zamanın %\'sini ölçer. Düşük değerler daha iyidir.' } @@ -12996,6 +12977,7 @@ function init() { cs: 'Průměrná celková denní změna je součet absolutních hodnoty všech glykémií za sledované období, děleno počtem dní. Nižší hodnota je lepší.' ,fi: 'Keskimääräinen Kokonaismuutos kertoo kerkimääräisen päivätason verensokerimuutoksien yhteenlasketun arvon. Pienempi arvo on parempi.' ,fr: 'La Variation Totale Journalière Moyenne est la somme de toute les excursions glycémiques absolues pour une période analysée, divisée par le nombre de jours. Les valeurs basses sont les meilleures.' + ,ko: '전체 일일 변동 평균은 조사된 기간동안 전체 혈당 절대값의 합을 전체 일수로 나눈 값입니다. 낮을수록 좋습니다.' ,it: 'Media Totale Giornaliera Variazioni è la somma dei valori assoluti di tutte le escursioni glicemiche per il periodo esaminato, diviso per il numero di giorni. Bassi valori sono migliori.' ,ro: 'Schimbarea medie totală zilnică este suma valorilor absolute ale tuturor excursiilor glicemice din perioada examinată, împărțite la numărul de zile. Valorile mici sunt de preferat.' ,ru: 'усредненное ежедневное изменение это сумма абсолютных величин всех отклонений СК в рассматриваемый период, деленное на количество дней. Меньшая величина предпочтительней' @@ -13006,6 +12988,7 @@ function init() { ,de: 'Die gesamte mittlere Änderung pro Tag ist die Summe der absoluten Werte aller Glukoseveränderungen im Betrachtungszeitraum geteilt durch die Anzahl der Tage. Niedrigere Werte sind besser.' ,dk: 'Middel Total Daglig Ændring er summen af absolutværdier af alla glukoseændringer i den undersøgte periode, divideret med antallet af dage. Lavere er bedre.' ,bg: 'Средната дневна промяна е сумата на всички промени в стойностите на КЗ за разгледания период, разделена на броя дни в периода. По-ниската стойност е по-добра' + ,hr: 'Srednja ukupna dnevna promjena je suma apsolutnih vrijednosti svih pomaka u gledanom periodu, podijeljeno s brojem dana. Niže vrijednosti su bolje.' ,pl: 'Sednia całkowita dziennych zmian jest sumą wszystkich zmian glikemii w badanym okresie, podzielonym przez liczbę dni. Mniejsze są lepsze' ,tr: 'Toplam Günlük Değişim, incelenen süre için, gün sayısına bölünen tüm glukoz değerlerinin mutlak değerinin toplamıdır. Düşük değer daha iyidir.' } @@ -13013,6 +12996,7 @@ function init() { cs: 'Průměrná hodinová změna je součet absolutní hodnoty všech glykémií za sledované období, dělených počtem hodin v daném období. Nižší hodnota je lepší.' ,fi: 'Keskimääräinen tunti kertoo keskimääräisen tuntitason verensokerimuutoksien yhteenlasketun arvon. Pienempi arvo on parempi.' ,fr: 'La Variation Horaire Moyenne est la somme de toute les excursions glycémiques absolues pour une période analysée, divisée par le nombre d\'heures dans la période. Les valeures basses sont les meilleures.' + ,ko: '시간당 변동 평균은 조사된 기간 동안 전체 혈당 절대값의 합을 기간의 시간으로 나눈 값입니다.낮을수록 좋습니다.' ,it: 'Media Oraria Variazioni è la somma del valore assoluto di tutte le escursioni glicemiche per il periodo esaminato, diviso per il numero di ore. Bassi valori sono migliori.' ,ro: 'Variația media orară este suma valorilor absolute ale tuturor excursiilor glicemice din perioada examinată, împărțite la numărul de ore din aceeași perioadă. Valorile mici sunt de preferat.' ,ru: 'усредненное часовое изменение это сумма абсолютных величин всех отклонений СК в рассматриваемый период, деленное на количество часов в этот период. Более низкое предпочтительней' @@ -13023,13 +13007,15 @@ function init() { ,de: 'Die mittlere Änderung pro Stunde ist die Summe der absoluten Werte aller Glukoseveränderungen im Betrachtungszeitraum geteilt durch die Anzahl der Stunden. Niedrigere Werte sind besser.' ,dk: 'Middelværdier per time er summen af absolutværdier fra alle glukoseændringer i den undersøgte periode divideret med antallet af timer. Lavere er bedre.' ,bg: 'Средната промяна за час е сумата на всички промени в стойностите на КЗ за разгледания период, разделена на броя часове в периода. По-ниската стойност е по-добра' + ,hr: 'Srednja ukupna promjena po satu je suma apsolutnih vrijednosti svih pomaka u gledanom periodu, podijeljeno s brojem sati. Niže vrijednosti su bolje.' ,pl: 'Sednia całkowita godzinnych zmian jest sumą wszystkich zmian glikemii w badanym okresie, podzielonym przez liczbę godzin. Mniejsze są lepsze' ,tr: 'Saat başına ortalama değişim, gözlem periyodu üzerindeki tüm glikoz değişikliklerinin mutlak değerlerinin saat sayısına bölünmesiyle elde edilen toplam değerdir. Düşük değerler daha iyidir.' } - , 'GVI (Glycemic Variability Index) and PGS (Patient Glycemic Status) are measures developed by Dexcom, detailed can be found here.' : { + , '">can be found here.' : { cs: '">zde.' ,he: '">here.' ,fi: '">here.' + ,ko: '">here.' ,it: '">qui.' ,es: '">here.' ,fr: '">ici.' @@ -13059,6 +13047,7 @@ function init() { ,de: '">hier.' ,dk: '">her.' ,bg: '">тук.' + ,hr: '">ovdje.' ,pl: '">tutaj.' ,tr: '">buradan.' } @@ -13067,16 +13056,18 @@ function init() { ,he: 'שינוי יומי ממוצע ' ,fi: 'Keskimääräinen Kokonaismuutos' ,fr: 'Variation Totale Journalière Moyenne' + ,ko: '전체 일일 변동 평균' ,it: 'Media Totale Giornaliera Variazioni' ,ro: 'Variația medie totală zilnică' ,ru: 'усредненное изменение за день' ,es: 'Variación media total diaria' ,nl: 'Gemiddelde veranderingen per dag' - ,zh_cn: '平均每日总变化' + ,zh_cn: '平均每日总变化' ,sv: 'Medel Total Daglig Förändring' ,de: 'Gesamte mittlere Änderung pro Tag' ,dk: 'Middel Total Daglig Ændring' ,bg: 'Средна промяна за ден' + ,hr: 'Srednja ukupna dnevna promjena' ,pl: 'Średnia całkowita dziennych zmian' ,tr: 'Günde toplam ortalama değişim' } @@ -13085,16 +13076,18 @@ function init() { ,he: 'שינוי ממוצע לשעה ' ,fi: 'Keskimääräinen tuntimuutos' ,fr: 'Variation Horaire Moyenne' + ,ko: '시간당 변동 평균' ,it: 'Media Oraria Variazioni' ,ro: 'Variația medie orară' ,es: 'Variación media total por horas' ,ru: 'усредненное изменение за час' ,nl: 'Gemiddelde veranderingen per uur' - ,zh_cn: '平均每小时变化' + ,zh_cn: '平均每小时变化' ,sv: 'Medelvärde per timme' ,de: 'Mittlere Änderung pro Stunde' ,dk: 'Middelværdier per time' ,bg: 'Средна промяна за час' + ,hr: 'Srednja ukupna promjena po satu' ,pl: 'Średnia całkowita godzinnych zmian' ,tr: 'Saatte ortalama değişim' } @@ -13109,9 +13102,9 @@ function init() { , fi: 'laskee hitaasti' , fr: 'en chute lente' , he: 'slightly dropping' - , hr: 'slightly dropping' - , it: 'leggera diminuzione' + , hr: 'sporo padajuće' , ko: 'slightly dropping' + , it: 'leggera diminuzione' , nb: 'svakt fallende' , pl: 'niewielki spadek' , pt: 'slightly dropping' @@ -13123,7 +13116,7 @@ function init() { , tr: 'biraz düşen' , zh_cn: '缓慢下降' , zh_tw: 'slightly dropping' - + }, 'FortyFiveUp': { bg: 'slightly rising' @@ -13136,7 +13129,7 @@ function init() { , fi: 'nousee hitaasti' , fr: 'en montée lente' , he: 'slightly rising' - , hr: 'slightly rising' + , hr: 'sporo rastuće' , it: 'leggero aumento' , ko: 'slightly rising' , nb: 'svakt stigende' @@ -13162,7 +13155,7 @@ function init() { , fi: 'tasainen' , fr: 'stable' , he: 'holding' - , hr: 'holding' + , hr: 'ravno' , it: 'stabile' , ko: 'holding' , nb: 'stabilt' @@ -13188,7 +13181,7 @@ function init() { , fi: 'nousussa' , fr: 'en montée' , he: 'rising' - , hr: 'rising' + , hr: 'rastuće' , it: 'aumento' , ko: 'rising' , nb: 'stigende' @@ -13214,7 +13207,7 @@ function init() { , fi: 'laskussa' , fr: 'en chute' , he: 'dropping' - , hr: 'dropping' + , hr: 'padajuće' , it: 'diminuzione' , ko: 'dropping' , nb: 'fallende' @@ -13240,7 +13233,7 @@ function init() { , fi: 'laskee nopeasti' , fr: 'en chute rapide' , he: 'rapidly dropping' - , hr: 'rapidly dropping' + , hr: 'brzo padajuće' , it: 'rapida diminuzione' , ko: 'rapidly dropping' , nb: 'hurtig stigende' @@ -13266,7 +13259,7 @@ function init() { , fi: 'nousee nopeasti' , fr: 'en montée rapide' , he: 'rapidly rising' - , hr: 'rapidly rising' + , hr: 'brzo rastuće' , it: 'rapido aumento' , ko: 'rapidly rising' , nb: 'hurtig fallende' @@ -13519,8 +13512,10 @@ function init() { bg: 'Your uploader battery is at %1' ,cs: 'Baterie mobilu má %1' , en: 'Your uploader battery is at %1' + , hr: 'Your uploader battery is at %1' , de: 'Der Akku deines Uploader Handys ist bei %1' , dk: 'Din uploaders batteri er %1' + , ko: 'Your uploader battery is at %1' , nl: 'De batterij van je mobiel is bij %l' ,zh_cn: '你的手机电池电量是 %1 ' , sv: 'Din uppladdares batteri är %1' @@ -13534,8 +13529,10 @@ function init() { bg: 'You have %1 units remaining' , cs: 'V zásobníku zbývá %1 jednotek' , en: 'You have %1 units remaining' + , hr: 'You have %1 units remaining' , de: 'Du hast %1 Einheiten übrig' , dk: 'Du har %1 enheder tilbage' + , ko: 'You have %1 units remaining' , nl: 'Je hebt nog %l eenheden in je reservoir' ,zh_cn: '你剩余%1 U的胰岛素' , sv: 'Du har %1 enheter kvar' @@ -13549,8 +13546,10 @@ function init() { bg: 'Your pump battery is at %1 %2' , cs: 'Baterie v pumpě má %1 %2' , en: 'Your pump battery is at %1 %2' + , hr: 'Your pump battery is at %1 %2' , de: 'Der Batteriestand deiner Pumpe ist bei %1 %2' , dk: 'Din pumpes batteri er %1 %2' + , ko: 'Your pump battery is at %1 %2' , nl: 'Je pomp batterij is bij %1 %2' ,zh_cn: '你的泵电池电量是%1 %2' , sv: 'Din pumps batteri är %1 %2' @@ -13564,8 +13563,10 @@ function init() { bg: 'The last successful loop was %1' , cs: 'Poslední úšpěšné provedení smyčky %1' , en: 'The last successful loop was %1' + , hr: 'The last successful loop was %1' , de: 'Der letzte erfolgreiche Loop war %1' , dk: 'Seneste successfulde loop var %1' + , ko: 'The last successful loop was %1' , nl: 'De meest recente goede loop was %1' ,zh_cn: '最后一次成功闭环的是在%1' , sv: 'Senaste lyckade loop var %1' @@ -13579,8 +13580,10 @@ function init() { bg: 'Loop plugin does not seem to be enabled' , cs: 'Plugin smyčka není patrně povolený' , en: 'Loop plugin does not seem to be enabled' + , hr: 'Loop plugin does not seem to be enabled' , de: 'Das Loop Plugin scheint nicht aktiviert zu sein' , dk: 'Loop plugin lader ikke til at være slået til' + , ko: 'Loop plugin does not seem to be enabled' , nl: 'De Loop plugin is niet geactiveerd' ,zh_cn: 'Loop插件看起来没有被启用' , sv: 'Loop plugin verkar inte vara aktiverad' @@ -13594,23 +13597,27 @@ function init() { bg: 'According to the loop forecast you are expected to be %1 over the next %2' , cs: 'Podle přepovědi smyčky je očekávána glykémie %1 během následujících %2' , en: 'According to the loop forecast you are expected to be %1 over the next %2' + , hr: 'According to the loop forecast you are expected to be %1 over the next %2' , de: 'Entsprechend der Loop Vorhersage landest du bei %1 während der nächsten %2' , dk: 'Ifølge Loops forudsigelse forventes du at blive %1 i den næste %2' + , ko: 'According to the loop forecast you are expected to be %1 over the next %2' , nl: 'Volgens de Loop voorspelling is je waarde %1 over de volgnede %2' ,zh_cn: '根据loop的预测,在接下来的%2你的血糖将会是%1' , sv: 'Enligt Loops förutsägelse förväntas du bli %1 inom %2' , fi: 'Ennusteen mukaan olet %1 seuraavan %2 ajan' , ro: 'Potrivit previziunii date de loop se estiemază %1 pentru următoarele %2' , pl: 'Zgodnie z prognozą pętli, glikemia %1 będzie podczas następnego %2' - , ru: 'по прогнозу алгоритма ЗЦ ожидается $1 за последующие %2' + , ru: 'по прогнозу алгоритма ЗЦ ожидается %1 за последующие %2' , tr: 'Döngü tahminine göre sonraki %2 ye göre %1 olması bekleniyor' }, 'alexaForecastUnavailable': { bg: 'Unable to forecast with the data that is available' , cs: 'S dostupnými daty přepověď není možná' , en: 'Unable to forecast with the data that is available' + , hr: 'Unable to forecast with the data that is available' , de: 'Mit den verfügbaren Daten ist eine Loop Vorhersage nicht möglich' , dk: 'Det er ikke muligt at forudsige md de tilgængelige data' + , ko: 'Unable to forecast with the data that is available' , nl: 'Niet mogelijk om een voorspelling te doen met de data die beschikbaar is' ,zh_cn: '血糖数据不可用,无法预测未来走势' , sv: 'Förutsägelse ej möjlig med tillgänlig data' @@ -13625,14 +13632,16 @@ function init() { , cs: 'Raw glykémie je %1' , de: 'Dein Rohblutzucker ist %1' , dk: 'Dit raw blodsukker er %1' + , ko: 'Your raw bg is %1' , nl: 'Je raw bloedwaarde is %1' ,zh_cn: '你的血糖是 %1' , sv: 'Ditt raw blodsocker är %1' , fi: 'Suodattamaton verensokeriarvo on %1' , ro: 'Glicemia brută este %1' , bg: 'Your raw bg is %1' + , hr: 'Your raw bg is %1' , pl: 'Glikemia RAW wynosi %1' - , ru: 'ваши необработанные данные RAW $1' + , ru: 'ваши необработанные данные RAW %1' , tr: 'Ham kan şekeriniz %1' }, 'alexaOpenAPSForecast': { @@ -13640,12 +13649,14 @@ function init() { , cs: 'OpenAPS Eventual BG je %1' , de: 'Der von OpenAPS vorhergesagte Blutzucker ist %1' , dk: 'OpenAPS forventet blodsukker er %1' + , ko: 'The OpenAPS Eventual BG is %1' , nl: 'OpenAPS uiteindelijke bloedglucose van %1' ,zh_cn: 'OpenAPS 预测最终血糖是 %1' , sv: 'OpenAPS slutgiltigt blodsocker är %1' , fi: 'OpenAPS verensokeriarvio on %1' , ro: 'Glicemia estimată de OpenAPS este %1' ,bg: 'The OpenAPS Eventual BG is %1' + ,hr: 'The OpenAPS Eventual BG is %1' , pl: 'Glikemia prognozowana przez OpenAPS wynosi %1' , ru: 'OpenAPS прогнозирует ваш СК как %1 ' , tr: 'OpenAPS tarafından tahmin edilen kan şekeri %1' @@ -13655,12 +13666,14 @@ function init() { , cs: '%1 %2 aktivních sachridů' , de: '%1 %2 Gramm Kohlenhydrate wirkend.' , dk: '%1 %2 gram aktive kulhydrater' + , ko: '%1 %2 carbohydrates on board' , nl: '%1 %2 actieve koolhydraten' ,zh_cn: '%1 %2 活性碳水化合物' , sv: '%1 %2 gram aktiva kolhydrater' , fi: '%1 %2 aktiivista hiilihydraattia' , ro: '%1 %2 carbohidrați activi în corp' ,bg: '%1 %2 carbohydrates on board' + ,hr: '%1 %2 carbohydrates on board' , pl: '%1 %2 aktywnych węglowodanów' , ru: '%1 $2 активных углеводов' , tr: '%1 %2 aktif karbonhidrat' @@ -13672,6 +13685,7 @@ function init() { ,es: 'Grasas [g]' ,fi: 'Rasva [g]' ,fr: 'Graisses [g]' + ,ko: 'Fat [g]' ,nl: 'Vet [g]' ,zh_cn: '脂肪[g]' ,ro: 'Grăsimi [g]' @@ -13679,6 +13693,7 @@ function init() { ,it: 'Grassi [g]' ,sv: 'Fett [g]' ,bg: 'Мазнини [гр]' + ,hr: 'Masnoće [g]' ,pl: 'Tłuszcz [g]' ,tr: 'Yağ [g]' }, @@ -13689,6 +13704,7 @@ function init() { ,es: 'Proteina [g]' ,fi: 'Proteiini [g]' ,fr: 'Protéines [g]' + ,ko: 'Protein [g]' ,nl: 'Proteine [g]' ,zh_cn: '蛋白质[g]' ,ro: 'Proteine [g]' @@ -13696,6 +13712,7 @@ function init() { ,it: 'Proteine [g]' ,sv: 'Protein [g]' ,bg: 'Протеини [гр]' + ,hr: 'Proteini [g]' ,pl: 'Białko [g]' ,tr: 'Protein [g]' }, @@ -13709,16 +13726,19 @@ function init() { ,ro: 'Energie [g]' ,ru: 'энергия [kJ' ,it: 'Energia [kJ]' - ,zh_cn: '能量 [kJ]' + ,zh_cn: '能量 [kJ]' + ,ko: 'Energy [kJ]' ,nl: 'Energie [kJ]' ,sv: 'Energi [kJ]' ,bg: 'Енергия [kJ]' + ,hr: 'Energija [kJ]' ,pl: 'Energia [kJ}' ,tr: 'Enerji [kJ]' }, 'Clock Views:': { cs: 'Hodiny:' ,fi: 'Kellonäkymä:' + ,ko: '시계 보기' ,nl: 'Klokweergave:' ,es: 'Vista del reloj:' ,fr: 'Vue Horloge:' @@ -13730,14 +13750,16 @@ function init() { ,de: 'Uhr-Anzeigen' ,dk: 'Vis klokken:' ,bg: 'Часовник изглед:' + ,hr: 'Satovi:' ,pl: 'Widoki zegarów' ,tr: 'Saat Görünümü' }, 'Clock': { cs: 'Hodiny' ,fr: 'L\'horloge' + ,ko: '시계모드' ,nl: 'Klok' - ,zh_cn: '时钟' + ,zh_cn: '时钟' ,sv: 'Klocka' ,de: 'Uhr' ,dk: 'Klokken' @@ -13745,6 +13767,7 @@ function init() { ,ro: 'Ceas' ,it: 'Orologio' ,bg: 'Часовник' + ,hr: 'Sat' ,pl: 'Zegar' ,ru: 'часы' ,tr: 'Saat' @@ -13752,8 +13775,9 @@ function init() { 'Color': { cs: 'Barva' ,fr: 'Couleur' + ,ko: '색상모드' ,nl: 'Kleur' - ,zh_cn: '彩色' + ,zh_cn: '彩色' ,sv: 'Färg' ,de: 'Farbe' ,dk: 'Farve' @@ -13761,6 +13785,7 @@ function init() { ,ro: 'Culoare' ,it: 'Colore' ,bg: 'Цвят' + ,hr: 'Boja' ,pl: 'Kolor' ,ru: 'цвет' ,tr: 'Renk' @@ -13768,8 +13793,9 @@ function init() { 'Simple': { cs: 'Jednoduchý' ,fr: 'Simple' + ,ko: '간편 모드' ,nl: 'Simpel' - ,zh_cn: '简单' + ,zh_cn: '简单' ,sv: 'Simpel' ,de: 'Einfach' ,dk: 'Simpel' @@ -13777,6 +13803,7 @@ function init() { ,ro: 'Simplu' ,it: 'Semplice' ,bg: 'Прост' + ,hr: 'Jednostavan' ,pl: 'Prosty' ,ru: 'простой' ,tr: 'Basit' @@ -13784,6 +13811,7 @@ function init() { 'TDD average': { cs: 'Průměrná denní dávka' , fi: 'Päivän kokonaisinsuliinin keskiarvo' + , ko: 'TDD average' , nl: 'Gemiddelde dagelijkse insuline (TDD)' ,zh_cn: '日胰岛素用量平均值' , sv: 'Genomsnittlig daglig mängd insulin' @@ -13792,6 +13820,7 @@ function init() { , ro: 'Media Dozei Zilnice Totale de insulină (TDD)' , it: 'Totale Dose Giornaliera media (TDD)' , bg: 'Обща дневна доза средно' + , hr: 'Srednji TDD' , pl: 'Średnia dawka dzienna' , ru: 'средняя суточная доза инсулина' , tr: 'Ortalama günlük Toplam Doz (TDD)' @@ -13799,6 +13828,7 @@ function init() { 'Carbs average': { cs: 'Průměrné množství sacharidů' , fi: 'Hiilihydraatit keskiarvo' + , ko: 'Carbs average' , nl: 'Gemiddelde koolhydraten per dag' ,zh_cn: '碳水化合物平均值' , sv: 'Genomsnittlig mängd kolhydrater per dag' @@ -13807,6 +13837,7 @@ function init() { , ro: 'Media carbohidraților' , it: 'Media carboidrati' , bg: 'Въглехидрати средно' + , hr: 'Prosjek UGH' , pl: 'Średnia ilość węglowodanów' , ru: 'среднее кол-во углеводов за сутки' , tr: 'Günde ortalama karbonhidrat' @@ -13814,6 +13845,7 @@ function init() { 'Eating Soon': { cs: 'Blížící se jídlo' , fi: 'Ruokailu pian' + , ko: 'Eating Soon' , nl: 'Pre-maaltijd modus' ,zh_cn: '过会吃饭' , sv: 'Äter snart' @@ -13822,6 +13854,7 @@ function init() { , ro: 'Mâncare în curând' , it: 'Mangiare presto' , bg: 'Преди хранене' + , hr: 'Uskoro obrok' , pl: 'Przed jedzeniem' , ru: 'скоро прием пищи' , tr: 'Yakında Yenecek' @@ -13829,6 +13862,7 @@ function init() { 'Last entry {0} minutes ago': { cs: 'Poslední hodnota {0} minut zpět' , fi: 'Edellinen verensokeri {0} minuuttia sitten' + , ko: 'Last entry {0} minutes ago' , nl: 'Laatste waarde {0} minuten geleden' ,zh_cn: '最后一个条目 {0} 分钟之前' , sv: 'Senaste värde {0} minuter sedan' @@ -13837,6 +13871,7 @@ function init() { , ro: 'Ultima înregistrare acum {0} minute' , it: 'Ultimo inserimento {0} minuti fa' , bg: 'Последен запис преди {0} минути' + , hr: 'Posljednji zapis prije {0} minuta' , pl: 'Ostatni wpis przed {0} minutami' , ru: 'предыдущая запись {0} минут назад' , tr: 'Son giriş {0} dakika önce' @@ -13844,6 +13879,7 @@ function init() { 'change': { cs: 'změna' , fi: 'muutos' + , ko: 'change' , nl: 'wijziging' ,zh_cn: '改变' , sv: 'byta' @@ -13852,6 +13888,7 @@ function init() { , ro: 'schimbare' , it: 'cambio' , bg: 'промяна' + , hr: 'promjena' , pl: 'zmiana' , ru: 'замена' , tr: 'değişiklik' @@ -13859,6 +13896,7 @@ function init() { 'Speech': { cs: 'Hlas' , fi: 'Puhe' + , ko: 'Speech' , nl: 'Spraak' ,zh_cn: '朗读' , sv: 'Tal' @@ -13867,6 +13905,7 @@ function init() { , ro: 'Vorbă' , it: 'Voce' , bg: 'Глас' + , hr: 'Govor' , pl: 'Głos' , ru: 'речь' , tr: 'Konuş' @@ -13875,12 +13914,14 @@ function init() { cs: 'Horní cíl' , dk: 'Højt mål' , fi: 'Tavoite ylä' + , ko: 'Target Top' , nl: 'Hoog tijdelijk doel' , ro: 'Țintă superioară' , it: 'Limite superiore' ,zh_cn: '目标高值' , sv: 'Högt målvärde' , bg: 'Горна граница' + , hr: 'Gornja granica' , pl: 'Górny limit' , ru: 'верхняя граница цели' , de: 'Oberes Ziel' @@ -13890,12 +13931,14 @@ function init() { cs: 'Dolní cíl' , dk: 'Lavt mål' , fi: 'Tavoite ala' + , ko: 'Target Bottom' , nl: 'Laag tijdelijk doel' ,zh_cn: '目标低值' , ro: 'Țintă inferioară' , it: 'Limite inferiore' , sv: 'Lågt målvärde' , bg: 'Долна граница' + , hr: 'Donja granica' , pl: 'Dolny limit' , ru: 'нижняя граница цели' , de: 'Unteres Ziel' @@ -13905,12 +13948,14 @@ function init() { cs: 'Zrušený' , dk: 'Afbrudt' , fi: 'Peruutettu' + , ko: 'Canceled' , nl: 'Geannuleerd' ,zh_cn: '被取消了' , ro: 'Anulat' , it: 'Cancellato' , sv: 'Avbruten' , bg: 'Отказан' + , hr: 'Otkazano' , pl: 'Anulowane' , ru: 'отменено' , de: 'Abgebrochen' @@ -13920,12 +13965,14 @@ function init() { cs: 'Hodnota z glukoměru' , dk: 'Blodsukkermåler BS' , fi: 'Mittarin VS' + , ko: 'Meter BG' , nl: 'Bloedglucosemeter waarde' ,zh_cn: '指血血糖值' , ro: 'Glicemie din glucometru' , it: 'Glicemia Capillare' , sv: 'Blodsockermätare BG' , bg: 'Измерена КЗ' + , hr: 'GUK iz krvi' , pl: 'Glikemia z krwi' , ru: 'СК по глюкометру' , de: 'Wert Blutzuckermessgerät' @@ -13935,12 +13982,14 @@ function init() { cs: 'přepověď' , dk: 'forudset' , fi: 'ennuste' + , ko: 'predicted' , nl: 'verwachting' ,zh_cn: '预测' , ro: 'estimat' , it: 'predetto' , sv: 'prognos' ,bg: 'прогнозна' + , hr: 'prognozirano' , pl: 'prognoza' , ru: 'прогноз' , de: 'vorhergesagt' @@ -13950,12 +13999,14 @@ function init() { cs: 'budoucnost' , dk: 'fremtidige' , fi: 'tulevaisuudessa' + , ko: 'future' , nl: 'toekomstig' ,zh_cn: '将来' , ro: 'viitor' , it: 'futuro' , sv: 'framtida' , bg: 'бъдеще' + , hr: 'budućnost' , pl: 'przyszłość' , ru: 'будущее' , de: 'Zukunft' @@ -13965,11 +14016,13 @@ function init() { cs: 'zpět' , dk: 'siden' , fi: 'sitten' + , ko: 'ago' , nl: 'geleden' ,zh_cn: '之前' , ro: 'în trecut' , sv: 'förfluten' , bg: 'преди' + , hr: 'prije' , pl: 'temu' , ru: 'назад' , de: 'vor' @@ -13979,12 +14032,14 @@ function init() { cs: 'Poslední data přiajata' , dk: 'Sidste data modtaget' , fi: 'Tietoa vastaanotettu viimeksi' + , ko: 'Last data received' , nl: 'Laatste gegevens ontvangen' ,zh_cn: '上次收到数据' , ro: 'Ultimele date primite' , it: 'Ultimo dato ricevuto' , sv: 'Data senast mottagen' , bg: 'Последни данни преди' + , hr: 'Podaci posljednji puta primljeni' , pl: 'Ostatnie otrzymane dane' , ru: 'недавние данные получены' , de: 'Zuletzt Daten empfangen' @@ -13998,15 +14053,38 @@ function init() { ,fr: 'Vue Horloge' ,ro: 'Vedere tip ceas' ,ru: 'вид циферблата' + ,ko: 'Clock View' ,it: 'Vista orologio' ,sv: 'Visa klocka' ,bg: 'Изглед часовник' + ,hr: 'Prikaz sata' ,nl: 'Klokweergave' ,zh_cn: '时钟视图' ,de: 'Uhr-Anzeigen' - , pl: 'Widok zegara' + ,pl: 'Widok zegara' ,tr: 'Saat Görünümü' - } + }, + 'Protein': { + fi: 'Proteiini' + }, + 'Fat': { + fi: 'Rasva' + }, + 'Protein average': { + fi: 'Proteiini keskiarvo' + }, + 'Fat average': { + fi: 'Rasva keskiarvo' + }, + 'Total carbs': { + fi: 'Hiilihydraatit yhteensä' + }, + 'Total protein': { + fi: 'Proteiini yhteensä' + }, + 'Total fat': { + fi: 'Rasva yhteensä' + } }; language.translations = translations; @@ -14041,6 +14119,7 @@ function init() { } if (options && options.params) { for (var i = 0; i < options.params.length; i++) { + // eslint-disable-next-line no-useless-escape var r = new RegExp('\%' + (i+1), 'g'); translated = translated.replace(r, options.params[i]); } diff --git a/lib/notifications.js b/lib/notifications.js index 8eb1f4eb042..1a03ab87244 100644 --- a/lib/notifications.js +++ b/lib/notifications.js @@ -15,7 +15,7 @@ var Alarm = function(level, group, label) { }; // list of alarms with their thresholds -var alarms = { }; +var alarms = {}; function init (env, ctx) { function notifications () { @@ -41,7 +41,7 @@ function init (env, ctx) { var sendClear = false; - for (var level = 1; level <=2; level++) { + for (var level = 1; level <= 2; level++) { var alarm = getAlarm(level, group); if (alarm.lastEmitTime) { console.info('auto acking ' + alarm.level, ' - ', group); @@ -51,7 +51,7 @@ function init (env, ctx) { } if (sendClear) { - var notify = {clear: true, title: 'All Clear', message: 'Auto ack\'d alarm(s)', group: group}; + var notify = { clear: true, title: 'All Clear', message: 'Auto ack\'d alarm(s)', group: group }; ctx.bus.emit('notification', notify); logEmitEvent(notify); } @@ -70,8 +70,8 @@ function init (env, ctx) { var requests = {}; - notifications.initRequests = function initRequests ( ) { - requests = { notifies: [] , snoozes: []}; + notifications.initRequests = function initRequests () { + requests = { notifies: [], snoozes: [] }; }; notifications.initRequests(); @@ -82,12 +82,12 @@ function init (env, ctx) { */ notifications.findHighestAlarm = function findHighestAlarm (group) { group = group || 'default'; - var filtered = _.filter(requests.notifies, {group: group}); - return _.find(filtered, {level: levels.URGENT}) || _.find(filtered, {level: levels.WARN}); + var filtered = _.filter(requests.notifies, { group: group }); + return _.find(filtered, { level: levels.URGENT }) || _.find(filtered, { level: levels.WARN }); }; - notifications.findUnSnoozeable = function findUnSnoozeable ( ) { - return _.filter(requests.notifies, function (notify) { + notifications.findUnSnoozeable = function findUnSnoozeable () { + return _.filter(requests.notifies, function(notify) { return notify.level <= levels.INFO || notify.isAnnouncement; }); }; @@ -95,7 +95,7 @@ function init (env, ctx) { notifications.snoozedBy = function snoozedBy (notify) { if (notify.isAnnouncement) { return false; } - var filtered = _.filter(requests.snoozes, {group: notify.group}); + var filtered = _.filter(requests.snoozes, { group: notify.group }); if (_.isEmpty(filtered)) { return false; } @@ -107,13 +107,8 @@ function init (env, ctx) { return _.last(sorted); }; - notifications.registerGroup = function registerGroup (group) { - if (groups.indexOf(group) < 0) { - groups.push(group); - } - }; - notifications.requestNotify = function requestNotify (notify) { + // eslint-disable-next-line no-prototype-builtins if (!notify.hasOwnProperty('level') || !notify.title || !notify.message || !notify.plugin) { console.error(new Error('Unable to request notification, since the notify isn\'t complete: ' + JSON.stringify(notify))); return; @@ -135,7 +130,7 @@ function init (env, ctx) { requests.snoozes.push(snooze); }; - notifications.process = function process ( ) { + notifications.process = function process () { var notifyGroups = _.map(requests.notifies, function eachNotify (notify) { return notify.group; @@ -205,7 +200,7 @@ function init (env, ctx) { }; - function ifTestModeThen(callback) { + function ifTestModeThen (callback) { if (env.testMode) { return callback(); } else { @@ -213,15 +208,15 @@ function init (env, ctx) { } } - notifications.resetStateForTests = function resetStateForTests ( ) { - ifTestModeThen(function doResetStateForTests ( ) { + notifications.resetStateForTests = function resetStateForTests () { + ifTestModeThen(function doResetStateForTests () { console.info('resetting notifications state for tests'); alarms = {}; }); }; notifications.getAlarmForTests = function getAlarmForTests (level, group) { - return ifTestModeThen(function doResetStateForTests ( ) { + return ifTestModeThen(function doResetStateForTests () { group = group || 'default'; var alarm = getAlarm(level, group); console.info('got alarm for tests: ', alarm); @@ -249,7 +244,7 @@ function init (env, ctx) { }; } - function logEmitEvent(notify) { + function logEmitEvent (notify) { var type = notify.level >= levels.WARN ? 'ALARM' : (notify.clear ? 'ALL CLEAR' : 'NOTIFICATION'); console.info([ logTimestamp() + '\tEMITTING ' + type + ':' @@ -257,7 +252,7 @@ function init (env, ctx) { ].join('\n')); } - function logSnoozingEvent(highestAlarm, snoozedBy) { + function logSnoozingEvent (highestAlarm, snoozedBy) { console.info([ logTimestamp() + '\tSNOOZING ALARM:' , ' ' + JSON.stringify(notifyToView(highestAlarm)) @@ -267,11 +262,11 @@ function init (env, ctx) { } //TODO: we need a common logger, but until then... - function logTimestamp ( ) { + function logTimestamp () { return (new Date).toISOString(); } return notifications(); } -module.exports = init; \ No newline at end of file +module.exports = init; diff --git a/lib/plugins/ar2.js b/lib/plugins/ar2.js index c440f613e0a..e25a2b36229 100644 --- a/lib/plugins/ar2.js +++ b/lib/plugins/ar2.js @@ -15,6 +15,7 @@ var AR = [-0.723, 1.716]; //TODO: move this to css var AR2_COLOR = 'cyan'; +// eslint-disable-next-line no-unused-vars function init (ctx) { var ar2 = { @@ -23,7 +24,7 @@ function init (ctx) { , pluginType: 'forecast' }; - function buildTitle(prop, sbx) { + function buildTitle (prop, sbx) { var rangeLabel = prop.eventName ? sbx.translate(prop.eventName, { ci: true }).toUpperCase() : sbx.translate('Check BG'); var title = sbx.levels.toDisplay(prop.level) + ', ' + rangeLabel; @@ -35,7 +36,7 @@ function init (ctx) { } ar2.setProperties = function setProperties (sbx) { - sbx.offerProperty('ar2', function setAR2 ( ) { + sbx.offerProperty('ar2', function setAR2 () { var prop = { forecast: ar2.forecast(sbx) @@ -49,7 +50,7 @@ function init (ctx) { } var predicted = prop.forecast && prop.forecast.predicted; - var scaled = predicted && _.map(predicted, function(p) { return sbx.scaleEntry(p) } ); + var scaled = predicted && _.map(predicted, function(p) { return sbx.scaleEntry(p) }); if (scaled && scaled.length >= 3) { prop.displayLine = 'BG 15m: ' + scaled[2] + ' ' + sbx.unitsLabel; @@ -106,8 +107,8 @@ function init (ctx) { return result; }; - ar2.updateVisualisation = function updateVisualisation(sbx) { - sbx.pluginBase.addForecastPoints(ar2.forecastCone(sbx), {type: 'ar2', label: 'AR2 Forecast'}); + ar2.updateVisualisation = function updateVisualisation (sbx) { + sbx.pluginBase.addForecastPoints(ar2.forecastCone(sbx), { type: 'ar2', label: 'AR2 Forecast' }); }; ar2.forecastCone = function forecastCone (sbx) { @@ -118,7 +119,7 @@ function init (ctx) { var coneFactor = getConeFactor(sbx); - function pushConePoints(result, step) { + function pushConePoints (result, step) { var next = incrementAR2(result); //offset from points so they are at a unique time @@ -172,8 +173,8 @@ function init (ctx) { ar2.alexa = { intentHandlers: [{ intent: 'MetricNow' - , routableSlot:'metric' - , slots:['ar2 forecast', 'forecast'] + , routableSlot: 'metric' + , slots: ['ar2 forecast', 'forecast'] , intentHandler: alexaAr2Handler }] }; @@ -181,7 +182,7 @@ function init (ctx) { return ar2; } -function checkForecast(forecast, sbx) { +function checkForecast (forecast, sbx) { var result = undefined; if (forecast && forecast.avgLoss > URGENT_THRESHOLD) { @@ -199,7 +200,7 @@ function checkForecast(forecast, sbx) { } function selectEventType (prop, sbx) { - var predicted = prop.forecast && _.map(prop.forecast.predicted, function(p) { return sbx.scaleEntry(p) } ); + var predicted = prop.forecast && _.map(prop.forecast.predicted, function(p) { return sbx.scaleEntry(p) }); var in20mins = predicted && predicted.length >= 4 ? predicted[3] : undefined; @@ -239,7 +240,7 @@ function getConeFactor (sbx) { return value; } -function okToForecast(sbx) { +function okToForecast (sbx) { var bgnow = sbx.properties.bgnow; var delta = sbx.properties.delta; @@ -273,7 +274,7 @@ function incrementAR2 (result) { }; } -function pushPoint(result) { +function pushPoint (result) { var next = incrementAR2(result); next.points.push(ar2Point( @@ -284,8 +285,7 @@ function pushPoint(result) { return next; } - -function ar2Point(next, options) { +function ar2Point (next, options) { var step = options.step || 0; var coneFactor = options.coneFactor || 0; var offset = options.offset || 0; @@ -301,16 +301,15 @@ function ar2Point(next, options) { }; } - function buildDebug (prop, sbx) { return prop.forecast && { forecast: { avgLoss: prop.forecast.avgLoss - , predicted: _.map(prop.forecast.predicted, function(p) { return sbx.scaleEntry(p) }).join(', ') + , predicted: _.map(prop.forecast.predicted, function(p) { return sbx.scaleEntry(p) }).join(', ') } }; } -function log10(val) { return Math.log(val) / Math.LN10; } +function log10 (val) { return Math.log(val) / Math.LN10; } module.exports = init; diff --git a/lib/plugins/careportal.js b/lib/plugins/careportal.js index b3149f73555..2d65e1c9e9c 100644 --- a/lib/plugins/careportal.js +++ b/lib/plugins/careportal.js @@ -8,6 +8,7 @@ function init() { , pluginType: 'drawer' }; + // eslint-disable-next-line no-unused-vars careportal.getEventTypes = function getEventTypes (sbx) { //TODO: use sbx and new CAREPORTAL_EVENTTYPE_GROUPS="core temps combo dad sensor site etc" @@ -15,59 +16,59 @@ function init() { return [ { val: '' , name: '' - , bg: true, insulin: true, carbs: true, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false + , bg: true, insulin: true, carbs: true, protein: false, fat: false, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false } , { val: 'BG Check' , name: 'BG Check' - , bg: true, insulin: false, carbs: false, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false + , bg: true, insulin: false, carbs: false, protein: false, fat: false, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false } , { val: 'Snack Bolus' , name: 'Snack Bolus' - , bg: true, insulin: true, carbs: true, prebolus: true, duration: false, percent: false, absolute: false, profile: false, split: false + , bg: true, insulin: true, carbs: true, protein: true, fat: true, prebolus: true, duration: false, percent: false, absolute: false, profile: false, split: false } , { val: 'Meal Bolus' , name: 'Meal Bolus' - , bg: true, insulin: true, carbs: true, prebolus: true, duration: false, percent: false, absolute: false, profile: false, split: false + , bg: true, insulin: true, carbs: true, protein: true, fat: true, prebolus: true, duration: false, percent: false, absolute: false, profile: false, split: false } , { val: 'Correction Bolus' , name: 'Correction Bolus' - , bg: true, insulin: true, carbs: false, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false + , bg: true, insulin: true, carbs: false, protein: false, fat: false, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false } , { val: 'Carb Correction' , name: 'Carb Correction' - , bg: true, insulin: false, carbs: true, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false + , bg: true, insulin: false, carbs: true, protein: true, fat: true, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false } , { val: 'Combo Bolus' , name: 'Combo Bolus' - , bg: true, insulin: true, carbs: true, prebolus: true, duration: true, percent: false, absolute: false, profile: false, split: true + , bg: true, insulin: true, carbs: true, protein: true, fat: true, prebolus: true, duration: true, percent: false, absolute: false, profile: false, split: true } , { val: 'Announcement' , name: 'Announcement' - , bg: true, insulin: false, carbs: false, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false + , bg: true, insulin: false, carbs: false, protein: false, fat: false, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false } , { val: 'Note' , name: 'Note' - , bg: true, insulin: false, carbs: false, prebolus: false, duration: true, percent: false, absolute: false, profile: false, split: false + , bg: true, insulin: false, carbs: false, protein: false, fat: false, prebolus: false, duration: true, percent: false, absolute: false, profile: false, split: false } , { val: 'Question' , name: 'Question' - , bg: true, insulin: false, carbs: false, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false + , bg: true, insulin: false, carbs: false, protein: false, fat: false, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false } , { val: 'Exercise' , name: 'Exercise' - , bg: false, insulin: false, carbs: false, prebolus: false, duration: true, percent: false, absolute: false, profile: false, split: false + , bg: false, insulin: false, carbs: false, protein: false, fat: false, prebolus: false, duration: true, percent: false, absolute: false, profile: false, split: false } , { val: 'Site Change' , name: 'Pump Site Change' - , bg: true, insulin: true, carbs: false, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false + , bg: true, insulin: true, carbs: false, protein: false, fat: false, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false } , { val: 'Sensor Start' , name: 'CGM Sensor Start' - , bg: true, insulin: false, carbs: false, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false + , bg: true, insulin: false, carbs: false, protein: false, fat: false, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false } , { val: 'Sensor Change' , name: 'CGM Sensor Insert' - , bg: true, insulin: false, carbs: false, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false + , bg: true, insulin: false, carbs: false, protein: false, fat: false, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false } , { val: 'Sensor Stop' , name: 'CGM Sensor Stop' @@ -75,27 +76,27 @@ function init() { } , { val: 'Pump Battery Change' , name: 'Pump Battery Change' - , bg: true, insulin: false, carbs: false, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false + , bg: true, insulin: false, carbs: false, protein: false, fat: false, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false } , { val: 'Insulin Change' , name: 'Insulin Cartridge Change' - , bg: true, insulin: false, carbs: false, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false + , bg: true, insulin: false, carbs: false, protein: false, fat: false, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false } , { val: 'Temp Basal Start' , name: 'Temp Basal Start' - , bg: true, insulin: false, carbs: false, prebolus: false, duration: true, percent: true, absolute: true, profile: false, split: false + , bg: true, insulin: false, carbs: false, protein: false, fat: false, prebolus: false, duration: true, percent: true, absolute: true, profile: false, split: false } , { val: 'Temp Basal End' , name: 'Temp Basal End' - , bg: true, insulin: false, carbs: false, prebolus: false, duration: true, percent: false, absolute: false, profile: false, split: false + , bg: true, insulin: false, carbs: false, protein: false, fat: false, prebolus: false, duration: true, percent: false, absolute: false, profile: false, split: false } , { val: 'Profile Switch' , name: 'Profile Switch' - , bg: true, insulin: false, carbs: false, prebolus: false, duration: true, percent: false, absolute: false, profile: true, split: false + , bg: true, insulin: false, carbs: false, protein: false, fat: false, prebolus: false, duration: true, percent: false, absolute: false, profile: true, split: false } , { val: 'D.A.D. Alert' , name: 'D.A.D. Alert' - , bg: true, insulin: false, carbs: false, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false + , bg: true, insulin: false, carbs: false, protein: false, fat: false, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false } ]; diff --git a/lib/plugins/cob.js b/lib/plugins/cob.js index 3858e794848..bc769197c2b 100644 --- a/lib/plugins/cob.js +++ b/lib/plugins/cob.js @@ -4,7 +4,7 @@ var _ = require('lodash') , moment = require('moment') , times = require('../times'); -function init(ctx) { +function init (ctx) { var translate = ctx.language.translate; var iob = require('./iob')(ctx); @@ -16,15 +16,15 @@ function init(ctx) { cob.RECENCY_THRESHOLD = times.mins(30).msecs; - cob.setProperties = function setProperties(sbx) { - sbx.offerProperty('cob', function setCOB ( ) { + cob.setProperties = function setProperties (sbx) { + sbx.offerProperty('cob', function setCOB () { return cob.cobTotal(sbx.data.treatments, sbx.data.devicestatus, sbx.data.profile, sbx.time); }); }; - cob.cobTotal = function cobTotal(treatments, devicestatus, profile, time, spec_profile) { + cob.cobTotal = function cobTotal (treatments, devicestatus, profile, time, spec_profile) { - if (!profile || !profile.hasData()) { + if (!profile || !profile.hasData()) { console.warn('For the COB plugin to function you need a treatment profile'); return {}; } @@ -55,7 +55,7 @@ function init(ctx) { return addDisplay(result); }; - function addDisplay(cob) { + function addDisplay (cob) { if (_.isEmpty(cob) || cob.cob === undefined) { return {}; } @@ -82,7 +82,7 @@ function init(ctx) { var recentMills = time - cob.RECENCY_THRESHOLD; return _.chain(devicestatus) - .filter(function (cobStatus) { + .filter(function(cobStatus) { return cobStatus.mills <= futureMills && cobStatus.mills >= recentMills; }) .map(cob.fromDeviceStatus) @@ -95,7 +95,7 @@ function init(ctx) { cob.COBDeviceStatusesInTimeRange = function COBDeviceStatusesInTimeRange (devicestatus, from, to) { return _.chain(devicestatus) - .filter(function (cobStatus) { + .filter(function(cobStatus) { return cobStatus.mills > from && cobStatus.mills < to; }) .map(cob.fromDeviceStatus) @@ -104,7 +104,7 @@ function init(ctx) { .value(); }; - cob.fromDeviceStatus = function fromDeviceStatus(devicestatusEntry) { + cob.fromDeviceStatus = function fromDeviceStatus (devicestatusEntry) { var cobObj; if (_.get(devicestatusEntry, 'openaps') !== undefined) { @@ -140,7 +140,7 @@ function init(ctx) { cob: lastCOB , source: 'OpenAPS' , device: devicestatusEntry.device - , mills: lastMoment.valueOf( ) + , mills: lastMoment.valueOf() }; } else if (_.get(devicestatusEntry, 'loop.cob') !== undefined) { cobObj = devicestatusEntry.loop.cob; @@ -148,7 +148,7 @@ function init(ctx) { cob: cobObj.cob , source: 'Loop' , device: devicestatusEntry.device - , mills: moment(cobObj.timestamp).valueOf( ) + , mills: moment(cobObj.timestamp).valueOf() }; } else { return {}; @@ -164,7 +164,7 @@ function init(ctx) { var isDecaying = 0; var lastDecayedBy = 0; - _.each(treatments, function eachTreatment(treatment) { + _.each(treatments, function eachTreatment (treatment) { if (treatment.carbs && treatment.mills < time) { lastCarbs = treatment; var cCalc = cob.cobCalc(treatment, profile, lastDecayedBy, time, spec_profile); @@ -175,7 +175,7 @@ function init(ctx) { var actEnd = iob.calcTotal(treatments, devicestatus, profile, cCalc.decayedBy, spec_profile).activity; var avgActivity = (actStart + actEnd) / 2; // units: g = BG * scalar / BG / U * g / U - var delayedCarbs = ( avgActivity * liverSensRatio / profile.getSensitivity(treatment.mills, spec_profile) ) * profile.getCarbRatio(treatment.mills, spec_profile); + var delayedCarbs = (avgActivity * liverSensRatio / profile.getSensitivity(treatment.mills, spec_profile)) * profile.getCarbRatio(treatment.mills, spec_profile); var delayMinutes = Math.round(delayedCarbs / profile.getCarbAbsorptionRate(treatment.mills, spec_profile) * 60); if (delayMinutes > 0) { cCalc.decayedBy.setMinutes(cCalc.decayedBy.getMinutes() + delayMinutes); @@ -211,7 +211,7 @@ function init(ctx) { }; }; - cob.carbImpact = function carbImpact(rawCarbImpact, insulinImpact) { + cob.carbImpact = function carbImpact (rawCarbImpact, insulinImpact) { var liverSensRatio = 1.0; var liverCarbImpactMax = 0.7; var liverCarbImpact = Math.min(liverCarbImpactMax, liverSensRatio * insulinImpact); @@ -219,12 +219,12 @@ function init(ctx) { var netCarbImpact = Math.max(0, rawCarbImpact - liverCarbImpact); var totalImpact = netCarbImpact - insulinImpact; return { - netCarbImpact: netCarbImpact, - totalImpact: totalImpact + netCarbImpact: netCarbImpact + , totalImpact: totalImpact }; }; - cob.cobCalc = function cobCalc(treatment, profile, lastDecayedBy, time, spec_profile) { + cob.cobCalc = function cobCalc (treatment, profile, lastDecayedBy, time, spec_profile) { var delay = 20; var isDecaying = 0; @@ -232,7 +232,7 @@ function init(ctx) { if (treatment.carbs) { var carbTime = new Date(treatment.mills); - + var carbs_hr = profile.getCarbAbsorptionRate(treatment.mills, spec_profile); var carbs_min = carbs_hr / 60; @@ -241,31 +241,28 @@ function init(ctx) { decayedBy.setMinutes(decayedBy.getMinutes() + Math.max(delay, minutesleft) + treatment.carbs / carbs_min); if (delay > minutesleft) { initialCarbs = parseInt(treatment.carbs); - } - else { + } else { initialCarbs = parseInt(treatment.carbs) + minutesleft * carbs_min; } var startDecay = new Date(carbTime); startDecay.setMinutes(carbTime.getMinutes() + delay); if (time < lastDecayedBy || time > startDecay) { isDecaying = 1; - } - else { + } else { isDecaying = 0; } return { - initialCarbs: initialCarbs, - decayedBy: decayedBy, - isDecaying: isDecaying, - carbTime: carbTime + initialCarbs: initialCarbs + , decayedBy: decayedBy + , isDecaying: isDecaying + , carbTime: carbTime }; - } - else { + } else { return ''; } }; - cob.updateVisualisation = function updateVisualisation(sbx) { + cob.updateVisualisation = function updateVisualisation (sbx) { var prop = sbx.properties.cob; @@ -273,16 +270,16 @@ function init(ctx) { var displayCob = Math.round(prop.cob * 10) / 10; - var info = [ ]; + var info = []; if (prop.treatmentCOB !== undefined && prop.treatmentCOB.cob) { - info.push({label: translate('Careportal COB'), value: Math.round(prop.treatmentCOB.cob * 10) / 10}); + info.push({ label: translate('Careportal COB'), value: Math.round(prop.treatmentCOB.cob * 10) / 10 }); } var lastCarbs = prop.lastCarbs || (prop.treatmentCOB && prop.treatmentCOB.lastCarbs); if (lastCarbs) { var when = new Date(lastCarbs.mills).toLocaleString(); var amount = lastCarbs.carbs + 'g'; - info.push({label: translate('Last Carbs'), value: amount + ' @ ' + when}); + info.push({ label: translate('Last Carbs'), value: amount + ' @ ' + when }); } sbx.pluginBase.updatePillText(sbx, { @@ -305,8 +302,8 @@ function init(ctx) { cob.alexa = { intentHandlers: [{ intent: 'MetricNow' - , routableSlot:'metric' - , slots:['cob', 'carbs on board', 'carbohydrates on board'] + , routableSlot: 'metric' + , slots: ['cob', 'carbs on board', 'carbohydrates on board'] , intentHandler: alexaCOBHandler }] }; diff --git a/lib/plugins/direction.js b/lib/plugins/direction.js index 53dda0e5879..12a3511368b 100644 --- a/lib/plugins/direction.js +++ b/lib/plugins/direction.js @@ -52,6 +52,7 @@ function init() { var dir2Char = { NONE: '⇼' + , TripleUp: '⤊' , DoubleUp: '⇈' , SingleUp: '↑' , FortyFiveUp: '↗' @@ -59,6 +60,7 @@ function init() { , FortyFiveDown: '↘' , SingleDown: '↓' , DoubleDown: '⇊' + , TripleDown: '⤋' , 'NOT COMPUTABLE': '-' , 'RATE OUT OF RANGE': '⇕' }; diff --git a/lib/plugins/index.js b/lib/plugins/index.js index 363c95fb356..5970c16836c 100644 --- a/lib/plugins/index.js +++ b/lib/plugins/index.js @@ -12,9 +12,11 @@ function init (ctx) { var allPlugins = [] , enabledPlugins = []; - function plugins(name) { + function plugins (name) { if (name) { - return _find(allPlugins, {name: name}); + return _find(allPlugins, { + name: name + }); } else { return plugins; } @@ -37,14 +39,15 @@ function init (ctx) { , require('./openaps')(ctx) , require('./xdrip-js')(ctx) , require('./loop')(ctx) + , require('./override')(ctx) , require('./boluswizardpreview')(ctx) , require('./cannulaage')(ctx) , require('./sensorage')(ctx) , require('./insulinage')(ctx) , require('./batteryage')(ctx) , require('./basalprofile')(ctx) - , require('./boluscalc')(ctx) // fake plugin to show/hide - , require('./profile')(ctx) // fake plugin to hold extended settings + , require('./boluscalc')(ctx) // fake plugin to show/hide + , require('./profile')(ctx) // fake plugin to hold extended settings , require('./speech')(ctx) ]; @@ -72,56 +75,52 @@ function init (ctx) { , require('./basalprofile')(ctx) ]; - plugins.registerServerDefaults = function registerServerDefaults() { + plugins.registerServerDefaults = function registerServerDefaults () { plugins.register(serverDefaultPlugins); return plugins; }; - plugins.registerClientDefaults = function registerClientDefaults() { + plugins.registerClientDefaults = function registerClientDefaults () { plugins.register(clientDefaultPlugins); return plugins; }; - plugins.register = function register(all) { - _each(all, function eachPlugin(plugin) { + plugins.register = function register (all) { + _each(all, function eachPlugin (plugin) { allPlugins.push(plugin); }); enabledPlugins = []; var enable = _get(ctx, 'settings.enable'); - function isEnabled(plugin) { + + function isEnabled (plugin) { //TODO: unify client/server env/app return enable && enable.indexOf(plugin.name) > -1; } - _each(allPlugins, function eachPlugin(plugin) { + _each(allPlugins, function eachPlugin (plugin) { plugin.enabled = isEnabled(plugin); if (plugin.enabled) { enabledPlugins.push(plugin); } }); - - console.log("Plugins registered", enabledPlugins); - }; - - plugins.isPluginEnabled = function isPluginEnabled(pluginName) { - var p = _.find(enabledPlugins, 'name', pluginName); + + plugins.isPluginEnabled = function isPluginEnabled (pluginName) { + var p = _find(enabledPlugins, 'name', pluginName); return (p !== null); } - - plugins.isPluginVisualization - plugins.getPlugin = function getPlugin(pluginName) { - return _.find(enabledPlugins, 'name', pluginName); + plugins.getPlugin = function getPlugin (pluginName) { + return _find(enabledPlugins, 'name', pluginName); } - plugins.eachPlugin = function eachPlugin(f) { + plugins.eachPlugin = function eachPlugin (f) { _each(allPlugins, f); }; - plugins.eachEnabledPlugin = function eachEnabledPlugin(f) { + plugins.eachEnabledPlugin = function eachEnabledPlugin (f) { _each(enabledPlugins, f); }; @@ -129,57 +128,72 @@ function init (ctx) { plugins.specialPlugins = 'ar2 bgnow delta direction timeago upbat rawbg errorcodes profile'; plugins.shownPlugins = function(sbx) { - return _filter(enabledPlugins, function filterPlugins(plugin) { + return _filter(enabledPlugins, function filterPlugins (plugin) { return plugins.specialPlugins.indexOf(plugin.name) > -1 || (sbx && sbx.showPlugins && sbx.showPlugins.indexOf(plugin.name) > -1); }); }; - plugins.eachShownPlugins = function eachShownPlugins(sbx, f) { + plugins.eachShownPlugins = function eachShownPlugins (sbx, f) { _each(plugins.shownPlugins(sbx), f); }; - plugins.hasShownType = function hasShownType(pluginType, sbx) { - return _find(plugins.shownPlugins(sbx), function findWithType(plugin) { + plugins.hasShownType = function hasShownType (pluginType, sbx) { + return _find(plugins.shownPlugins(sbx), function findWithType (plugin) { return plugin.pluginType === pluginType; }) !== undefined; }; - plugins.setProperties = function setProperties(sbx) { + plugins.setProperties = function setProperties (sbx) { plugins.eachEnabledPlugin(function eachPlugin (plugin) { if (plugin.setProperties) { - plugin.setProperties(sbx.withExtendedSettings(plugin)); + try { + plugin.setProperties(sbx.withExtendedSettings(plugin)); + } catch (error) { + console.error('Plugin error on setProperties(): ', plugin.name, error); + } } }); }; - plugins.checkNotifications = function checkNotifications(sbx) { + plugins.checkNotifications = function checkNotifications (sbx) { plugins.eachEnabledPlugin(function eachPlugin (plugin) { if (plugin.checkNotifications) { - plugin.checkNotifications(sbx.withExtendedSettings(plugin)); + try { + plugin.checkNotifications(sbx.withExtendedSettings(plugin)); + } catch (error) { + console.error('Plugin error on checkNotifications(): ', plugin.name, error); + } } }); }; - - plugins.visualizeAlarm = function visualizeAlarm(sbx, alarm, alarmMessage) { - console.log("visualizeAlarms"); - plugins.eachShownPlugins(sbx, function eachPlugin(plugin) { + + plugins.visualizeAlarm = function visualizeAlarm (sbx, alarm, alarmMessage) { + plugins.eachShownPlugins(sbx, function eachPlugin (plugin) { if (plugin.visualizeAlarm) { - plugin.visualizeAlarm(sbx.withExtendedSettings(plugin), alarm, alarmMessage); + try { + plugin.visualizeAlarm(sbx.withExtendedSettings(plugin), alarm, alarmMessage); + } catch (error) { + console.error('Plugin error on visualizeAlarm(): ', plugin.name, error); + } } - }); + }); }; - plugins.updateVisualisations = function updateVisualisations(sbx) { - plugins.eachShownPlugins(sbx, function eachPlugin(plugin) { + plugins.updateVisualisations = function updateVisualisations (sbx) { + plugins.eachShownPlugins(sbx, function eachPlugin (plugin) { if (plugin.updateVisualisation) { - plugin.updateVisualisation(sbx.withExtendedSettings(plugin)); + try { + plugin.updateVisualisation(sbx.withExtendedSettings(plugin)); + } catch (error) { + console.error('Plugin error on visualizeAlarm(): ', plugin.name, error); + } } }); }; - plugins.getAllEventTypes = function getAllEventTypes(sbx) { + plugins.getAllEventTypes = function getAllEventTypes (sbx) { var all = []; - plugins.eachEnabledPlugin(function eachPlugin(plugin) { + plugins.eachEnabledPlugin(function eachPlugin (plugin) { if (plugin.getEventTypes) { var eventTypes = plugin.getEventTypes(sbx.withExtendedSettings(plugin)); if (_isArray(eventTypes)) { @@ -191,8 +205,8 @@ function init (ctx) { return all; }; - plugins.enabledPluginNames = function enabledPluginNames() { - return _map(enabledPlugins, function mapped(plugin) { + plugins.enabledPluginNames = function enabledPluginNames () { + return _map(enabledPlugins, function mapped (plugin) { return plugin.name; }).join(' '); }; diff --git a/lib/plugins/iob.js b/lib/plugins/iob.js index 5468ff0700d..f9bf082d0f4 100644 --- a/lib/plugins/iob.js +++ b/lib/plugins/iob.js @@ -34,9 +34,9 @@ function init(ctx) { if (_.isEmpty(result)) { result = treatmentResult; } else if (treatmentResult.iob) { - result.treatmentIob = treatmentResult.iob; + result.treatmentIob = +(Math.round(treatmentResult.iob + "e+3") + "e-3"); } - + if (result.iob) result.iob = +(Math.round(result.iob + "e+3") + "e-3"); return addDisplay(result); }; @@ -162,7 +162,7 @@ function init(ctx) { }); return { - iob: totalIOB + iob: +(Math.round(totalIOB + "e+3") + "e-3") , activity: totalActivity , lastBolus: lastBolus , source: translate('Care Portal') diff --git a/lib/plugins/loop.js b/lib/plugins/loop.js index 6082b6bdc00..fc8dcbb3282 100644 --- a/lib/plugins/loop.js +++ b/lib/plugins/loop.js @@ -7,7 +7,7 @@ var levels = require('../levels'); // var ALL_STATUS_FIELDS = ['status-symbol', 'status-label', 'iob', 'freq', 'rssi']; Unused variable -function init(ctx) { +function init (ctx) { var utils = require('../utils')(ctx); var loop = { @@ -18,7 +18,7 @@ function init(ctx) { var firstPrefs = true; - loop.getPrefs = function getPrefs(sbx) { + loop.getPrefs = function getPrefs (sbx) { var prefs = { warn: sbx.extendedSettings.warn ? sbx.extendedSettings.warn : 30 @@ -35,7 +35,7 @@ function init(ctx) { }; loop.setProperties = function setProperties (sbx) { - sbx.offerProperty('loop', function setLoop ( ) { + sbx.offerProperty('loop', function setLoop () { return loop.analyzeData(sbx); }); }; @@ -45,14 +45,14 @@ function init(ctx) { var recentMills = sbx.time - times.hours(recentHours).msecs; var recentData = _.chain(sbx.data.devicestatus) - .filter(function (status) { + .filter(function(status) { return ('loop' in status) && sbx.entryMills(status) <= sbx.time && sbx.entryMills(status) >= recentMills; - }).value( ); + }).value(); var prefs = loop.getPrefs(sbx); var recent = moment(sbx.time).subtract(prefs.warn / 2, 'minutes'); - function getDisplayForStatus (status) { + function getDisplayForStatus (status) { var desc = { symbol: '⚠' @@ -113,6 +113,16 @@ function init(ctx) { } } + function assignLastOverride (status) { + var override = status.override; + if (override && override.timestamp) { + override.moment = moment(override.timestamp); + if (!result.lastOverride || override.moment.isAfter(result.lastOverride.moment)) { + result.lastOverride = override; + } + } + } + function assignLastOkMoment (loopStatus) { if (!loopStatus.failureReason && (!result.lastOkMoment || loopStatus.moment.isAfter(result.lastOkMoment))) { result.lastOkMoment = loopStatus.moment; @@ -126,6 +136,7 @@ function init(ctx) { assignLastEnacted(loopStatus); assignLastLoop(loopStatus); assignLastPredicted(loopStatus); + assignLastOverride(status); assignLastOkMoment(loopStatus); } }); @@ -135,7 +146,7 @@ function init(ctx) { return result; }; - loop.checkNotifications = function checkNotifications(sbx) { + loop.checkNotifications = function checkNotifications (sbx) { var prefs = loop.getPrefs(sbx); if (!prefs.enableAlerts) { return; } @@ -171,9 +182,9 @@ function init(ctx) { return (value != null) ? prefix + value : ''; } - var events = [ ]; + var events = []; - function addRecommendedTempBasal() { + function addRecommendedTempBasal () { if (prop.lastLoop && prop.lastLoop.recommendedTempBasal) { var recommendedTempBasal = prop.lastLoop.recommendedTempBasal; @@ -185,7 +196,7 @@ function init(ctx) { valueParts = concatIOB(valueParts); valueParts = concatCOB(valueParts); - valueParts = concatEventualBG (valueParts); + valueParts = concatEventualBG(valueParts); valueParts = concatRecommendedBolus(valueParts); events.push({ @@ -195,48 +206,48 @@ function init(ctx) { } } - function addRSSI() { - + function addRSSI () { + var mostRecent = ""; var pumpRSSI = ""; var bleRSSI = ""; var reportRSSI = ""; - + _.forEach(sbx.data.devicestatus, function(entry) { - + if (entry.radioAdapter) { var entryMoment = moment(entry.created_at); - - if (mostRecent == "") { - mostRecent = entryMoment; - if (entry.radioAdapter.pumpRSSI) { - pumpRSSI = entry.radioAdapter.pumpRSSI; - } - if (entry.radioAdapter.RSSI) { - bleRSSI = entry.radioAdapter.RSSI; - } - } - - if (mostRecent < entryMoment) { - mostRecent = entryMoment; - if (entry.radioAdapter.pumpRSSI) { - pumpRSSI = entry.radioAdapter.pumpRSSI; - } - if (entry.radioAdapter.RSSI) { - bleRSSI = entry.radioAdapter.RSSI; - } - } - } + + if (mostRecent == "") { + mostRecent = entryMoment; + if (entry.radioAdapter.pumpRSSI) { + pumpRSSI = entry.radioAdapter.pumpRSSI; + } + if (entry.radioAdapter.RSSI) { + bleRSSI = entry.radioAdapter.RSSI; + } + } + + if (mostRecent < entryMoment) { + mostRecent = entryMoment; + if (entry.radioAdapter.pumpRSSI) { + pumpRSSI = entry.radioAdapter.pumpRSSI; + } + if (entry.radioAdapter.RSSI) { + bleRSSI = entry.radioAdapter.RSSI; + } + } + } }); - + if (bleRSSI != "") { - reportRSSI = "BLE RSSI: " + bleRSSI + " "; + reportRSSI = "BLE RSSI: " + bleRSSI + " "; } - + if (pumpRSSI != "") { - reportRSSI = reportRSSI + "Pump RSSI: " + pumpRSSI; + reportRSSI = reportRSSI + "Pump RSSI: " + pumpRSSI; } - + if (reportRSSI != "") { events.push({ time: mostRecent @@ -245,21 +256,21 @@ function init(ctx) { } } - - function addLastEnacted() { + + function addLastEnacted () { if (prop.lastEnacted) { var canceled = prop.lastEnacted.rate === 0 && prop.lastEnacted.duration === 0; var valueParts = [ - , 'Temp Basal' + (canceled ? ' Canceled' : ' Started') + '' + 'Temp Basal' + (canceled ? ' Canceled' : ' Started') + '' , canceled ? '' : ' ' + prop.lastEnacted.rate.toFixed(2) + 'U/hour for ' + prop.lastEnacted.duration + 'm' , valueString(', ', prop.lastEnacted.reason) ]; valueParts = concatIOB(valueParts); valueParts = concatCOB(valueParts); - valueParts = concatEventualBG (valueParts); - valueParts = concatRecommendedBolus(valueParts); + valueParts = concatEventualBG(valueParts); + valueParts = concatRecommendedBolus(valueParts); events.push({ time: prop.lastEnacted.moment @@ -273,7 +284,9 @@ function init(ctx) { var iob = prop.lastLoop.iob; valueParts = valueParts.concat([ ', IOB: ' + , sbx.roundInsulinForDisplayFormat(iob.iob) + 'U' + , iob.basaliob ? ', Basal IOB ' + sbx.roundInsulinForDisplayFormat(iob.basaliob) + 'U' : '' ]); } @@ -283,7 +296,6 @@ function init(ctx) { function concatCOB (valueParts) { if (prop.lastLoop && prop.lastLoop.cob) { - var cob = prop.lastLoop.cob; var cob = prop.lastLoop.cob.cob; cob = Math.round(cob); valueParts = valueParts.concat([ @@ -298,28 +310,29 @@ function init(ctx) { function concatEventualBG (valueParts) { if (prop.lastLoop && prop.lastLoop.predicted) { var predictedBGvalues = prop.lastLoop.predicted.values; - var eventualBG = predictedBGvalues[predictedBGvalues.length-1]; - var maxBG = Math.max.apply(null,predictedBGvalues); - var minBG = Math.min.apply(null,predictedBGvalues); - var eventualBGscaled = sbx.settings.units === 'mmol' ? - sbx.roundBGToDisplayFormat(sbx.scaleMgdl(eventualBG)) : eventualBG; - var maxBGscaled = sbx.settings.units === 'mmol' ? - sbx.roundBGToDisplayFormat(sbx.scaleMgdl(maxBG)) : maxBG; - var minBGscaled = sbx.settings.units === 'mmol' ? - sbx.roundBGToDisplayFormat(sbx.scaleMgdl(minBG)) : minBG; + var eventualBG = predictedBGvalues[predictedBGvalues.length - 1]; + var maxBG = Math.max.apply(null, predictedBGvalues); + var minBG = Math.min.apply(null, predictedBGvalues); + var eventualBGscaled = sbx.settings.units === 'mmol' ? + sbx.roundBGToDisplayFormat(sbx.scaleMgdl(eventualBG)) : eventualBG; + var maxBGscaled = sbx.settings.units === 'mmol' ? + sbx.roundBGToDisplayFormat(sbx.scaleMgdl(maxBG)) : maxBG; + var minBGscaled = sbx.settings.units === 'mmol' ? + sbx.roundBGToDisplayFormat(sbx.scaleMgdl(minBG)) : minBG; + valueParts = valueParts.concat([ ', Predicted Min-Max BG: ' - , minBGscaled - , '-' - , maxBGscaled - ,', Eventual BG: ' - , eventualBGscaled + , minBGscaled + , '-' + , maxBGscaled + , ', Eventual BG: ' + , eventualBGscaled ]); } - + return valueParts; - } - + } + function concatRecommendedBolus (valueParts) { if (prop.lastLoop && prop.lastLoop.recommendedBolus) { var recommendedBolus = prop.lastLoop.recommendedBolus; @@ -330,14 +343,13 @@ function init(ctx) { } return valueParts; - } - - - function getForecastPoints ( ) { - var points = [ ]; + } + + function getForecastPoints () { + var points = []; function toPoints (startTime, offset) { - return function toPoint (value, index) { + return function toPoint (value, index) { return { mgdl: value , color: '#ff00ff' @@ -353,12 +365,6 @@ function init(ctx) { if (predicted.values) { points = points.concat(_.map(predicted.values, toPoints(startTime, 0))); } - // if (prop.lastPredBGs.IOB) { - // points = points.concat(_.map(prop.lastPredBGs.IOB, toPoints(moment, 3000))); - // } - // if (prop.lastPredBGs.COB) { - // points = points.concat(_.map(prop.lastPredBGs.COB, toPoints(moment, 7000))); - // } } return points; @@ -375,12 +381,12 @@ function init(ctx) { } else if ('looping' === prop.display.code) { addLastEnacted(); } else { - addRecommendedTempBasal(); + addRecommendedTempBasal(); } - + addRSSI(); - var sorted = _.sortBy(events, function toMill(event) { + var sorted = _.sortBy(events, function toMill (event) { return event.time.valueOf(); }).reverse(); @@ -397,12 +403,23 @@ function init(ctx) { loopName = prop.lastLoop.name; } + var eventualBGValue = ''; + if (prop.lastLoop && prop.lastLoop.predicted) { + var predictedBGvalues = prop.lastLoop.predicted.values; + var eventualBG = predictedBGvalues[predictedBGvalues.length - 1]; + if (sbx.settings.units === 'mmol') { + eventualBG = sbx.roundBGToDisplayFormat(sbx.scaleMgdl(eventualBG)); + } + eventualBGValue = ' ↝ ' + eventualBG; + } + var label = loopName + ' ' + prop.display.symbol; - var lastLoopMoment = prop.lastLoop ? prop.lastLoop.moment : null; + var lastLoopValue = prop.lastLoop ? + utils.timeFormat(prop.lastLoop.moment, sbx) + eventualBGValue : null; sbx.pluginBase.updatePillText(loop, { - value: utils.timeFormat(lastLoopMoment, sbx) + value: lastLoopValue , label: label , info: info , pillClass: statusClass(prop, prefs, sbx) @@ -410,7 +427,7 @@ function init(ctx) { var forecastPoints = getForecastPoints(); if (forecastPoints && forecastPoints.length > 0) { - sbx.pluginBase.addForecastPoints(forecastPoints, {type: 'loop', label: 'Loop Forecasts'}); + sbx.pluginBase.addForecastPoints(forecastPoints, { type: 'loop', label: 'Loop Forecasts' }); } }; @@ -448,7 +465,7 @@ function init(ctx) { } } - function alexaLastLoopHandler(next, slots, sbx) { + function alexaLastLoopHandler (next, slots, sbx) { console.log(JSON.stringify(sbx.properties.loop.lastLoop)); var response = 'The last successful loop was ' + moment(sbx.properties.loop.lastOkMoment).from(moment(sbx.time)); next('Last loop', response); @@ -501,5 +518,4 @@ function init(ctx) { } - module.exports = init; diff --git a/lib/plugins/openaps.js b/lib/plugins/openaps.js index 78c4ad2ca35..27b7a31ae95 100644 --- a/lib/plugins/openaps.js +++ b/lib/plugins/openaps.js @@ -7,7 +7,7 @@ var levels = require('../levels'); // var ALL_STATUS_FIELDS = ['status-symbol', 'status-label', 'iob', 'meal-assist', 'freq', 'rssi']; Unused variable -function init(ctx) { +function init (ctx) { var utils = require('../utils')(ctx); var openaps = { name: 'openaps' @@ -17,7 +17,15 @@ function init(ctx) { var translate = ctx.language.translate; var firstPrefs = true; - openaps.getPrefs = function getPrefs(sbx) { + openaps.getClientPrefs = function getClientPrefs() { + return ([{ + label: "Color prediction lines", + id: "colorPredictionLines", + type: "boolean" + }]); + } + + openaps.getPrefs = function getPrefs (sbx) { function cleanList (value) { return decodeURIComponent(value || '').toLowerCase().split(' '); @@ -27,31 +35,41 @@ function init(ctx) { return _.isEmpty(list) || _.isEmpty(list[0]); } + const settings = sbx.extendedSettings || {}; - var fields = cleanList(sbx.extendedSettings.fields); + var fields = cleanList(settings.fields); fields = isEmpty(fields) ? ['status-symbol', 'status-label', 'iob', 'meal-assist', 'rssi'] : fields; - var retroFields = cleanList(sbx.extendedSettings.retroFields); + var retroFields = cleanList(settings.retroFields); retroFields = isEmpty(retroFields) ? ['status-symbol', 'status-label', 'iob', 'meal-assist', 'rssi'] : retroFields; + if (typeof settings.colorPredictionLines == 'undefined') { + settings.colorPredictionLines = true; + } + var prefs = { fields: fields , retroFields: retroFields - , warn: sbx.extendedSettings.warn ? sbx.extendedSettings.warn : 30 - , urgent: sbx.extendedSettings.urgent ? sbx.extendedSettings.urgent : 60 - , enableAlerts: sbx.extendedSettings.enableAlerts + , warn: settings.warn ? settings.warn : 30 + , urgent: settings.urgent ? settings.urgent : 60 + , enableAlerts: settings.enableAlerts + , predIOBColor: settings.predIobColor ? settings.predIobColor : '#1e88e5' + , predCOBColor: settings.predCobColor ? settings.predCobColor : '#FB8C00FF' + , predACOBColor: settings.predAcobColor ? settings.predAcobColor : '#FB8C0080' + , predZTColor: settings.predZtColor ? settings.predZtColor : '#00d2d2' + , predUAMColor: settings.predUamColor ? settings.predUamColor : '#c9bd60' + , colorPredictionLines: settings.colorPredictionLines }; if (firstPrefs) { firstPrefs = false; - console.info('OpenAPS Prefs:', prefs); } return prefs; }; openaps.setProperties = function setProperties (sbx) { - sbx.offerProperty('openaps', function setOpenAPS ( ) { + sbx.offerProperty('openaps', function setOpenAPS () { return openaps.analyzeData(sbx); }); }; @@ -61,10 +79,10 @@ function init(ctx) { var recentMills = sbx.time - times.hours(recentHours).msecs; var recentData = _.chain(sbx.data.devicestatus) - .filter(function (status) { + .filter(function(status) { return ('openaps' in status) && sbx.entryMills(status) <= sbx.time && sbx.entryMills(status) >= recentMills; }) - .map(function (status) { + .map(function(status) { if (status.openaps && _.isArray(status.openaps.iob) && status.openaps.iob.length > 0) { status.openaps.iob = status.openaps.iob[0]; if (status.openaps.iob.time) { @@ -73,7 +91,7 @@ function init(ctx) { } return status; }) - .value( ); + .value(); var prefs = openaps.getPrefs(sbx); var recent = moment(sbx.time).subtract(prefs.warn / 2, 'minutes'); @@ -88,7 +106,7 @@ function init(ctx) { , lastPredBGs: null }; - function getDevice(status) { + function getDevice (status) { var uri = status.device || 'device'; var device = result.seenDevices[uri]; @@ -105,7 +123,7 @@ function init(ctx) { function toMoments (status) { return { - when: moment(status.mills) + when: moment(status.mills) , enacted: status.openaps.enacted && status.openaps.enacted.timestamp && (status.openaps.enacted.recieved || status.openaps.enacted.received) && moment(status.openaps.enacted.timestamp) , notEnacted: status.openaps.enacted && status.openaps.enacted.timestamp && !(status.openaps.enacted.recieved || status.openaps.enacted.received) && moment(status.openaps.enacted.timestamp) , suggested: status.openaps.suggested && status.openaps.suggested.timestamp && moment(status.openaps.suggested.timestamp) @@ -113,7 +131,7 @@ function init(ctx) { }; } - function momentsToLoopStatus (moments, noWarning) { + function momentsToLoopStatus (moments, noWarning) { var status = { symbol: '⚠' @@ -122,8 +140,7 @@ function init(ctx) { }; if (moments.notEnacted && ( - (moments.enacted && moments.notEnacted.isAfter(moments.enacted)) || (!moments.enacted && moments.notEnacted.isAfter(recent))) - ) { + (moments.enacted && moments.notEnacted.isAfter(moments.enacted)) || (!moments.enacted && moments.notEnacted.isAfter(recent)))) { status.symbol = 'x'; status.code = 'notenacted'; status.label = 'Not Enacted'; @@ -160,7 +177,7 @@ function init(ctx) { enacted.moment = moment(enacted.timestamp); result.lastEnacted = enacted; if (enacted.predBGs && (!result.lastPredBGs || enacted.moment.isAfter(result.lastPredBGs.moment))) { - result.lastPredBGs = _.isArray(enacted.predBGs) ? {values: enacted.predBGs} : enacted.predBGs; + result.lastPredBGs = _.isArray(enacted.predBGs) ? { values: enacted.predBGs } : enacted.predBGs; result.lastPredBGs.moment = enacted.moment; } } @@ -175,7 +192,7 @@ function init(ctx) { suggested.moment = moment(suggested.timestamp); result.lastSuggested = suggested; if (suggested.predBGs && (!result.lastPredBGs || suggested.moment.isAfter(result.lastPredBGs.moment))) { - result.lastPredBGs = _.isArray(suggested.predBGs) ? {values: suggested.predBGs} : suggested.predBGs; + result.lastPredBGs = _.isArray(suggested.predBGs) ? { values: suggested.predBGs } : suggested.predBGs; result.lastPredBGs.moment = suggested.moment; } } @@ -203,11 +220,11 @@ function init(ctx) { result.lastEventualBG = result.lastSuggested.eventualBG; } } else if (result.lastEnacted && result.lastEnacted.moment) { - result.lastLoopMoment = result.lastEnacted.moment; - result.lastEventualBG = result.lastEnacted.eventualBG; + result.lastLoopMoment = result.lastEnacted.moment; + result.lastEventualBG = result.lastEnacted.eventualBG; } else if (result.lastSuggested && result.lastSuggested.moment) { - result.lastLoopMoment = result.lastSuggested.moment; - result.lastEventualBG = result.lastSuggested.eventualBG; + result.lastLoopMoment = result.lastSuggested.moment; + result.lastEventualBG = result.lastSuggested.eventualBG; } result.status = momentsToLoopStatus({ @@ -220,43 +237,68 @@ function init(ctx) { }; openaps.getEventTypes = function getEventTypes (sbx) { - - var units = sbx.settings.units; - console.log('units', units); - + + var units = sbx.settings.units; + console.log('units', units); + var reasonconf = []; - + if (units == 'mmol') { - reasonconf.push({ name: translate('Eating Soon'), targetTop: 4.5, targetBottom: 4.5, duration: 60 }); - reasonconf.push({ name: translate('Activity'), targetTop: 8, targetBottom: 6.5, duration: 120 }); + reasonconf.push({ name: translate('Eating Soon'), targetTop: 4.5, targetBottom: 4.5, duration: 60 }); + reasonconf.push({ name: translate('Activity'), targetTop: 8, targetBottom: 6.5, duration: 120 }); } else { - reasonconf.push({ name: translate('Eating Soon'), targetTop: 80, targetBottom: 80, duration: 60 }); - reasonconf.push({ name: translate('Activity'), targetTop: 140, targetBottom: 120, duration: 120 }); + reasonconf.push({ name: translate('Eating Soon'), targetTop: 80, targetBottom: 80, duration: 60 }); + reasonconf.push({ name: translate('Activity'), targetTop: 140, targetBottom: 120, duration: 120 }); } - - reasonconf.push({ name: 'Manual' }); - + + reasonconf.push({ name: 'Manual' }); + return [ { val: 'Temporary Target' , name: 'Temporary Target' - , bg: false, insulin: false, carbs: false, prebolus: false, duration: true, percent: false, absolute: false, profile: false, split: false - , targets: true, reasons: reasonconf + , bg: false + , insulin: false + , carbs: false + , prebolus: false + , duration: true + , percent: false + , absolute: false + , profile: false + , split: false + , targets: true + , reasons: reasonconf } , { val: 'Temporary Target Cancel' , name: 'Temporary Target Cancel' - , bg: false, insulin: false, carbs: false, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false - } + , bg: false + , insulin: false + , carbs: false + , prebolus: false + , duration: false + , percent: false + , absolute: false + , profile: false + , split: false + } , { val: 'OpenAPS Offline' , name: 'OpenAPS Offline' - , bg: false, insulin: false, carbs: false, prebolus: false, duration: true, percent: false, absolute: false, profile: false, split: false + , bg: false + , insulin: false + , carbs: false + , prebolus: false + , duration: true + , percent: false + , absolute: false + , profile: false + , split: false } ]; }; - openaps.checkNotifications = function checkNotifications(sbx) { + openaps.checkNotifications = function checkNotifications (sbx) { var prefs = openaps.getPrefs(sbx); if (!prefs.enableAlerts) { return; } @@ -283,8 +325,8 @@ function init(ctx) { } }; - openaps.findOfflineMarker = function findOfflineMarker(sbx) { - return _.findLast(sbx.data.treatments, function match(treatment) { + openaps.findOfflineMarker = function findOfflineMarker (sbx) { + return _.findLast(sbx.data.treatments, function match (treatment) { var eventTime = sbx.entryMills(treatment); var eventEnd = treatment.duration ? eventTime + times.mins(treatment.duration).msecs : eventTime; return eventTime <= sbx.time && treatment.eventType === 'OpenAPS Offline' && eventEnd >= sbx.time; @@ -302,9 +344,9 @@ function init(ctx) { return value ? prefix + value : ''; } - var events = [ ]; + var events = []; - function addSuggestion() { + function addSuggestion () { if (prop.lastSuggested) { var valueParts = [ @@ -337,14 +379,23 @@ function init(ctx) { return valueParts; } - function getForecastPoints ( ) { - var points = [ ]; + function getForecastPoints () { + var points = []; function toPoints (offset, forecastType) { - return function toPoint (value, index) { + return function toPoint (value, index) { + var colors = { + 'Values': '#ff00ff' + , 'IOB': prefs.predIOBColor + , 'Zero-Temp': prefs.predZTColor + , 'COB': prefs.predCOBColor + , 'Accel-COB': prefs.predACOBColor + , 'UAM': prefs.predUAMColor + } + return { mgdl: value - , color: '#ff00ff' + , color: prefs.colorPredictionLines ? colors[forecastType] : '#ff00ff' , mills: prop.lastPredBGs.moment.valueOf() + times.mins(5 * index).msecs + offset , noFade: true , forecastType: forecastType @@ -413,7 +464,7 @@ function init(ctx) { } if (device.mmtune) { - var best = _.maxBy(device.mmtune.scanDetails, function (d) { + var best = _.maxBy(device.mmtune.scanDetails, function(d) { return d[2]; }); @@ -430,7 +481,7 @@ function init(ctx) { }); }); - var sorted = _.sortBy(events, function toMill(event) { + var sorted = _.sortBy(events, function toMill (event) { return event.time.valueOf(); }).reverse(); @@ -455,7 +506,7 @@ function init(ctx) { var forecastPoints = getForecastPoints(); if (forecastPoints && forecastPoints.length > 0) { - sbx.pluginBase.addForecastPoints(forecastPoints, {type: 'openaps', label: 'OpenAPS Forecasts'}); + sbx.pluginBase.addForecastPoints(forecastPoints, { type: 'openaps', label: 'OpenAPS Forecasts' }); } }; @@ -464,8 +515,8 @@ function init(ctx) { var response = translate('alexaOpenAPSForecast', { params: [ sbx.properties.openaps.lastEventualBG - ]} - ); + ] + }); next('Loop Forecast', response); } } diff --git a/lib/plugins/override.js b/lib/plugins/override.js new file mode 100644 index 00000000000..ba57b11761f --- /dev/null +++ b/lib/plugins/override.js @@ -0,0 +1,67 @@ +'use strict'; + +function init() { + var override = { + name: 'override' + , label: 'Override' + , pluginType: 'pill-status' + }; + + override.isActive = function isActive(overrideStatus, sbx) { + + if (!overrideStatus) { + return false; + } else { + var endMoment = overrideStatus.duration ? overrideStatus.moment.clone().add(overrideStatus.duration, 'seconds') : null; + overrideStatus.endMoment = endMoment; + return overrideStatus.active && (!endMoment || endMoment.isAfter(sbx.time)); + } + + }; + + override.updateVisualisation = function updateVisualisation (sbx) { + var lastOverride = sbx.properties.loop.lastOverride; + var info = [ ]; + var label = ''; + var isActive = override.isActive(lastOverride, sbx); + + if (isActive) { + if (lastOverride.currentCorrectionRange) { + var max = lastOverride.currentCorrectionRange.maxValue; + var min = lastOverride.currentCorrectionRange.minValue; + + if (sbx.settings.units === 'mmol') { + max = sbx.roundBGToDisplayFormat(sbx.scaleMgdl(max)); + min = sbx.roundBGToDisplayFormat(sbx.scaleMgdl(min)); + } + + if (lastOverride.currentCorrectionRange.minValue === lastOverride.currentCorrectionRange.maxValue) { + label += 'BG Target: ' + min; + } else { + label += 'BG Targets: ' + min + ':' + max; + } + } + if ((lastOverride.multiplier || lastOverride.multiplier === 0) && lastOverride.multiplier !== 1) { + var multiplier = (lastOverride.multiplier * 100).toFixed(0); + label += ' | O: ' + multiplier + '%'; + } + } + + var endOverrideValue = lastOverride && lastOverride.endMoment ? + '⇥ ' + lastOverride.endMoment.format('LT') : (lastOverride ? '∞' : ''); + + sbx.pluginBase.updatePillText(override, { + value: endOverrideValue + , label: label + , info: info + , hide: !isActive + }); + + }; + + return override; + +} + + +module.exports = init; diff --git a/lib/plugins/pump.js b/lib/plugins/pump.js index dc495bfcc1e..842d8536b6b 100644 --- a/lib/plugins/pump.js +++ b/lib/plugins/pump.js @@ -215,6 +215,10 @@ function init (ctx) { } else { result.reservoir.level = levels.NONE; } + } else if (result.manufacturer === 'Insulet' && result.model === 'Eros') { + result.reservoir = { + label: 'Reservoir', display: '50+ U' + } } } @@ -264,7 +268,7 @@ function init (ctx) { if (pump.warnOnSuspend && pump.status.suspended) { result.status.level = levels.WARN; result.status.message = 'Pump Suspended'; - }; + } } result.status = { value: status, display: status, label: translate('Status') }; } @@ -277,6 +281,8 @@ function init (ctx) { level: levels.NONE , clock: pump.clock ? { value: moment(pump.clock) } : null , reservoir: pump.reservoir || pump.reservoir === 0 ? { value: pump.reservoir } : null + , manufacturer: pump.manufacturer + , model: pump.model , extended: pump.extended || null }; diff --git a/lib/plugins/speech.js b/lib/plugins/speech.js index e9032b46644..498071c2a5a 100644 --- a/lib/plugins/speech.js +++ b/lib/plugins/speech.js @@ -1,10 +1,6 @@ 'use strict'; -var levels = require('../levels'); -var times = require('../times'); - var lastEntryValue; -var lastTime; var lastMinutes; var lastEntryTime; @@ -78,7 +74,7 @@ function init(ctx) { lastMinutes = timeMinutes; var lastEntryString = translate('Last entry {0} minutes ago'); - var sayIt = lastEntryString.replace('{0}', timeMinutes); + sayIt = lastEntryString.replace('{0}', timeMinutes); speech.say(sayIt); } } diff --git a/lib/plugins/timeago.js b/lib/plugins/timeago.js index 0e460eb87b0..6f8989a4876 100644 --- a/lib/plugins/timeago.js +++ b/lib/plugins/timeago.js @@ -2,18 +2,20 @@ var levels = require('../levels'); var times = require('../times'); +var lastChecked = new Date(); +var lastSuspendTime = new Date("1900-01-01"); -function init (ctx) { +function init(ctx) { var translate = ctx.language.translate; var timeago = { - name: 'timeago' - , label: 'Timeago' - , pluginType: 'pill-status' - , pillFlip: true + name: 'timeago', + label: 'Timeago', + pluginType: 'pill-status', + pillFlip: true }; - timeago.checkNotifications = function checkNotifications (sbx) { + timeago.checkNotifications = function checkNotifications(sbx) { if (!sbx.extendedSettings.enableAlerts) { return; @@ -31,44 +33,60 @@ function init (ctx) { return lines.join('\n'); } - function sendAlarm (opts) { + function sendAlarm(opts) { var agoDisplay = timeago.calcDisplay(lastSGVEntry, sbx.time); sbx.notifications.requestNotify({ - level: opts.level - , title: translate('Stale data, check rig?') - , message: buildMessage(agoDisplay) - , eventName: timeago.name - , plugin: timeago - , group: 'Time Ago' - , pushoverSound: opts.pushoverSound - , debug: agoDisplay + level: opts.level, + title: translate('Stale data, check rig?'), + message: buildMessage(agoDisplay), + eventName: timeago.name, + plugin: timeago, + group: 'Time Ago', + pushoverSound: opts.pushoverSound, + debug: agoDisplay }); } var status = timeago.checkStatus(sbx); if (status === 'urgent') { sendAlarm({ - level: levels.URGENT - , pushoverSound: 'echo' + level: levels.URGENT, + pushoverSound: 'echo' }); } else if (status === 'warn') { sendAlarm({ - level: levels.WARN - , pushoverSound: 'echo' + level: levels.WARN, + pushoverSound: 'echo' }); } }; - timeago.checkStatus = function checkStatus (sbx) { + timeago.checkStatus = function checkStatus(sbx) { - var lastSGVEntry = sbx.lastSGVEntry() - , warn = sbx.settings.alarmTimeagoWarn - , warnMins = sbx.settings.alarmTimeagoWarnMins || 15 - , urgent = sbx.settings.alarmTimeagoUrgent - , urgentMins = sbx.settings.alarmTimeagoUrgentMins || 30 - ; + // Check if the app has been suspended; if yes, snooze data missing alarmn for 15 seconds + var now = new Date(); + var delta = now.getTime() - lastChecked.getTime(); + lastChecked = now; + + if (delta > 15 * 1000) { // Looks like we've been hibernating + lastSuspendTime = now; + } + + var timeSinceLastSuspended = now.getTime() - lastSuspendTime.getTime(); + + if (timeSinceLastSuspended < (10 * 1000)) { + + console.log('Hibernation detected, suspending timeago alarm'); + return 'current'; + } + + var lastSGVEntry = sbx.lastSGVEntry(), + warn = sbx.settings.alarmTimeagoWarn, + warnMins = sbx.settings.alarmTimeagoWarnMins || 15, + urgent = sbx.settings.alarmTimeagoUrgent, + urgentMins = sbx.settings.alarmTimeagoUrgentMins || 30; function isStale(mins) { return sbx.time - lastSGVEntry.mills > times.mins(mins).msecs; @@ -88,63 +106,60 @@ function init (ctx) { }; - timeago.isMissing = function isMissing (opts) { + timeago.isMissing = function isMissing(opts) { if (!opts || !opts.entry || isNaN(opts.entry.mills) || isNaN(opts.time) || isNaN(opts.timeSince)) { return { - label: translate('time ago') - , shortLabel: translate('ago') + label: translate('time ago'), + shortLabel: translate('ago') }; } }; - timeago.inTheFuture = function inTheFuture (opts) { + timeago.inTheFuture = function inTheFuture(opts) { if (opts.entry.mills - times.mins(5).msecs > opts.time) { return { - label: translate('in the future') - , shortLabel: translate('future') + label: translate('in the future'), + shortLabel: translate('future') }; } }; - timeago.almostInTheFuture = function almostInTheFuture (opts) { + timeago.almostInTheFuture = function almostInTheFuture(opts) { if (opts.entry.mills > opts.time) { return { - value: 1 - , label: translate('min ago') - , shortLabel: 'm' + value: 1, + label: translate('min ago'), + shortLabel: 'm' }; } }; - timeago.isLessThan = function isLessThan (limit, divisor, label, shortLabel) { - return function checkIsLessThan (opts) { + timeago.isLessThan = function isLessThan(limit, divisor, label, shortLabel) { + return function checkIsLessThan(opts) { if (opts.timeSince < limit) { return { - value: Math.max(1, Math.round(opts.timeSince / divisor)) - , label: label - , shortLabel: shortLabel + value: Math.max(1, Math.round(opts.timeSince / divisor)), + label: label, + shortLabel: shortLabel }; } }; }; timeago.resolvers = [ - timeago.isMissing - , timeago.inTheFuture - , timeago.almostInTheFuture - , timeago.isLessThan(times.mins(2).msecs, times.min().msecs, 'min ago', 'm') - , timeago.isLessThan(times.hour().msecs, times.min().msecs, 'mins ago', 'm') - , timeago.isLessThan(times.hours(2).msecs, times.hour().msecs, 'hour ago', 'h') - , timeago.isLessThan(times.day().msecs, times.hour().msecs, 'hours ago', 'h') - , timeago.isLessThan(times.days(2).msecs, times.day().msecs, 'day ago', 'd') - , timeago.isLessThan(times.week().msecs, times.day().msecs, 'days ago', 'd') - , function ( ) { return { label: 'long ago', shortLabel: 'ago' } } + timeago.isMissing, timeago.inTheFuture, timeago.almostInTheFuture, timeago.isLessThan(times.mins(2).msecs, times.min().msecs, 'min ago', 'm'), timeago.isLessThan(times.hour().msecs, times.min().msecs, 'mins ago', 'm'), timeago.isLessThan(times.hours(2).msecs, times.hour().msecs, 'hour ago', 'h'), timeago.isLessThan(times.day().msecs, times.hour().msecs, 'hours ago', 'h'), timeago.isLessThan(times.days(2).msecs, times.day().msecs, 'day ago', 'd'), timeago.isLessThan(times.week().msecs, times.day().msecs, 'days ago', 'd'), + function () { + return { + label: 'long ago', + shortLabel: 'ago' + } + } ]; - timeago.calcDisplay = function calcDisplay (entry, time) { + timeago.calcDisplay = function calcDisplay(entry, time) { var opts = { - time: time - , entry: entry + time: time, + entry: entry }; if (time && entry && entry.mills) { @@ -159,15 +174,16 @@ function init (ctx) { } }; - timeago.updateVisualisation = function updateVisualisation (sbx) { + timeago.updateVisualisation = function updateVisualisation(sbx) { var agoDisplay = timeago.calcDisplay(sbx.lastSGVEntry(), sbx.time); var inRetroMode = sbx.data.inRetroMode; sbx.pluginBase.updatePillText(timeago, { - value: inRetroMode ? null : agoDisplay.value - , label: inRetroMode ? translate('RETRO') : translate(agoDisplay.label) - //no warning/urgent class when in retro mode - , pillClass: inRetroMode ? 'current' : timeago.checkStatus(sbx) + value: inRetroMode ? null : agoDisplay.value, + label: inRetroMode ? translate('RETRO') : translate(agoDisplay.label) + //no warning/urgent class when in retro mode + , + pillClass: inRetroMode ? 'current' : timeago.checkStatus(sbx) }); }; diff --git a/lib/plugins/treatmentnotify.js b/lib/plugins/treatmentnotify.js index e108dfd0ca7..abb47c78dae 100644 --- a/lib/plugins/treatmentnotify.js +++ b/lib/plugins/treatmentnotify.js @@ -1,14 +1,15 @@ 'use strict'; -var _ = require('lodash'); -var times = require('../times'); -var simplealarms = require('./simplealarms')(); +const _ = require('lodash'); +const times = require('../times'); +const simplealarms = require('./simplealarms')(); +const crypto = require('crypto'); -var MANUAL_TREATMENTS = ['BG Check', 'Meal Bolus', 'Carb Correction', 'Correction Bolus']; +const MANUAL_TREATMENTS = ['BG Check', 'Meal Bolus', 'Carb Correction', 'Correction Bolus']; function init() { - var treatmentnotify = { + const treatmentnotify = { name: 'treatmentnotify' , label: 'Treatment Notifications' , pluginType: 'notification' @@ -102,26 +103,32 @@ function init() { if (lastTreatment.isAnnouncement) { requestAnnouncementNotify(lastTreatment, sbx); } else { - var message = buildTreatmentMessage(lastTreatment, sbx); + let message = buildTreatmentMessage(lastTreatment, sbx); - var eventType = lastTreatment.eventType; + let eventType = lastTreatment.eventType; if (lastTreatment.duration === 0 && eventType === 'Temporary Target') { eventType += ' Cancel'; message = translate('Canceled'); } - var timestamp = lastTreatment.timestamp; + const timestamp = lastTreatment.timestamp; if (!message) { message = '...'; } + + const hash = crypto.createHash('sha1'); + const info = JSON.stringify({ eventType, timestamp}); + hash.update(info); + const notifyhash = hash.digest('hex'); sbx.notifications.requestNotify({ level: sbx.levels.INFO , title: translate(eventType) - , message: message - , timestamp: timestamp + , message + , timestamp , plugin: treatmentnotify + , notifyhash }); } } diff --git a/lib/profilefunctions.js b/lib/profilefunctions.js index 94120d72f67..c15860bab26 100644 --- a/lib/profilefunctions.js +++ b/lib/profilefunctions.js @@ -2,31 +2,32 @@ var _ = require('lodash'); var moment = require('moment-timezone'); -var NodeCache = require('node-cache'); +var c = require('memory-cache'); var times = require('./times'); var crypto = require('crypto'); +var cacheTTL = 600; + var prevBasalTreatment = null; function init (profileData) { - var profile = { }; + var profile = {}; + var cache = new c.Cache(); - profile.timeValueCache = new NodeCache({ stdTTL: 600, checkperiod: 600 }); - profile.loadData = function loadData (profileData) { if (profileData && profileData.length) { - profile.data = profile.convertToProfileStore(profileData); + profile.data = profile.convertToProfileStore(profileData); _.each(profile.data, function eachProfileRecord (record) { _.each(record.store, profile.preprocessProfileOnLoad); record.mills = new Date(record.startDate).getTime(); }); } }; - + profile.convertToProfileStore = function convertToProfileStore (dataArray) { var convertedProfiles = []; - _.each(dataArray, function (profile) { + _.each(dataArray, function(profile) { if (!profile.defaultProfile) { var newObject = {}; newObject.defaultProfile = 'Default'; @@ -50,13 +51,13 @@ function init (profileData) { profile.timeStringToSeconds = function timeStringToSeconds (time) { var split = time.split(':'); - return parseInt(split[0])*3600 + parseInt(split[1])*60; + return parseInt(split[0]) * 3600 + parseInt(split[1]) * 60; }; // preprocess the timestamps to seconds for a couple orders of magnitude faster operation profile.preprocessProfileOnLoad = function preprocessProfileOnLoad (container) { _.each(container, function eachValue (value) { - if( Object.prototype.toString.call(value) === '[object Array]' ) { + if (Object.prototype.toString.call(value) === '[object Array]') { profile.preprocessProfileOnLoad(value); } @@ -66,7 +67,7 @@ function init (profileData) { } }); }; - + profile.getValueByTime = function getValueByTime (time, valueType, spec_profile) { if (!time) { time = Date.now(); } @@ -76,8 +77,8 @@ function init (profileData) { var activeTreatment = profile.activeProfileTreatmentToTime(time); var isCcpProfile = !spec_profile && activeTreatment && activeTreatment.CircadianPercentageProfile; if (isCcpProfile) { - percentage = activeTreatment.percentage; - timeshift = activeTreatment.timeshift; // in hours + percentage = activeTreatment.percentage; + timeshift = activeTreatment.timeshift; // in hours } var offset = timeshift % 24; time = time + offset * times.hours(offset).msecs; @@ -86,7 +87,7 @@ function init (profileData) { var minuteTime = Math.round(time / 60000) * 60000; var cacheKey = (minuteTime + valueType + spec_profile + profile.profiletreatments_hash); - var returnValue = profile.timeValueCache[cacheKey]; + var returnValue = cache.get(cacheKey); if (returnValue) { return returnValue; @@ -100,7 +101,7 @@ function init (profileData) { // TODO: Better warnings to user for missing configuration var t = profile.getTimezone(spec_profile) ? moment(minuteTime).tz(profile.getTimezone(spec_profile)) : moment(minuteTime); - + // Convert to seconds from midnight var mmtMidnight = t.clone().startOf('day'); var timeAsSecondsFromMidnight = t.clone().diff(mmtMidnight, 'seconds'); @@ -109,7 +110,7 @@ function init (profileData) { returnValue = valueContainer; - if( Object.prototype.toString.call(valueContainer) === '[object Array]' ) { + if (Object.prototype.toString.call(valueContainer) === '[object Array]') { _.each(valueContainer, function eachValue (value) { if (timeAsSecondsFromMidnight >= value.timeAsSeconds) { returnValue = value.value; @@ -117,22 +118,22 @@ function init (profileData) { }); } - if (returnValue) { - returnValue = parseFloat(returnValue); - if (isCcpProfile) { - switch (valueType) { - case "sens": - case "carbratio": - returnValue = returnValue * 100 / percentage; - break; - case "basal": - returnValue = returnValue * percentage / 100; - break; - } + if (returnValue) { + returnValue = parseFloat(returnValue); + if (isCcpProfile) { + switch (valueType) { + case "sens": + case "carbratio": + returnValue = returnValue * 100 / percentage; + break; + case "basal": + returnValue = returnValue * percentage / 100; + break; } + } } - profile.timeValueCache[cacheKey] = returnValue; + cache.put(cacheKey, returnValue, cacheTTL); return returnValue; }; @@ -185,27 +186,27 @@ function init (profileData) { }; profile.updateTreatments = function updateTreatments (profiletreatments, tempbasaltreatments, combobolustreatments) { - + profile.profiletreatments = profiletreatments || []; profile.tempbasaltreatments = tempbasaltreatments || []; - // dedupe temp basal events + // dedupe temp basal events profile.tempbasaltreatments = _.uniqBy(profile.tempbasaltreatments, 'mills'); - + _.each(profile.tempbasaltreatments, function addDuration (t) { - t.endmills = t.mills + times.mins(t.duration || 0).msecs; + t.endmills = t.mills + times.mins(t.duration || 0).msecs; + }); + + profile.tempbasaltreatments.sort(function compareTreatmentMills (a, b) { + return a.mills - b.mills; }); - - profile.tempbasaltreatments.sort (function compareTreatmentMills (a, b) { - return a.mills - b.mills; - }); profile.combobolustreatments = combobolustreatments || []; profile.profiletreatments_hash = crypto.createHash('sha1').update(JSON.stringify(profile.profiletreatments)).digest('hex'); profile.tempbasaltreatments_hash = crypto.createHash('sha1').update(JSON.stringify(profile.tempbasaltreatments)).digest('hex'); profile.combobolustreatments_hash = crypto.createHash('sha1').update(JSON.stringify(profile.combobolustreatments)).digest('hex'); }; - + profile.activeProfileToTime = function activeProfileToTime (time) { if (profile.hasData()) { var timeprofile = profile.data[0].defaultProfile; @@ -218,7 +219,7 @@ function init (profileData) { } return null; }; - + profile.activeProfileTreatmentToTime = function activeProfileTreatmentToTime (time) { var cacheKey = 'profile' + time + profile.profiletreatments_hash; //var returnValue = profile.timeValueCache[cacheKey]; @@ -230,78 +231,79 @@ function init (profileData) { var treatment = null; if (profile.hasData()) { - profile.profiletreatments.forEach( function eachTreatment (t) { - if (time >= t.mills && t.mills >= profile.data[0].mills) { - var duration = times.mins(t.duration || 0).msecs; - if (duration != 0 && time < t.mills + duration) { - treatment = t; - // if profile switch contains json of profile inject it in to store to be findable by profile name - if (treatment.profileJson && !profile.data[0].store[treatment.profile]) { - if (treatment.profile.indexOf("@@@@@") < 0) - treatment.profile += "@@@@@" + treatment.mills; - var json = JSON.parse(treatment.profileJson); - profile.data[0].store[treatment.profile] = json; - } + profile.profiletreatments.forEach(function eachTreatment (t) { + if (time >= t.mills && t.mills >= profile.data[0].mills) { + var duration = times.mins(t.duration || 0).msecs; + if (duration != 0 && time < t.mills + duration) { + treatment = t; + // if profile switch contains json of profile inject it in to store to be findable by profile name + if (treatment.profileJson && !profile.data[0].store[treatment.profile]) { + if (treatment.profile.indexOf("@@@@@") < 0) + treatment.profile += "@@@@@" + treatment.mills; + let json = JSON.parse(treatment.profileJson); + profile.data[0].store[treatment.profile] = json; } - if (duration == 0) { - treatment = t; - // if profile switch contains json of profile inject it in to store to be findable by profile name - if (treatment.profileJson && !profile.data[0].store[treatment.profile]) { - if (treatment.profile.indexOf("@@@@@") < 0) - treatment.profile += "@@@@@" + treatment.mills; - var json = JSON.parse(treatment.profileJson); - profile.data[0].store[treatment.profile] = json; - } + } + if (duration == 0) { + treatment = t; + // if profile switch contains json of profile inject it in to store to be findable by profile name + if (treatment.profileJson && !profile.data[0].store[treatment.profile]) { + if (treatment.profile.indexOf("@@@@@") < 0) + treatment.profile += "@@@@@" + treatment.mills; + let json = JSON.parse(treatment.profileJson); + profile.data[0].store[treatment.profile] = json; } } + } }); } - + returnValue = treatment; - profile.timeValueCache[cacheKey] = returnValue; + cache.put(cacheKey, returnValue, cacheTTL); return returnValue; }; - profile.profileSwitchName = function profileSwitchName(name) { + profile.profileSwitchName = function profileSwitchName (name) { var index = name.indexOf("@@@@@"); if (index < 0) return name; else return name.substring(0, index); } - + profile.tempBasalTreatment = function tempBasalTreatment (time) { - // Most queries for the data in reporting will match the latest found value, caching that hugely improves performance - if (prevBasalTreatment && time >= prevBasalTreatment.mills && time <= prevBasalTreatment.endmills) { - return prevBasalTreatment; - } - + // Most queries for the data in reporting will match the latest found value, caching that hugely improves performance + if (prevBasalTreatment && time >= prevBasalTreatment.mills && time <= prevBasalTreatment.endmills) { + return prevBasalTreatment; + } + // Binary search for events for O(log n) performance - var first = 0, last = profile.tempbasaltreatments.length - 1; - + var first = 0 + , last = profile.tempbasaltreatments.length - 1; + while (first <= last) { - var i = first + Math.floor((last - first) / 2); - var t = profile.tempbasaltreatments[i]; - if (time >= t.mills && time <= t.endmills) { - prevBasalTreatment = t; - return t; - } - if (time < t.mills) { - last = i - 1; - } else { - first = i + 1; - } + var i = first + Math.floor((last - first) / 2); + var t = profile.tempbasaltreatments[i]; + if (time >= t.mills && time <= t.endmills) { + prevBasalTreatment = t; + return t; + } + if (time < t.mills) { + last = i - 1; + } else { + first = i + 1; + } } - + return null; }; profile.comboBolusTreatment = function comboBolusTreatment (time) { var treatment = null; - profile.combobolustreatments.forEach( function eachTreatment (t) { - var duration = times.mins(t.duration || 0).msecs; - if (time < t.mills + duration && time > t.mills) { - treatment = t; - } + profile.combobolustreatments.forEach(function eachTreatment (t) { + var duration = times.mins(t.duration || 0).msecs; + if (time < t.mills + duration && time > t.mills) { + treatment = t; + } }); return treatment; }; @@ -309,7 +311,7 @@ function init (profileData) { profile.getTempBasal = function getTempBasal (time, spec_profile) { var cacheKey = 'basal' + time + profile.tempbasaltreatments_hash + profile.combobolustreatments_hash + profile.profiletreatments_hash + spec_profile; - var returnValue = profile.timeValueCache[cacheKey]; + var returnValue = cache.get(cacheKey); if (returnValue) { return returnValue; @@ -326,7 +328,7 @@ function init (profileData) { tempbasal = Number(treatment.absolute); } else if (treatment && treatment.percent) { tempbasal = basal * (100 + treatment.percent) / 100; - } + } if (combobolustreatment && combobolustreatment.relative) { combobolusbasal = combobolustreatment.relative; } @@ -338,7 +340,7 @@ function init (profileData) { , combobolusbasal: combobolusbasal , totalbasal: tempbasal + combobolusbasal }; - profile.timeValueCache[cacheKey] = returnValue; + cache.put(cacheKey, returnValue, cacheTTL); return returnValue; }; @@ -347,30 +349,14 @@ function init (profileData) { if (profile.hasData()) { var current = profile.activeProfileToTime(); profiles.push(current); - - for (var key in profile.data[0].store) { - if (profile.data[0].store.hasOwnProperty(key) && key !== current) { - if (key.indexOf('@@@@@') < 0) - profiles.push(key); - } - } - } - return profiles; - }; - // get original store without added profiles fro profileSwitches - profile.getProfileStore = function getProfileStore () { - var newprofiledata = _.clone(profile.data[0]); - for (var key in profile.data[0].store) { - if (profile.data[0].store.hasOwnProperty(key)) { - if (key.indexOf('@@@@@') < 0) - store[key] = profile.data[0].store[key]; - } + Object.keys(profile.data[0].store).forEach(key => { + if (key !== current && key.indexOf('@@@@@') < 0) profiles.push(key); + }) } - return store; + return profiles; }; - if (profileData) { profile.loadData(profileData); } // init treatments array profile.updateTreatments([], []); @@ -378,4 +364,4 @@ function init (profileData) { return profile; } -module.exports = init; \ No newline at end of file +module.exports = init; diff --git a/lib/report_plugins/calibrations.js b/lib/report_plugins/calibrations.js index f7088080690..958dd06c906 100644 --- a/lib/report_plugins/calibrations.js +++ b/lib/report_plugins/calibrations.js @@ -8,30 +8,29 @@ var calibrations = { , pluginType: 'report' }; -function init() { +function init () { return calibrations; } module.exports = init; -calibrations.html = function html(client) { +calibrations.html = function html (client) { var translate = client.translate; var ret = - '

' + translate('Calibrations') + '

' - + '
' - + '
' - ; + '

' + translate('Calibrations') + '

' + + '
' + + '
'; return ret; }; -calibrations.report = function report_calibrations(datastorage,sorteddaystoshow) { +calibrations.report = function report_calibrations (datastorage, sorteddaystoshow) { var Nightscout = window.Nightscout; var report_plugins = Nightscout.report_plugins; var padding = { top: 15, right: 15, bottom: 30, left: 70 }; var treatments = []; - sorteddaystoshow.forEach(function (day) { - treatments = treatments.concat(datastorage[day].treatments.filter(function (t) { + sorteddaystoshow.forEach(function(day) { + treatments = treatments.concat(datastorage[day].treatments.filter(function(t) { if (t.eventType === 'Sensor Start') { return true; } @@ -43,59 +42,58 @@ calibrations.report = function report_calibrations(datastorage,sorteddaystoshow) }); var cals = []; - sorteddaystoshow.forEach(function (day) { + sorteddaystoshow.forEach(function(day) { cals = cals.concat(datastorage[day].cal); }); var sgvs = []; - sorteddaystoshow.forEach(function (day) { + sorteddaystoshow.forEach(function(day) { sgvs = sgvs.concat(datastorage[day].sgv); }); - + var mbgs = []; - sorteddaystoshow.forEach(function (day) { + sorteddaystoshow.forEach(function(day) { mbgs = mbgs.concat(datastorage[day].mbg); }); - mbgs.forEach(function (mbg) { calcmbg(mbg); }); - + mbgs.forEach(function(mbg) { calcmbg(mbg); }); var events = treatments.concat(cals).concat(mbgs).sort(function(a, b) { return a.mills - b.mills; }); - - var colors = ['Aqua','Blue','Brown','Chartreuse','Coral','CornflowerBlue','DarkCyan','DarkMagenta','DarkOrange','Fuchsia','Green','Yellow']; + + var colors = ['Aqua', 'Blue', 'Brown', 'Chartreuse', 'Coral', 'CornflowerBlue', 'DarkCyan', 'DarkMagenta', 'DarkOrange', 'Fuchsia', 'Green', 'Yellow']; var colorindex = 0; var html = ''; var lastmbg = null; - for (var i=0; i'; - }; - + } + html += '
'; + html += '' + report_plugins.utils.localeDateTime(new Date(e.mills)) + ''; e.bgcolor = colors[colorindex]; if (e.eventType) { - html += ''+translate(e.eventType)+':
'; + html += '' + translate(e.eventType) + ':
'; } else if (typeof e.device !== 'undefined') { - html += ' '; - html += 'MBG: ' + e.y + ' Raw: '+e.raw+'
'; + html += ' '; + html += 'MBG: ' + e.y + ' Raw: ' + e.raw + '
'; lastmbg = e; e.cals = []; e.checked = false; } else if (typeof e.scale !== 'undefined') { html += 'CAL: ' + ' Scale: ' + e.scale.toFixed(2) + ' Intercept: ' + e.intercept.toFixed(0) + ' Slope: ' + e.slope.toFixed(2) + '
'; - if (lastmbg) { + if (lastmbg) { lastmbg.cals.push(e); } } else { html += JSON.stringify(e); } html += '
'; $('#calibrations-list').html(html); - + // select last 3 mbgs checkLastCheckboxes(3); drawelements(); @@ -103,27 +101,27 @@ calibrations.report = function report_calibrations(datastorage,sorteddaystoshow) $('.calibrations-checkbox').change(checkboxevent); function checkLastCheckboxes (maxcals) { - for (i=events.length-1; i>0; i--) { + for (i = events.length - 1; i > 0; i--) { if (typeof events[i].device !== 'undefined') { events[i].checked = true; - $('#calibrations-'+i).prop('checked',true); - if (--maxcals<1) { + $('#calibrations-' + i).prop('checked', true); + if (--maxcals < 1) { break; } } } } - - function checkboxevent(event) { + + function checkboxevent (event) { var index = $(this).attr('index'); events[index].checked = $(this).is(':checked'); drawelements(); event.preventDefault(); } - function drawelements() { + function drawelements () { drawChart(); - for (var i=0; i5*60*1000) { - console.log('Last SGV too old for MBG. Time diff: '+((mbg.mills-lastsgv.mills)/1000/60).toFixed(1)+' min',mbg); + if (mbg.mills - lastsgv.mills > 5 * 60 * 1000) { + console.log('Last SGV too old for MBG. Time diff: ' + ((mbg.mills - lastsgv.mills) / 1000 / 60).toFixed(1) + ' min', mbg); } else { mbg.raw = lastsgv.filtered || lastsgv.unfiltered; } } else { - console.log('Last entry not found for MBG ',mbg); + console.log('Last entry not found for MBG ', mbg); } } - - function drawmbg(mbg) { + + function drawmbg (mbg) { var color = mbg.bgcolor; if (mbg.raw) { calibration_context.append('circle') @@ -267,11 +265,11 @@ calibrations.report = function report_calibrations(datastorage,sorteddaystoshow) .attr('r', 5); } } - - function findlatest(date,storage) { + + function findlatest (date, storage) { var last = null; var time = date.getTime(); - for (var i=0; i time) { return last; } diff --git a/lib/report_plugins/dailystats.js b/lib/report_plugins/dailystats.js index 4cfd99f8450..2f9fa77a24a 100644 --- a/lib/report_plugins/dailystats.js +++ b/lib/report_plugins/dailystats.js @@ -6,41 +6,39 @@ var dailystats = { , pluginType: 'report' }; -function init() { +function init () { return dailystats; } module.exports = init; -dailystats.html = function html(client) { +dailystats.html = function html (client) { var translate = client.translate; var ret = - '

' + translate('Daily stats report') + '

' - + '
' - ; + '

' + translate('Daily stats report') + '

' + + '
'; return ret; }; dailystats.css = - '#dailystats-placeholder .tdborder {' - + ' width:80px;' - + ' border: 1px #ccc solid;' - + ' margin: 0;' - + ' padding: 1px;' - + ' text-align:center;' - + '}' - + '#dailystats-placeholder .inlinepiechart {' - + ' width: 2.0in;' - + ' height: 0.9in;' - + '}' - ; - -dailystats.report = function report_dailystats(datastorage,sorteddaystoshow,options) { + '#dailystats-placeholder .tdborder {' + + ' width:80px;' + + ' border: 1px #ccc solid;' + + ' margin: 0;' + + ' padding: 1px;' + + ' text-align:center;' + + '}' + + '#dailystats-placeholder .inlinepiechart {' + + ' width: 2.0in;' + + ' height: 0.9in;' + + '}'; + +dailystats.report = function report_dailystats (datastorage, sorteddaystoshow, options) { var Nightscout = window.Nightscout; var client = Nightscout.client; var translate = client.translate; var report_plugins = Nightscout.report_plugins; - + var ss = require('simple-statistics'); var todo = []; @@ -52,31 +50,31 @@ dailystats.report = function report_dailystats(datastorage,sorteddaystoshow,opti report.append(table); var thead = $('
'+translate('Date')+''+translate('Low')+''+translate('Normal')+''+translate('High')+''+translate('Readings')+''+translate('Min')+''+translate('Max')+''+translate('Average')+''+translate('StDev')+''+translate('25%')+''+translate('Median')+''+translate('75%')+'' + translate('Date') + '' + translate('Low') + '' + translate('Normal') + '' + translate('High') + '' + translate('Readings') + '' + translate('Min') + '' + translate('Max') + '' + translate('Average') + '' + translate('StDev') + '' + translate('25%') + '' + translate('Median') + '' + translate('75%') + '
').appendTo(tr); - $('' + report_plugins.utils.localeDate(day) + ''+translate('No data available')+'' + report_plugins.utils.localeDate(day) + '' + translate('No data available') + '
' + report_plugins.utils.localeDate(day) + '' + Math.round((100 * stats.lows) / daysRecords.length) + '%' + Math.round((100 * stats.normal) / daysRecords.length) + '%' + Math.round((100 * stats.highs) / daysRecords.length) + '%' + daysRecords.length +'' + minForDay +'' + maxForDay +'' + average.toFixed(1) +'' + ss.standard_deviation(bgValues).toFixed(1) + '' + ss.quantile(bgValues, 0.25).toFixed(1) + '' + ss.quantile(bgValues, 0.5).toFixed(1) + '' + ss.quantile(bgValues, 0.75).toFixed(1) + '
' + report_plugins.utils.localeDate(day) + '' + Math.round((100 * stats.lows) / daysRecords.length) + '%' + Math.round((100 * stats.normal) / daysRecords.length) + '%' + Math.round((100 * stats.highs) / daysRecords.length) + '%' + daysRecords.length + '' + minForDay + '' + maxForDay + '' + average.toFixed(1) + '' + ss.standard_deviation(bgValues).toFixed(1) + '' + ss.quantile(bgValues, 0.25).toFixed(1) + '' + ss.quantile(bgValues, 0.5).toFixed(1) + '' + ss.quantile(bgValues, 0.75).toFixed(1) + '
')); }); }; -daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) { +daytoday.report = function report_daytoday (datastorage, sorteddaystoshow, options) { var Nightscout = window.Nightscout; var client = Nightscout.client; var translate = client.translate; var profile = client.sbx.data.profile; var report_plugins = Nightscout.report_plugins; var scaledTreatmentBG = report_plugins.utils.scaledTreatmentBG; - + var TOOLTIP_TRANS_MS = 300; var padding = { top: 15, right: 22, bottom: 30, left: 35 }; var tddSum = 0; var carbsSum = 0; + var proteinSum = 0; + var fatSum = 0; - daytoday.prepareHtml(sorteddaystoshow) ; - sorteddaystoshow.forEach( function eachDay(day) { - drawChart(day,datastorage[day],options); + daytoday.prepareHtml(sorteddaystoshow); + sorteddaystoshow.forEach(function eachDay (day) { + drawChart(day, datastorage[day], options); }); var tddAverage = tddSum / datastorage.alldays; var carbsAverage = carbsSum / datastorage.alldays; + var proteinAverage = proteinSum / datastorage.alldays; + var fatAverage = fatSum / datastorage.alldays; if (options.insulindistribution) - $('#daytodaycharts').append('

' + translate('TDD average') + ': ' + tddAverage.toFixed(1) + 'U ' + translate('Carbs average') + ': ' + carbsAverage.toFixed(0) + 'g'); - - function timeTicks(n,i) { - var t12 = [ - '12am', '', '2am', '', '4am', '', '6am', '', '8am', '', '10am', '', - '12pm', '', '2pm', '', '4pm', '', '6pm', '', '8pm', '', '10pm', '', '12am' + $('#daytodaycharts').append('

' + translate('TDD average') + ': ' + tddAverage.toFixed(1) + 'U ' + + translate('Carbs average') + ': ' + carbsAverage.toFixed(0) + 'g' + + translate('Protein average') + ': ' + proteinAverage.toFixed(0) + 'g' + + translate('Fat average') + ': ' + fatAverage.toFixed(0) + 'g' + ); + + function timeTicks (n, i) { + var t12 = [ + '12am', '', '2am', '', '4am', '', '6am', '', '8am', '', '10am', '' + , '12pm', '', '2pm', '', '4pm', '', '6pm', '', '8pm', '', '10pm', '', '12am' ]; if (Nightscout.client.settings.timeFormat === 24) { return ('00' + i).slice(-2); @@ -112,28 +119,28 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) return t12[i]; } } - - function drawChart(day,data,options) { + + function drawChart (day, data, options) { var tickValues , charts , context , xScale2, yScale2 , yInsulinScale, yCarbsScale, yScaleBasals , xAxis2, yAxis2 - , dateFn = function (d) { return new Date(d.date); } + , dateFn = function(d) { return new Date(d.date); } , foodtexts = 0; - tickValues = client.ticks(client, { - scaleY: options.scale === report_plugins.consts.SCALE_LOG ? 'log' : 'linear' - , targetTop: options.targetHigh - , targetBottom: options.targetLow - }); - - // add defs for combo boluses - var dashWidth = 5; - d3.select('body').append('svg') - .append('defs') - .append('pattern') + tickValues = client.ticks(client, { + scaleY: options.scale === report_plugins.consts.SCALE_LOG ? 'log' : 'linear' + , targetTop: options.targetHigh + , targetBottom: options.targetLow + }); + + // add defs for combo boluses + var dashWidth = 5; + d3.select('body').append('svg') + .append('defs') + .append('pattern') .attr('id', 'hash') .attr('patternUnits', 'userSpaceOnUse') .attr('width', 6) @@ -141,24 +148,24 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) .attr('x', 0) .attr('y', 0) .append('g') - .style('fill', 'none') - .style('stroke', '#0099ff') - .style('stroke-width', 2) + .style('fill', 'none') + .style('stroke', '#0099ff') + .style('stroke-width', 2) .append('path').attr('d', 'M0,0 l' + dashWidth + ',' + dashWidth) .append('path').attr('d', 'M' + dashWidth + ',0 l-' + dashWidth + ',' + dashWidth); // create svg and g to contain the chart contents charts = d3.select('#daytodaychart-' + day).html( - ''+ - report_plugins.utils.localeDate(day)+ + '' + + report_plugins.utils.localeDate(day) + '
' - ).append('svg'); + ).append('svg'); charts.append('rect') .attr('width', '100%') .attr('height', '100%') .attr('fill', 'WhiteSmoke'); - + context = charts.append('g'); // define the parts of the axis that aren't dependent on width or height @@ -178,10 +185,10 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) .domain([-2 * options.maxInsulinValue, 2 * options.maxInsulinValue]); yCarbsScale = d3.scale.linear() - .domain([0, options.maxCarbsValue*1.25]); + .domain([0, options.maxCarbsValue * 1.25]); yScaleBasals = d3.scale.linear(); - + xAxis2 = d3.svg.axis() .scale(xScale2) .tickFormat(timeTicks) @@ -204,20 +211,20 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) //set the width and height of the SVG element charts.attr('width', options.width) .attr('height', options.height); - + // ranges are based on the width and height available so reset xScale2.range([0, chartWidth]); - yScale2.range([chartHeight,0]); + yScale2.range([chartHeight, 0]); yInsulinScale.range([chartHeight * 2, 0]); - yCarbsScale.range([chartHeight,0]); + yCarbsScale.range([chartHeight, 0]); yScaleBasals.range([yScale2(client.utils.scaleMgdl(72)), chartHeight]); // add target BG rect context.append('rect') - .attr('x', xScale2(dataRange[0])+padding.left) - .attr('y', yScale2(options.targetHigh)+padding.top) - .attr('width', xScale2(dataRange[1]- xScale2(dataRange[0]))) - .attr('height', yScale2(options.targetLow)-yScale2(options.targetHigh)) + .attr('x', xScale2(dataRange[0]) + padding.left) + .attr('y', yScale2(options.targetHigh) + padding.top) + .attr('width', xScale2(dataRange[1] - xScale2(dataRange[0]))) + .attr('height', yScale2(options.targetLow) - yScale2(options.targetHigh)) .style('fill', '#D6FFD6') .attr('stroke', 'grey'); @@ -244,72 +251,68 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) .style('fill', 'none') .call(xAxis2); - _.each(tickValues, function (n, li) { + _.each(tickValues, function(n, li) { context.append('line') .attr('class', 'high-line') - .attr('x1', xScale2(dataRange[0])+padding.left) - .attr('y1', yScale2(tickValues[li])+padding.top) - .attr('x2', xScale2(dataRange[1])+padding.left) - .attr('y2', yScale2(tickValues[li])+padding.top) + .attr('x1', xScale2(dataRange[0]) + padding.left) + .attr('y1', yScale2(tickValues[li]) + padding.top) + .attr('x2', xScale2(dataRange[1]) + padding.left) + .attr('y2', yScale2(tickValues[li]) + padding.top) .style('stroke-dasharray', ('1, 5')) .attr('stroke', 'grey'); }); - // bind up the context chart data to an array of circles - var contextCircles = context.selectAll('circle') - .data(data.sgv); - - function prepareContextCircles(sel) { + function prepareContextCircles (sel) { var badData = []; - sel.attr('cx', function (d) { - return xScale2(d.date) + padding.left; + sel.attr('cx', function(d) { + return xScale2(d.date) + padding.left; }) - .attr('cy', function (d) { - if (isNaN(d.sgv)) { - badData.push(d); - return yScale2(client.utils.scaleMgdl(450) + padding.top); - } else { - return yScale2(d.sgv) + padding.top; - } - }) - .attr('fill', function (d) { - if (d.color === 'gray' && !options.raw) { - return 'transparent'; - } - return d.color; - }) - .style('opacity', function () { return 0.5 }) - .attr('stroke-width', function (d) {if (d.type === 'mbg') { return 2; } else if (options.openAps && d.openaps) { return 1; } else { return 0; }}) - .attr('stroke', function () { return 'black'; }) - .attr('r', function(d) { - if (d.type === 'mbg') { - return 4; - } else { - return 2 + (options.width - 800) / 400; - } - }) - .on('mouseover', function (d) { - if (options.openAps && d.openaps) { - client.tooltip.transition().duration(TOOLTIP_TRANS_MS).style('opacity', .9); - var text = 'BG: ' + d.openaps.suggested.bg - + ', ' + d.openaps.suggested.reason - + (d.openaps.suggested.mealAssist ? ' Meal Assist: ' + d.openaps.suggested.mealAssist : ''); - client.tooltip.html(text) - .style('left', (d3.event.pageX) + 'px') - .style('top', (d3.event.pageY + 15) + 'px'); - } - }) - .on('mouseout', hideTooltip); - - if (badData.length > 0) { - console.warn('Bad Data: isNaN(sgv)', badData); + .attr('cy', function(d) { + if (isNaN(d.sgv)) { + badData.push(d); + return yScale2(client.utils.scaleMgdl(450) + padding.top); + } else { + return yScale2(d.sgv) + padding.top; + } + }) + .attr('fill', function(d) { + if (d.color === 'gray' && !options.raw) { + return 'transparent'; + } + return d.color; + }) + .style('opacity', function() { return 0.5 }) + .attr('stroke-width', function(d) { if (d.type === 'mbg') { return 2; } else if (options.openAps && d.openaps) { return 1; } else { return 0; } }) + .attr('stroke', function() { return 'black'; }) + .attr('r', function(d) { + if (d.type === 'mbg') { + return 4; + } else { + return 2 + (options.width - 800) / 400; + } + }) + .on('mouseover', function(d) { + if (options.openAps && d.openaps) { + client.tooltip.transition().duration(TOOLTIP_TRANS_MS).style('opacity', .9); + var text = 'BG: ' + d.openaps.suggested.bg + + ', ' + d.openaps.suggested.reason + + (d.openaps.suggested.mealAssist ? ' Meal Assist: ' + d.openaps.suggested.mealAssist : ''); + client.tooltip.html(text) + .style('left', (d3.event.pageX) + 'px') + .style('top', (d3.event.pageY + 15) + 'px'); } - return sel; + }) + .on('mouseout', hideTooltip); + + if (badData.length > 0) { + console.warn('Bad Data: isNaN(sgv)', badData); } + return sel; + } // PREDICTIONS START // - function preparePredictedData() { + function preparePredictedData () { var treatmentsTimestamps = []; // Only timestamps for (carbs and bolus insulin) treatments will be captured in this array treatmentsTimestamps.push(dataRange[0]); // Create a fake timestamp at midnight so we can show predictions during night @@ -324,14 +327,14 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) if (undefined != treatment.insulin && null != treatment.insulin && treatment.insulin > 0) { if (treatment.timestamp) treatmentsTimestamps.push(treatment.timestamp); - else if (treatment.created_at) - treatmentsTimestamps.push(treatment.created_at); + else if (treatment.created_at) + treatmentsTimestamps.push(treatment.created_at); } } var predictions = []; if (data && data.devicestatus) { - for (var i = data.devicestatus.length - 1; i >= 0; i--) { + for (i = data.devicestatus.length - 1; i >= 0; i--) { if (data.devicestatus[i].loop && data.devicestatus[i].loop.predicted) { predictions.push(data.devicestatus[i].loop.predicted); } else if (data.devicestatus[i].openaps && data.devicestatus[i].openaps.suggested && data.devicestatus[i].openaps.suggested.predBGs) { @@ -354,13 +357,16 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) // Iterate over all treatments, find the predictions for each and add them to the predicted array p for (var treatmentsIndex = 0; treatmentsIndex < treatmentsTimestamps.length; treatmentsIndex++) { var timestamp = treatmentsTimestamps[treatmentsIndex]; + // TODO refactor code so this is set here - now set as global in file loaded by the browser + // eslint-disable-next-line no-undef var predictedIndex = findPredicted(predictions, timestamp, predictedOffset); // Find predictions offset before or after timestamp if (predictedIndex != null) { - var entry = predictions[predictedIndex]; // Start entry + entry = predictions[predictedIndex]; // Start entry var d = moment(entry.startDate); var end = moment().endOf('day'); if (options.predictedTruncate) { + // eslint-disable-next-line no-undef if (predictedOffset >= 0) { // If we are looking forward we want to stop at the next treatment if (treatmentsIndex < treatmentsTimestamps.length - 1) { @@ -390,7 +396,7 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) /* Find the earliest new predicted instance that has a timestamp equal to or larger than timestamp */ /* (so if we have bolused or eaten we want to find the prediction that Loop has estimated just after that) */ /* Returns the index into the predictions array that is the predicted we are looking for */ - function findPredicted(predictions, timestamp, offset) { + function findPredicted (predictions, timestamp, offset) { var ts = moment(timestamp).add(offset, 'minutes'); var predicted = null; if (offset && offset < 0) { // If offset is negative, start searching from first prediction going forward @@ -399,8 +405,8 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) predicted = i; } } - } else { // If offset is positive or zero, start searching from last prediction going backward - for (var i = predictions.length - 1; i > 0; i--) { + } else { // If offset is positive or zero, start searching from last prediction going backward + for (i = predictions.length - 1; i > 0; i--) { if (predictions[i] && predictions[i].startDate && moment(predictions[i].startDate) >= ts) { predicted = i; } @@ -411,7 +417,6 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) // // PREDICTIONS ENDS - // bind up the context chart data to an array of circles var contextData = (options.predicted ? data.sgv.concat(preparePredictedData()) : data.sgv); var contextCircles = context.selectAll('circle').data(contextData); @@ -422,10 +427,11 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) contextCircles.exit() .remove(); - var to = moment(day).add(1, 'days'); - var from = moment(day); - var iobpolyline = '', cobpolyline = ''; - + var to = moment(day).add(1, 'days'); + var from = moment(day); + var iobpolyline = '' + , cobpolyline = ''; + // basals data var linedata = []; var notemplinedata = []; @@ -439,13 +445,13 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) data.netBasalPositive = []; data.netBasalNegative = []; - [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23].forEach(function(hour) { + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23].forEach(function(hour) { data.netBasalPositive[hour] = 0; data.netBasalNegative[hour] = 0; }); profile.updateTreatments(datastorage.profileSwitchTreatments, datastorage.tempbasalTreatments, datastorage.combobolusTreatments); - + var bolusInsulin = 0; var baseBasalInsulin = 0; var positiveTemps = 0; @@ -460,9 +466,9 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) console.log("Device COB status available: ", cobStatusAvailable); console.log("Device IOB status available: ", iobStatusAvailable); - for (var dt=moment(from); dt < to; dt.add(5, 'minutes')) { + for (var dt = moment(from); dt < to; dt.add(5, 'minutes')) { if (options.iob && !iobStatusAvailable) { - var iob = client.plugins('iob').calcTotal(datastorage.treatments,datastorage.devicestatus,profile,dt.toDate()).iob; + var iob = client.plugins('iob').calcTotal(datastorage.treatments, datastorage.devicestatus, profile, dt.toDate()).iob; // make the graph discontinuous when data is missing if (iob === undefined) { iobpolyline += ', ' + (xScale2(lastDt) + padding.left) + ',' + (yInsulinScale(0) + padding.top); @@ -471,19 +477,19 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) if (lastIOB === undefined) { iobpolyline += ', ' + (xScale2(dt) + padding.left) + ',' + (yInsulinScale(0) + padding.top); } - iobpolyline += ', '+ (xScale2(dt) + padding.left) + ',' + (yInsulinScale(iob) + padding.top); + iobpolyline += ', ' + (xScale2(dt) + padding.left) + ',' + (yInsulinScale(iob) + padding.top); } lastDt = dt.clone(); lastIOB = iob; } if (options.cob && !cobStatusAvailable) { - var cob = client.plugins('cob').cobTotal(datastorage.treatments,datastorage.devicestatus,profile,dt.toDate()).cob; + var cob = client.plugins('cob').cobTotal(datastorage.treatments, datastorage.devicestatus, profile, dt.toDate()).cob; if (!dt.isSame(from)) { cobpolyline += ', '; } cobpolyline += (xScale2(dt.toDate()) + padding.left) + ',' + (yCarbsScale(cob) + padding.top) + ' '; } - if (options.basal) { + if (options.basal) { var date = dt.format('x'); var hournow = dt.hour(); var basalvalue = profile.getTempBasal(date); @@ -493,26 +499,27 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) if (tempPart > 0) { positiveTemps += tempPart; data.netBasalPositive[hournow] += tempPart; - } if (tempPart < 0) { + } + if (tempPart < 0) { negativeTemps += tempPart; data.netBasalNegative[hournow] += tempPart; } - + if (!_.isEqual(lastbasal, basalvalue)) { - linedata.push( { d: date, b: basalvalue.totalbasal } ); - notemplinedata.push( { d: date, b: basalvalue.basal } ); + linedata.push({ d: date, b: basalvalue.totalbasal }); + notemplinedata.push({ d: date, b: basalvalue.basal }); if (basalvalue.combobolustreatment && basalvalue.combobolustreatment.relative) { - tempbasalareadata.push( { d: date, b: basalvalue.tempbasal } ); - basalareadata.push( { d: date, b: 0 } ); - comboareadata.push( { d: date, b: basalvalue.totalbasal } ); + tempbasalareadata.push({ d: date, b: basalvalue.tempbasal }); + basalareadata.push({ d: date, b: 0 }); + comboareadata.push({ d: date, b: basalvalue.totalbasal }); } else if (basalvalue.treatment) { - tempbasalareadata.push( { d: date, b: basalvalue.totalbasal } ); - basalareadata.push( { d: date, b: 0 } ); - comboareadata.push( { d: date, b: 0 } ); + tempbasalareadata.push({ d: date, b: basalvalue.totalbasal }); + basalareadata.push({ d: date, b: 0 }); + comboareadata.push({ d: date, b: 0 }); } else { - tempbasalareadata.push( { d: date, b: 0 } ); - basalareadata.push( { d: date, b: basalvalue.totalbasal } ); - comboareadata.push( { d: date, b: 0 } ); + tempbasalareadata.push({ d: date, b: 0 }); + basalareadata.push({ d: date, b: basalvalue.totalbasal }); + comboareadata.push({ d: date, b: 0 }); } } lastbasal = basalvalue; @@ -543,8 +550,8 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) // Draw IOB from devicestatuses if available if (iobStatusAvailable) { - var lastdate = 0; - var previousdate = 0; + lastdate = 0; + previousdate = 0; var iobArray = client.plugins('iob').IOBDeviceStatusesInTimeRange(datastorage.devicestatus, from.valueOf(), to.valueOf()); _.each(iobArray, function drawCob (point) { if (previousdate !== 0 && point.mills - previousdate > times.mins(15).msecs) { @@ -568,24 +575,24 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) .attr('stroke', 'blue') .attr('opacity', '0.5') .attr('fill-opacity', '0.1') - .attr('points',iobpolyline); - } + .attr('points', iobpolyline); + } if (options.cob) { context.append('polyline') .attr('stroke', 'red') .attr('opacity', '0.5') .attr('fill-opacity', '0.1') - .attr('points',cobpolyline); + .attr('points', cobpolyline); } if (options.basal) { var toTempBasal = profile.getTempBasal(to.format('x')); - linedata.push( { d: to.format('x'), b: toTempBasal.totalbasal } ); - notemplinedata.push( { d: to.format('x'), b: toTempBasal.basal } ); - basalareadata.push( { d: to.format('x'), b: toTempBasal.basal } ); - tempbasalareadata.push( { d: to.format('x'), b: toTempBasal.totalbasal } ); - comboareadata.push( { d: to.format('x'), b: toTempBasal.totalbasal } ); + linedata.push({ d: to.format('x'), b: toTempBasal.totalbasal }); + notemplinedata.push({ d: to.format('x'), b: toTempBasal.basal }); + basalareadata.push({ d: to.format('x'), b: toTempBasal.basal }); + tempbasalareadata.push({ d: to.format('x'), b: toTempBasal.totalbasal }); + comboareadata.push({ d: to.format('x'), b: toTempBasal.totalbasal }); var basalMax = d3.max(linedata, function(d) { return d.b; }); basalMax = Math.max(basalMax, d3.max(basalareadata, function(d) { return d.b; })); @@ -648,7 +655,7 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) .attr('stroke-width', 1) .attr('d', area); - datastorage.tempbasalTreatments.forEach(function (t) { + datastorage.tempbasalTreatments.forEach(function(t) { // only if basal and focus interval overlap and there is a chance to fit if (t.mills < to.format('x') && t.mills + times.mins(t.duration).msecs > from.format('x')) { var text = g.append('text') @@ -658,9 +665,9 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) .attr('fill', '#0099ff') .attr('text-anchor', 'middle') .attr('dy', '.35em') - .attr('x', xScale2((Math.max(t.mills, from.format('x')) + Math.min(t.mills + times.mins(t.duration).msecs, to.format('x')))/2) + padding.left) + .attr('x', xScale2((Math.max(t.mills, from.format('x')) + Math.min(t.mills + times.mins(t.duration).msecs, to.format('x'))) / 2) + padding.left) .attr('y', yScaleBasals(0) - 10 + padding.top) -// .text((t.percent ? (t.percent > 0 ? '+' : '') + t.percent + '%' : '') + (t.absolute ? Number(t.absolute).toFixed(2) + 'U' : '')); + // .text((t.percent ? (t.percent > 0 ? '+' : '') + t.percent + '%' : '') + (t.absolute ? Number(t.absolute).toFixed(2) + 'U' : '')); // better hide if not fit if (text.node().getBBox().width > xScale2(t.mills + times.mins(t.duration).msecs) - xScale2(t.mills)) { text.attr('display', 'none'); @@ -669,8 +676,7 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) }); } - - data.treatments.forEach(function (treatment) { + data.treatments.forEach(function(treatment) { // Calculate bolus stats if (treatment.insulin) { bolusInsulin += treatment.insulin; @@ -689,10 +695,10 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) var drawpointer = false; if (treatment.boluscalc && treatment.boluscalc.foods && treatment.boluscalc.foods.length > 0 && options.food) { var foods = treatment.boluscalc.foods; - for (var fi=0; fi
' + translate('Total basal insulin:') + '' + totalBasalInsulin.toFixed(1) + 'U
' + translate('Total daily insulin:') + '' + totalDailyInsulin.toFixed(1) + 'U
' + translate('Total carbs') + ':' + data.dailyCarbs + ' g
' + translate('Total protein') + ':' + data.dailyProtein + ' g
' + translate('Total fat') + ':' + data.dailyFat + ' g
' + - '' + - '' + - '' + - '' + - '
' + - '
' + - '
' + - '
' + - '* ' + translate('This is only a rough estimation that can be very inaccurate and does not replace actual blood testing. The formula used is taken from:') + - 'Nathan, David M., et al. "Translating the A1C assay into estimated average glucose values." Diabetes care 31.8 (2008): 1473-1478.' + '

' + - translate('Time in fluctuation and Time in rapid fluctuation measure the % of time during the examined period, during which the blood glucose has been changing relatively fast or rapidly. Lower values are better.') + '

' + - translate('Mean Total Daily Change is a sum of the absolute value of all glucose excursions for the examined period, divided by the number of days. Lower is better.')+ '

' + - translate('Mean Hourly Change is a sum of the absolute value of all glucose excursions for the examined period, divided by the number of hours in the period. Lower is better.')+ '

' + - translate('Out of Range RMS is calculated by squaring the distance out of range for all glucose readings for the examined period, summing them, dividing by the count and taking the square root. This metric is similar to in-range percentage but weights readings far out of range higher. Lower values are better.')+ '

' + - translate('GVI (Glycemic Variability Index) and PGS (Patient Glycemic Status) are measures developed by Dexcom, detailed can be found here.')+ - '


' + - translate('Filter by hours') + ':' + - '
' + - '0' + - '1' + - '2' + - '3' + - '4' + - '5' + - '6' + - '7' + - '8' + - '9' + - '10' + - '11' + - '12' + - '13' + - '14' + - '15' + - '16' + - '17' + - '18' + - '19' + - '20' + - '21' + - '22' + - '23' - - ; - return ret; +glucosedistribution.html = function html (client) { + var translate = client.translate; + var ret = + '

' + + translate('Glucose distribution') + + ' (' + + ' ' + + ' )' + + '

' + + '' + + '' + + '' + + '' + + '' + + '
' + + '
' + + '
' + + '
' + + '* ' + translate('This is only a rough estimation that can be very inaccurate and does not replace actual blood testing. The formula used is taken from:') + + 'Nathan, David M., et al. "Translating the A1C assay into estimated average glucose values." Diabetes care 31.8 (2008): 1473-1478.' + '

' + + translate('Time in fluctuation and Time in rapid fluctuation measure the % of time during the examined period, during which the blood glucose has been changing relatively fast or rapidly. Lower values are better.') + '

' + + translate('Mean Total Daily Change is a sum of the absolute value of all glucose excursions for the examined period, divided by the number of days. Lower is better.') + '

' + + translate('Mean Hourly Change is a sum of the absolute value of all glucose excursions for the examined period, divided by the number of hours in the period. Lower is better.') + '

' + + translate('Out of Range RMS is calculated by squaring the distance out of range for all glucose readings for the examined period, summing them, dividing by the count and taking the square root. This metric is similar to in-range percentage but weights readings far out of range higher. Lower values are better.') + '

' + + translate('GVI (Glycemic Variability Index) and PGS (Patient Glycemic Status) are measures developed by Dexcom, detailed can be found here.') + + '


' + + translate('Filter by hours') + ':' + + '
' + + '0' + + '1' + + '2' + + '3' + + '4' + + '5' + + '6' + + '7' + + '8' + + '9' + + '10' + + '11' + + '12' + + '13' + + '14' + + '15' + + '16' + + '17' + + '18' + + '19' + + '20' + + '21' + + '22' + + '23'; + return ret; }; glucosedistribution.css = - '#glucosedistribution-overviewchart {' + - ' width: 2.4in;' + - ' height: 2.4in;' + - '}' + - '#glucosedistribution-placeholder .tdborder {' + - ' width:80px;' + - ' border: 1px #ccc solid;' + - ' margin: 0;' + - ' padding: 1px;' + - ' text-align:center;' + - '}'; - - - -glucosedistribution.report = function report_glucosedistribution(datastorage, sorteddaystoshow, options) { - var Nightscout = window.Nightscout; - var client = Nightscout.client; - var translate = client.translate; - var displayUnits = Nightscout.client.settings.units; - - var ss = require('simple-statistics'); - - var colors = ['#f88', '#8f8', '#ff8']; - var tablecolors = { - Low: '#f88', - Normal: '#8f8', - High: '#ff8' - }; - - var enabledHours = [true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true]; - - var report = $('#glucosedistribution-report'); - report.empty(); - - var stability = $('#glucosedistribution-stability'); - stability.empty(); - - var stats = []; - var table = $(''); - var thead = $(''); - $('').appendTo(thead); - $('').appendTo(thead); - $('').appendTo(thead); - $('').appendTo(thead); - $('').appendTo(thead); - $('').appendTo(thead); - $('').appendTo(thead); - thead.appendTo(table); - - var data = datastorage.allstatsrecords; - var days = datastorage.alldays; - - $('#glucosedistribution-days').text(days + ' ' + translate('days total')); - - for (var i = 0; i < 23; i++) { - $('#glucosedistribution-' + i).unbind('click').click(onClick); - enabledHours[i] = $('#glucosedistribution-' + i).is(':checked'); + '#glucosedistribution-overviewchart {' + + ' width: 2.4in;' + + ' height: 2.4in;' + + '}' + + '#glucosedistribution-placeholder .tdborder {' + + ' width:80px;' + + ' border: 1px #ccc solid;' + + ' margin: 0;' + + ' padding: 1px;' + + ' text-align:center;' + + '}'; + +glucosedistribution.report = function report_glucosedistribution (datastorage, sorteddaystoshow, options) { + var Nightscout = window.Nightscout; + var client = Nightscout.client; + var translate = client.translate; + var displayUnits = Nightscout.client.settings.units; + + var ss = require('simple-statistics'); + + var colors = ['#f88', '#8f8', '#ff8']; + var tablecolors = { + Low: '#f88' + , Normal: '#8f8' + , High: '#ff8' + }; + + var enabledHours = [true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true]; + + var report = $('#glucosedistribution-report'); + report.empty(); + + var stability = $('#glucosedistribution-stability'); + stability.empty(); + + var stats = []; + var table = $('
' + translate('Range') + '' + translate('% of Readings') + '' + translate('# of Readings') + '' + translate('Average') + '' + translate('Median') + '' + translate('Standard Deviation') + '' + translate('A1c estimation*') + '
'); + var thead = $(''); + $('').appendTo(thead); + $('').appendTo(thead); + $('').appendTo(thead); + $('').appendTo(thead); + $('').appendTo(thead); + $('').appendTo(thead); + $('').appendTo(thead); + thead.appendTo(table); + + var data = datastorage.allstatsrecords; + var days = datastorage.alldays; + + $('#glucosedistribution-days').text(days + ' ' + translate('days total')); + + for (var i = 0; i < 23; i++) { + $('#glucosedistribution-' + i).unbind('click').click(onClick); + enabledHours[i] = $('#glucosedistribution-' + i).is(':checked'); + } + + var result = {}; + + // Filter data for noise + // data cleaning pass 0 - remove duplicates and non-sgv entries, sort + var seen = []; + data = data.filter(function(item) { + if (!item.sgv || !item.bgValue || !item.displayTime || item.bgValue < 39) { + console.log(item); + return false; } + return seen.includes(item.displayTime) ? false : (seen[item.displayTime] = true); + }); - //console.log(enabledHours); + data.sort(function(a, b) { + return a.displayTime.getTime() - b.displayTime.getTime(); + }); - var result = {}; + var glucose_data = [data[0]]; - // Filter data for noise - - var glucose_data = [data[0]]; + // data cleaning pass 1 - add interpolated missing points + for (i = 0; i <= data.length - 2; i++) { + var entry = data[i]; + var nextEntry = data[i + 1]; - // data cleaning pass 0 - remove duplicates and sort - - var seen = {}; - data = data.filter(function(item) { - return seen.hasOwnProperty(item.displayTime) ? false : (seen[item.displayTime] = true); - }); + var timeDelta = nextEntry.displayTime.getTime() - entry.displayTime.getTime(); - data.sort(function(a,b){ - return a.displayTime.getTime()-b.displayTime.getTime(); - }); + if (timeDelta < 9 * 60 * 1000 || timeDelta > 25 * 60 * 1000) { + glucose_data.push(entry); + continue; + } - // data cleaning pass 1 - add interpolated missing points + var missingRecords = Math.floor(timeDelta / (5 * 60 * 990)) - 1; - for (var i = 0; i < data.length - 2; i++) { + var timePatch = Math.floor(timeDelta / (missingRecords + 1)); + var bgDelta = (nextEntry.bgValue - entry.bgValue) / (missingRecords + 1); - var entry = data[i]; - var nextEntry = data[i + 1]; + glucose_data.push(entry); - var timeDelta = nextEntry.displayTime.getTime() - entry.displayTime.getTime(); + for (var j = 1; j <= missingRecords; j++) { + var bg = Math.floor(entry.bgValue + bgDelta * j); + var t = new Date(entry.displayTime.getTime() + j * timePatch); + var newEntry = { + sgv: displayUnits === 'mmol' ? bg / 18 : bg + , bgValue: bg + , displayTime: t + }; + glucose_data.push(newEntry); + } + } + // Need to add the last record, after interpolating between points + glucose_data.push(data[data.length - 1]); - if (timeDelta < 9 * 60 * 1000 ||  timeDelta > 25 * 60 * 1000) { - glucose_data.push(entry); - continue; - } + // data cleaning pass 2 - replace single jumpy measures with interpolated values + var glucose_data2 = [glucose_data[0]]; + var prevEntry = glucose_data[0]; - var missingRecords = Math.floor(timeDelta / (5 * 60 * 990)) -1; + const maxGap = (5 * 60 * 1000) + 10000; - var timePatch = Math.floor(timeDelta / (missingRecords + 1)); - var bgDelta = (nextEntry.bgValue - entry.bgValue) / (missingRecords + 1); + for (i = 1; i <= glucose_data.length - 2; i++) { + let entry = glucose_data[i]; + let nextEntry = glucose_data[i + 1]; - glucose_data.push(entry); + let timeDelta = nextEntry.displayTime.getTime() - entry.displayTime.getTime(); + let timeDelta2 = entry.displayTime.getTime() - prevEntry.displayTime.getTime(); - for (var j = 1; j <= missingRecords; j++) { - - var bg = Math.floor(entry.bgValue + bgDelta * j); - var t = new Date(entry.displayTime.getTime() + j * timePatch); - var newEntry = { - bgValue: bg, - displayTime: t - }; - glucose_data.push(newEntry); - } + if (timeDelta > maxGap || timeDelta2 > maxGap) { + glucose_data2.push(entry); + prevEntry = entry; + continue; + } + + var delta1 = entry.bgValue - prevEntry.bgValue; + var delta2 = nextEntry.bgValue - entry.bgValue; + if (delta1 <= 8 && delta2 <= 8) { + glucose_data2.push(entry); + prevEntry = entry; + continue; } - // data cleaning pass 2 - replace single jumpy measures with interpolated values - - var glucose_data2 = [glucose_data[0]]; - - var prevEntry = glucose_data[0]; - - const maxGap = (5 * 60 * 1000) + 10000; - - for (var i = 1; i < glucose_data.length-2; i++) { - -// var prevEntry = glucose_data[i-1]; - var entry = glucose_data[i]; - var nextEntry = glucose_data[i+1]; - - var timeDelta = nextEntry.displayTime.getTime() - entry.displayTime.getTime(); - var timeDelta2 = entry.displayTime.getTime() - prevEntry.displayTime.getTime(); - - if (timeDelta > maxGap || timeDelta2 > maxGap ) { - glucose_data2.push(entry); - prevEntry = entry; - continue; - } - - var delta1 = entry.bgValue - prevEntry.bgValue; - var delta2 = nextEntry.bgValue - entry.bgValue; - - if (delta1 <= 8 && delta2 <= 8) { - glucose_data2.push(entry); - prevEntry = entry; - continue; - } - - - if ((delta1 > 0 && delta2 <0) || (delta1 < 0 && delta2 > 0)) { - var d = (nextEntry.bgValue - prevEntry.bgValue) / 2; - var newEntry = { - bgValue: prevEntry.bgValue + d, - displayTime: entry.displayTime - }; - glucose_data2.push(newEntry); - prevEntry = newEntry; - continue; - - } - - glucose_data2.push(entry); - prevEntry = entry; - } - - glucose_data = data = glucose_data2.filter(function(r) { - return enabledHours[new Date(r.displayTime).getHours()] + if ((delta1 > 0 && delta2 < 0) || (delta1 < 0 && delta2 > 0)) { + const d = (nextEntry.bgValue - prevEntry.bgValue) / 2; + const interpolatedValue = prevEntry.bgValue + d; + + let newEntry = { + sgv: displayUnits === 'mmol' ? interpolatedValue / 18 : interpolatedValue + , bgValue: interpolatedValue + , displayTime: entry.displayTime + }; + glucose_data2.push(newEntry); + prevEntry = newEntry; + continue; + } + + glucose_data2.push(entry); + prevEntry = entry; + } + // Need to add the last record, after interpolating between points + glucose_data2.push(glucose_data[glucose_data.length - 1]); + + glucose_data = data = glucose_data2.filter(function(r) { + return enabledHours[new Date(r.displayTime).getHours()] + }); + + glucose_data.sort(function(a, b) { + return a.displayTime.getTime() - b.displayTime.getTime(); + }); + + var timeTotal = 0; + for (i = 1; i <= glucose_data.length - 2; i++) { + let entry = glucose_data[i]; + let nextEntry = glucose_data[i + 1]; + let timeDelta = nextEntry.displayTime.getTime() - entry.displayTime.getTime(); + if (timeDelta < maxGap) { + timeTotal += timeDelta; + } + } + + var daysTotal = timeTotal / (1000 * 60 * 60 * 24); + + ['Low', 'Normal', 'High'].forEach(function(range) { + result[range] = {}; + var r = result[range]; + r.rangeRecords = glucose_data.filter(function(r) { + if (range === 'Low') { + return r.sgv > 0 && r.sgv < options.targetLow; + } else if (range === 'Normal') { + return r.sgv >= options.targetLow && r.sgv < options.targetHigh; + } else { + return r.sgv >= options.targetHigh; + } }); - - glucose_data.sort(function(a,b){ - return a.displayTime.getTime()-b.displayTime.getTime(); + stats.push(r.rangeRecords.length); + r.rangeRecords.sort(function(a, b) { + return a.sgv - b.sgv; }); - - var timeTotal = 0; - - for (var i = 1; i < glucose_data.length-2; i++) { - var entry = glucose_data[i]; - var nextEntry = glucose_data[i+1]; - var timeDelta = nextEntry.displayTime.getTime() - entry.displayTime.getTime(); - if (timeDelta < maxGap) { - timeTotal += timeDelta; - } - } - - var daysTotal = timeTotal / (1000*60*60*24); - - ['Low', 'Normal', 'High'].forEach(function(range) { - result[range] = {}; - var r = result[range]; - r.rangeRecords = glucose_data.filter(function(r) { - if (range === 'Low') { - return r.sgv > 0 && r.sgv < options.targetLow; - } else if (range === 'Normal') { - return r.sgv >= options.targetLow && r.sgv < options.targetHigh; - } else { - return r.sgv >= options.targetHigh; - } - }); - stats.push(r.rangeRecords.length); - r.rangeRecords.sort(function(a, b) { - return a.sgv - b.sgv; - }); - r.localBgs = r.rangeRecords.map(function(r) { - return r.sgv; - }).filter(function(bg) { - return !!bg; - }); - r.midpoint = Math.floor(r.rangeRecords.length / 2); - r.readingspct = (100 * r.rangeRecords.length / data.length).toFixed(1); - if (r.rangeRecords.length > 0) { - r.mean = Math.floor(10 * ss.mean(r.localBgs)) / 10; - r.median = r.rangeRecords[r.midpoint].sgv; - r.stddev = Math.floor(ss.standard_deviation(r.localBgs) * 10) / 10; - } + r.localBgs = r.rangeRecords.map(function(r) { + return r.sgv; + }).filter(function(bg) { + return !!bg; }); + r.midpoint = Math.floor(r.rangeRecords.length / 2); + r.readingspct = (100 * r.rangeRecords.length / data.length).toFixed(1); + if (r.rangeRecords.length > 0) { + r.mean = Math.floor(10 * ss.mean(r.localBgs)) / 10; + r.median = r.rangeRecords[r.midpoint].sgv; + r.stddev = Math.floor(ss.standard_deviation(r.localBgs) * 10) / 10; + } + }); - // make sure we have total 100% - result.Normal.readingspct = (100 - result.Low.readingspct - result.High.readingspct).toFixed(1); - - ['Low', 'Normal', 'High'].forEach(function(range) { - var tr = $(''); - var r = result[range]; - - var rangeExp = ''; - - if (range == 'Low') { - rangeExp = ' (<' + options.targetLow + ')'; - } - if (range == 'High') { - rangeExp = ' (>=' + options.targetHigh + ')'; - } + // make sure we have total 100% + result.Normal.readingspct = (100 - result.Low.readingspct - result.High.readingspct).toFixed(1); - $('').appendTo(tr); - $('').appendTo(tr); - $('').appendTo(tr); - if (r.rangeRecords.length > 0) { - $('').appendTo(tr); - $('').appendTo(tr); - $('').appendTo(tr); - $('').appendTo(tr); - } else { - $('').appendTo(tr); - $('').appendTo(tr); - $('').appendTo(tr); - $('').appendTo(tr); - } + ['Low', 'Normal', 'High'].forEach(function(range) { + var tr = $(''); + var r = result[range]; - table.append(tr); - }); + var rangeExp = ''; + if (range == 'Low') { + rangeExp = ' (<' + options.targetLow + ')'; + } + if (range == 'High') { + rangeExp = ' (>=' + options.targetHigh + ')'; + } - var tr = $(''); - $('').appendTo(tr); - $('').appendTo(tr); - $('').appendTo(tr); - if (glucose_data.length > 0) { - var localBgs = glucose_data.map(function(r) { - return r.sgv; - }).filter(function(bg) { - return !!bg; - }); - var mgDlBgs = glucose_data.map(function(r) { - return r.bgValue; - }).filter(function(bg) { - return !!bg; - }); - $('').appendTo(tr); - $('').appendTo(tr); - $('').appendTo(tr); - $('').appendTo(tr); + $('').appendTo(tr); + $('').appendTo(tr); + $('').appendTo(tr); + if (r.rangeRecords.length > 0) { + $('').appendTo(tr); + $('').appendTo(tr); + $('').appendTo(tr); + $('').appendTo(tr); } else { - $('').appendTo(tr); - $('').appendTo(tr); - $('').appendTo(tr); - $('').appendTo(tr); + $('').appendTo(tr); + $('').appendTo(tr); + $('').appendTo(tr); + $('').appendTo(tr); } - table.append(tr); - report.append(table); - - // Stability - - var t1 = 6; - var t2 = 11; - var t1count = 0; - var t2count = 0; - - var total = 0; - var events = 0; - - var GVITotal = 0; - var GVIIdeal = 0; - - var RMSTotal = 0; - - var usedRecords = 0; - var glucoseTotal = 0; - var deltaTotal = 0; - - for (var i = 0; i < glucose_data.length - 2; i++) { - - var entry = glucose_data[i]; - var nextEntry = glucose_data[i + 1]; - - var timeDelta = nextEntry.displayTime.getTime() - entry.displayTime.getTime(); + table.append(tr); + }); + + var tr = $(''); + $('').appendTo(tr); + $('').appendTo(tr); + $('').appendTo(tr); + if (glucose_data.length > 0) { + var localBgs = glucose_data.map(function(r) { + return r.sgv; + }).filter(function(bg) { + return !!bg; + }); + var mgDlBgs = glucose_data.map(function(r) { + return r.bgValue; + }).filter(function(bg) { + return !!bg; + }); + $('').appendTo(tr); + $('').appendTo(tr); + $('').appendTo(tr); + $('').appendTo(tr); + } else { + $('').appendTo(tr); + $('').appendTo(tr); + $('').appendTo(tr); + $('').appendTo(tr); + } + table.append(tr); + report.append(table); + + // Stability + var t1 = 6; + var t2 = 11; + var t1count = 0; + var t2count = 0; + + var events = 0; + + var GVITotal = 0; + var GVIIdeal = 0; + var GVIIdeal_Time = 0; + + var RMSTotal = 0; + + var usedRecords = 0; + var glucoseTotal = 0; + var deltaTotal = 0; + + for (i = 0; i <= glucose_data.length - 2; i++) { + const entry = glucose_data[i]; + const nextEntry = glucose_data[i + 1]; + const timeDelta = nextEntry.displayTime.getTime() - entry.displayTime.getTime(); + + // Use maxGap constant + if (timeDelta == 0 || timeDelta > maxGap) { // 6 * 60 * 1000) { + // console.log("Record skipped"); + continue; + } - if (timeDelta > 6 * 60 * 1000) { -// console.log("Record skipped"); - continue; - } - - usedRecords += 1; + usedRecords += 1; + events += 1; + + var delta = Math.abs(nextEntry.bgValue - entry.bgValue); + deltaTotal += delta; + + if (delta > 0) { // avoid divide by 0 error + // Are we rising at faster than 5mg/DL/5minutes + if ((delta / timeDelta) >= (t1 / (1000 * 60 * 5))) { + t1count += 1; + } + // Are we rising at faster than 10mg/DL/5minutes + if ((delta / timeDelta) >= (t2 / (1000 * 60 * 5))) { + t2count += 1; + } + } - var delta = Math.abs(nextEntry.bgValue - entry.bgValue); - - deltaTotal += delta; + // Calculate the distance travelled for this time step + GVITotal += Math.sqrt(Math.pow(timeDelta / (1000 * 60), 2) + Math.pow(delta, 2)); - total += delta; - events += 1; + // Keep track of the number of minutes in this timestep + GVIIdeal_Time += timeDelta / (1000 * 60); + glucoseTotal += entry.bgValue; - if (delta >= t1) { - t1count += 1; - } - - if (delta >= t2) { - t2count += 1; - } - - GVITotal += Math.sqrt(25 + Math.pow(delta, 2)); - glucoseTotal += entry.bgValue; + if (entry.bgValue < options.targetLow) { + RMSTotal += Math.pow(options.targetLow - entry.bgValue, 2); + } + if (entry.bgValue > options.targetHigh) { + RMSTotal += Math.pow(entry.bgValue - options.targetHigh, 2); + } + } - if (entry.bgValue < options.targetLow) { - RMSTotal += Math.pow(options.targetLow - entry.bgValue, 2); - } - if (entry.bgValue > options.targetHigh) { - RMSTotal += Math.pow(entry.bgValue - options.targetHigh, 2); - } + // Difference between first and last reading + var GVIDelta = Math.floor(glucose_data[0].bgValue - glucose_data[glucose_data.length - 1].bgValue); - } - - var GVIDelta = Math.floor(glucose_data[0].bgValue,glucose_data[glucose_data.length-1].bgValue); - - GVIIdeal = Math.sqrt(Math.pow(usedRecords*5,2) + Math.pow(GVIDelta,2)); - - var GVI = Math.round(GVITotal / GVIIdeal * 100) / 100; - - console.log('GVI',GVI,'GVIIdeal',GVIIdeal,'GVITotal',GVITotal); - - var glucoseMean = Math.floor(glucoseTotal / usedRecords); + // Delta for total time considered against total period rise + GVIIdeal = Math.sqrt(Math.pow(GVIIdeal_Time, 2) + Math.pow(GVIDelta, 2)); - var tirMultiplier = result.Normal.readingspct / 100.0; + var GVI = Math.round(GVITotal / GVIIdeal * 100) / 100; + console.log('GVI', GVI, 'GVIIdeal', GVIIdeal, 'GVITotal', GVITotal, 'GVIIdeal_Time', GVIIdeal_Time); - var PGS = Math.round(GVI * glucoseMean * (1-tirMultiplier) * 100) / 100; + var glucoseMean = Math.floor(glucoseTotal / usedRecords); + var tirMultiplier = result.Normal.readingspct / 100.0; + var PGS = Math.round(GVI * glucoseMean * (1 - tirMultiplier) * 100) / 100; + console.log('glucoseMean', glucoseMean, 'tirMultiplier', tirMultiplier, 'PGS', PGS); - console.log('glucoseMean', glucoseMean,'tirMultiplier',tirMultiplier, 'PGS',PGS); + var TDC = deltaTotal / daysTotal; + var TDCHourly = TDC / 24.0; - var TDC = deltaTotal / daysTotal; - - var TDCHourly = TDC / 24.0; + var RMS = Math.sqrt(RMSTotal / events); - var RMS = Math.sqrt(RMSTotal / events); + // console.log('TADC',TDC,'days',days); -// console.log('TADC',TDC,'days',days); + var timeInT1 = Math.round(100 * t1count / events).toFixed(1); + var timeInT2 = Math.round(100 * t2count / events).toFixed(1); - var timeInT1 = Math.round(100 * t1count / events).toFixed(1); - var timeInT2 = Math.round(100 * t2count / events).toFixed(1); + var unitString = ' mg/dl'; + if (displayUnits == 'mmol') { + TDC = TDC / 18.0; + TDCHourly = TDCHourly / 18.0; + unitString = ' mmol/L'; - var unitString = ' mg/dl'; + RMS = Math.sqrt(RMSTotal / events) / 18; + } - if (displayUnits == 'mmol') { - TDC = TDC / 18.0; - TDCHourly = TDCHourly / 18.0; - unitString = ' mmol/L'; - - RMS = Math.sqrt(RMSTotal / events) / 18; - } - - TDC = Math.round(TDC * 100) / 100; - TDCHourly = Math.round(TDCHourly * 100) / 100; + TDC = Math.round(TDC * 100) / 100; + TDCHourly = Math.round(TDCHourly * 100) / 100; - var stabilitytable = $('
' + translate('Range') + '' + translate('% of Readings') + '' + translate('# of Readings') + '' + translate('Average') + '' + translate('Median') + '' + translate('Standard Deviation') + '' + translate('A1c estimation*') + '
' + translate(range) + rangeExp + ': ' + r.readingspct + '%' + r.rangeRecords.length + '' + r.mean.toFixed(1) + '' + r.median.toFixed(1) + '' + r.stddev.toFixed(1) + ' N/AN/AN/A
' + translate('Overall') + ': ' + glucose_data.length + '' + (Math.round(10 * ss.mean(localBgs)) / 10).toFixed(1) + '' + (Math.round(10 * ss.quantile(localBgs, 0.5)) / 10).toFixed(1) + '' + (Math.round(ss.standard_deviation(localBgs) * 10) / 10).toFixed(1) + '
' + (Math.round(10 * (ss.mean(mgDlBgs) + 46.7) / 28.7) / 10).toFixed(1) + '%DCCT | ' + Math.round(((ss.mean(mgDlBgs) + 46.7) / 28.7 - 2.15) * 10.929) + 'IFCC
' + translate(range) + rangeExp + ': ' + r.readingspct + '%' + r.rangeRecords.length + '' + r.mean.toFixed(1) + '' + r.median.toFixed(1) + '' + r.stddev.toFixed(1) + ' N/AN/AN/AN/AN/AN/AN/A
' + translate('Overall') + ': ' + glucose_data.length + '' + (Math.round(10 * ss.mean(localBgs)) / 10).toFixed(1) + '' + (Math.round(10 * ss.quantile(localBgs, 0.5)) / 10).toFixed(1) + '' + (Math.round(ss.standard_deviation(localBgs) * 10) / 10).toFixed(1) + '
' + (Math.round(10 * (ss.mean(mgDlBgs) + 46.7) / 28.7) / 10).toFixed(1) + '%DCCT | ' + Math.round(((ss.mean(mgDlBgs) + 46.7) / 28.7 - 2.15) * 10.929) + 'IFCC
N/AN/AN/AN/A
'); + var stabilitytable = $('
'); - var t1exp = '>5 mg/dl/5m'; - var t2exp = '>10 mg/dl/5m'; + var t1exp = '>5 mg/dl/5m'; + var t2exp = '>10 mg/dl/5m'; + if (displayUnits == 'mmol') { + t1exp = '>0.27 mmol/l/5m'; + t2exp = '>0.55 mmol/l/5m'; + } - if (displayUnits == 'mmol') { - t1exp = '>0.27 mmol/l/5m'; - t2exp = '>0.55 mmol/l/5m'; - } + $('').appendTo(stabilitytable); + $('').appendTo(stabilitytable); - $('').appendTo(stabilitytable); - $('').appendTo(stabilitytable); - - $('').appendTo(stabilitytable); - $('').appendTo(stabilitytable); - -// $('').appendTo(stabilitytable); -// $('').appendTo(stabilitytable); - - stabilitytable.appendTo(stability); - - setTimeout(function() { - $.plot( - '#glucosedistribution-overviewchart', - stats, { - series: { - pie: { - show: true - } - }, - colors: colors - } - ); - }); + $('').appendTo(stabilitytable); + $('').appendTo(stabilitytable); - function onClick() { - report_glucosedistribution(datastorage, sorteddaystoshow, options); - } + $('').appendTo(stabilitytable); + $('').appendTo(stabilitytable); + stabilitytable.appendTo(stability); + setTimeout(function() { + $.plot( + '#glucosedistribution-overviewchart' + , stats, { + series: { + pie: { + show: true + } + } + , colors: colors + } + ); + }); + + function onClick () { + report_glucosedistribution(datastorage, sorteddaystoshow, options); + } }; diff --git a/lib/report_plugins/hourlystats.js b/lib/report_plugins/hourlystats.js index 12a4412666b..84114209c96 100644 --- a/lib/report_plugins/hourlystats.js +++ b/lib/report_plugins/hourlystats.js @@ -8,34 +8,33 @@ var hourlystats = { , pluginType: 'report' }; -function init() { +function init () { return hourlystats; } module.exports = init; -hourlystats.html = function html(client) { +hourlystats.html = function html (client) { var translate = client.translate; var ret = - '

' + translate('Hourly stats') + '

' - + '
' - + '
' - ; + '

' + translate('Hourly stats') + '

' + + '
' + + '
'; return ret; }; hourlystats.css = - '#hourlystats-overviewchart {' - + ' width: 100%;' - + ' min-width: 6.5in;' - + ' height: 5in;' - + '}' - + '#hourlystats-placeholder td {' - + ' text-align:center;' - + '}'; - -hourlystats.report = function report_hourlystats(datastorage, sorteddaystoshow, options) { -//console.log(window); + '#hourlystats-overviewchart {' + + ' width: 100%;' + + ' min-width: 6.5in;' + + ' height: 5in;' + + '}' + + '#hourlystats-placeholder td {' + + ' text-align:center;' + + '}'; + +hourlystats.report = function report_hourlystats (datastorage, sorteddaystoshow, options) { + //console.log(window); var ss = require('simple-statistics'); var Nightscout = window.Nightscout; var client = Nightscout.client; @@ -52,15 +51,15 @@ hourlystats.report = function report_hourlystats(datastorage, sorteddaystoshow, pivotedByHour[i] = []; } - data = data.filter(function(o) { return !isNaN(o.sgv);}); - + data = data.filter(function(o) { return !isNaN(o.sgv); }); + data.forEach(function(record) { var d = new Date(record.displayTime); record.sgv = Number(record.sgv); pivotedByHour[d.getHours()].push(record); }); - + var table = $('
' + translate('Mean Total Daily Change') + '' + translate('Time in fluctuation') + '
(' + t1exp + ')
' + translate('Time in rapid fluctuation') + '
(' + t2exp + ')
' + TDC + unitString + '' + timeInT1 + '%' + timeInT2 + '%
' + translate('Mean Total Daily Change') + '' + translate('Time in fluctuation') + '
(' + t1exp + ')
' + translate('Time in rapid fluctuation') + '
(' + t2exp + ')
' + TDC + unitString + '' + timeInT1 + '%' + timeInT2 + '%
' + translate('Mean Hourly Change') + 'GVIPGS
' + TDCHourly + unitString + '' + GVI + '' + PGS + '
Out of Range RMS
' + Math.round(RMS * 100) / 100 + unitString + '
' + translate('Mean Hourly Change') + 'GVIPGS
' + TDCHourly + unitString + '' + GVI + '' + PGS + '
Out of Range RMS
' + Math.round(RMS * 100) / 100 + unitString + '
'); var thead = $(''); $('').appendTo(thead); @@ -74,50 +73,53 @@ hourlystats.report = function report_hourlystats(datastorage, sorteddaystoshow, $('').appendTo(thead); thead.appendTo(table); - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23].forEach(function (hour) { + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23].forEach(function(hour) { var tr = $(''); var display = new Date(0, 0, 1, hour, 0, 0, 0).toLocaleTimeString().replace(/([\d]+:[\d]{2})(:[\d]{2})(.*)/, '$1$3'); - var avg = Math.floor(pivotedByHour[hour].map(function (r) { - return r.sgv; - }).reduce(function (o, v) { - return o + v; - }, 0) / pivotedByHour[hour].length); + var avg = Math.floor(pivotedByHour[hour].map(function(r) { + return r.sgv; + }).reduce(function(o, v) { + return o + v; + }, 0) / pivotedByHour[hour].length); var d = new Date(times.hours(hour).msecs); - var dev = ss.standard_deviation(pivotedByHour[hour].map(function (r) { + var dev = ss.standard_deviation(pivotedByHour[hour].map(function(r) { return r.sgv; })); stats.push([ - new Date(d), - ss.quantile(pivotedByHour[hour].map(function (r) { + new Date(d) + , ss.quantile(pivotedByHour[hour].map(function(r) { return r.sgv; - }), 0.25), - ss.quantile(pivotedByHour[hour].map(function (r) { + }), 0.25) + , ss.quantile(pivotedByHour[hour].map(function(r) { return r.sgv; - }), 0.75), - avg - dev, - avg + dev + }), 0.75) + , avg - dev + , avg + dev ]); var tmp; $('').appendTo(tr); $('').appendTo(tr); $('').appendTo(tr); - $('').appendTo(tr); - $('').appendTo(tr); - $('').appendTo(tr); - $('').appendTo(tr); - $('').appendTo(tr); + $('').appendTo(tr); + // eslint-disable-next-line no-cond-assign + $('').appendTo(tr); + // eslint-disable-next-line no-cond-assign + $('').appendTo(tr); + // eslint-disable-next-line no-cond-assign + $('').appendTo(tr); + $('').appendTo(tr); $('').appendTo(tr); table.append(tr); }); @@ -126,28 +128,27 @@ hourlystats.report = function report_hourlystats(datastorage, sorteddaystoshow, report.append(table); $.plot( - '#hourlystats-overviewchart', - [{ - data: stats, - candle: true - }], - { + '#hourlystats-overviewchart' + , [{ + data: stats + , candle: true + }], { series: { - candle: true, - lines: false //Somehow it draws lines if you dont disable this. Should investigate and fix this ;) - }, - xaxis: { - mode: 'time', - timeFormat: '%h:00', - min: 0, - max: times.hours(24).msecs - times.secs(1).msecs - }, - yaxis: { - min: 0, - max: options.units === 'mmol' ? 22 : 400, - show: true - }, - grid: { + candle: true + , lines: false //Somehow it draws lines if you dont disable this. Should investigate and fix this ;) + } + , xaxis: { + mode: 'time' + , timeFormat: '%h:00' + , min: 0 + , max: times.hours(24).msecs - times.secs(1).msecs + } + , yaxis: { + min: 0 + , max: options.units === 'mmol' ? 22 : 400 + , show: true + } + , grid: { show: true } } @@ -161,7 +162,7 @@ hourlystats.report = function report_hourlystats(datastorage, sorteddaystoshow, var days = 0; table = $('
' + translate('Time') + '' + translate('Standard Deviation') + '
' + display + '' + pivotedByHour[hour].length + ' (' + Math.floor(100 * pivotedByHour[hour].length / data.length) + '%)' + avg + '' + Math.min.apply(Math, pivotedByHour[hour].map(function (r) { - return r.sgv; - })) + '' + ((tmp = ss.quantile(pivotedByHour[hour].map(function (r) { - return r.sgv; - }), 0.25)) ? tmp.toFixed(1) : 0 ) + '' + ((tmp = ss.quantile(pivotedByHour[hour].map(function (r) { - return r.sgv; - }), 0.5)) ? tmp.toFixed(1) : 0 ) + '' + ((tmp = ss.quantile(pivotedByHour[hour].map(function (r) { - return r.sgv; - }), 0.75)) ? tmp.toFixed(1) : 0 ) + '' + Math.max.apply(Math, pivotedByHour[hour].map(function (r) { - return r.sgv; - })) + '' + Math.min.apply(Math, pivotedByHour[hour].map(function(r) { + return r.sgv; + })) + '' + ((tmp = ss.quantile(pivotedByHour[hour].map(function(r) { + return r.sgv; + }), 0.25)) ? tmp.toFixed(1) : 0) + '' + ((tmp = ss.quantile(pivotedByHour[hour].map(function(r) { + return r.sgv; + }), 0.5)) ? tmp.toFixed(1) : 0) + '' + ((tmp = ss.quantile(pivotedByHour[hour].map(function(r) { + return r.sgv; + }), 0.75)) ? tmp.toFixed(1) : 0) + '' + Math.max.apply(Math, pivotedByHour[hour].map(function(r) { + return r.sgv; + })) + '' + Math.floor(dev * 10) / 10 + '
'); thead = $(''); - ["", 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23].forEach(function (hour) { + ["", 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23].forEach(function(hour) { $('').appendTo(thead); totalPositive[hour] = 0; totalNegative[hour] = 0; @@ -171,7 +172,7 @@ hourlystats.report = function report_hourlystats(datastorage, sorteddaystoshow, }); thead.appendTo(table); - sorteddaystoshow.forEach(function (day) { + sorteddaystoshow.forEach(function(day) { if (datastorage[day].netBasalPositive) { days++; var tr = $(''); diff --git a/lib/report_plugins/loopalyzer.js b/lib/report_plugins/loopalyzer.js index 8eb96e68102..2d53fa251a3 100644 --- a/lib/report_plugins/loopalyzer.js +++ b/lib/report_plugins/loopalyzer.js @@ -11,7 +11,7 @@ var loopalyzer = { , pluginType: 'report' }; -function init() { +function init () { return loopalyzer; } @@ -23,80 +23,79 @@ var risingInterpolationGap = 6; // How large a gap in COB/IOB graph is allowed t var fallingInterpolationGap = 24; // And if less than start var interpolationRatio = 1.25; // But do allow rising interpolation if gap larger than interpolationGap and end value is less than 10% larger than start -loopalyzer.html = function html(client) { +loopalyzer.html = function html (client) { var translate = client.translate; var ret = ''; - ret += '

Loopalyzer  

'; - ret += '' + translate('The primary purpose of Loopalyzer is to visualise how the Loop closed loop system performs. It may work with other setups as well, both closed and open loop, and non loop. However depending on which uploader you use, how frequent it is able to capture your data and upload, and how it is able to backfill missing data some graphs may have gaps or even be completely empty. Always ensure the graphs look reasonable. Best is to view one day at a time and scroll through a number of days first to see.'); - ret += '

' + translate('Loopalyzer includes a time shift feature. If you for example have breakfast at 07:00 one day and at 08:00 the day after your average blood glucose curve these two days will most likely look flattened and not show the actual response after a breakfast. Time shift will compute the average time these meals were eaten and then shift all data (carbs, insulin, basal etc.) during both days the corresponding time difference so that both meals align with the average meal start time. '); - ret += '
' + translate('In this example all data from first day is pushed 30 minutes forward in time and all data from second day 30 minutes backward in time so it appears as if you had had breakfast at 07:30 both days. This allows you to see your actual average blood glucose response from a meal.'); - ret += '

' + translate('Time shift highlights the period after the average meal start time in gray, for the duration of the DIA (Duration of Insulin Action). As all data points the entire day are shifted the curves outside the gray area may not be accurate.'); - ret += '

' + translate('Note that time shift is available only when viewing multiple days.'); - ret += '

'; - ret += translate('To see this report, press SHOW while in this view'); - ret += '
'; - ret += ''; - ret += '';/* loopalyzer-button */ - ret += '
'; - ret += '
'; - ret += '
'; - ret += '
'; - ret += '
'; - ret += '
'; - ret += '
'; - ret += '
'; - ret += '
'; - return ret; + ret += '

Loopalyzer  

'; + ret += '' + translate('The primary purpose of Loopalyzer is to visualise how the Loop closed loop system performs. It may work with other setups as well, both closed and open loop, and non loop. However depending on which uploader you use, how frequent it is able to capture your data and upload, and how it is able to backfill missing data some graphs may have gaps or even be completely empty. Always ensure the graphs look reasonable. Best is to view one day at a time and scroll through a number of days first to see.'); + ret += '

' + translate('Loopalyzer includes a time shift feature. If you for example have breakfast at 07:00 one day and at 08:00 the day after your average blood glucose curve these two days will most likely look flattened and not show the actual response after a breakfast. Time shift will compute the average time these meals were eaten and then shift all data (carbs, insulin, basal etc.) during both days the corresponding time difference so that both meals align with the average meal start time. '); + ret += '
' + translate('In this example all data from first day is pushed 30 minutes forward in time and all data from second day 30 minutes backward in time so it appears as if you had had breakfast at 07:30 both days. This allows you to see your actual average blood glucose response from a meal.'); + ret += '

' + translate('Time shift highlights the period after the average meal start time in gray, for the duration of the DIA (Duration of Insulin Action). As all data points the entire day are shifted the curves outside the gray area may not be accurate.'); + ret += '

' + translate('Note that time shift is available only when viewing multiple days.'); + ret += '

'; + ret += translate('To see this report, press SHOW while in this view'); + ret += '
'; + ret += ''; + ret += ''; /* loopalyzer-button */ + ret += '
'; + ret += '
'; + ret += '
'; + ret += '
'; + ret += '
'; + ret += '
'; + ret += '
'; + ret += '
'; + ret += '
'; + return ret; }; loopalyzer.css = -'#loopalyzer-charts, #loopalyzer-profiles { padding: 20px; } ' -+ '#loopalyzer-basal, #loopalyzer-bg, #loopalyzer-tempbasal, #loopalyzer-iob, #loopalyzer-cob, #loopalyzer-profiles {' -+ ' width: 100%;' -+ ' height: 100%;' -+ '}' -+ '#loopalyzer-profiles-table table { margin: 0 10px; border-collapse: collapse; border: 0px; }' -+ '#loopalyzer-profiles-table td { vertical-align: top; }' -+ '#loopalyzer-profiles-table td table { margin: 0 10px; border-collapse: collapse; border: 0px; }' -+ '#loopalyzer-profiles-table td caption { text-align: left; font-weight: bold; }' -+ '#loopalyzer-profiles-table td th { background-color: #4CAF50; color: white; }' -+ '#loopalyzer-profiles-table td td { text-align: right; vertical-align: top; padding: 0 1px; }' -+ '#loopalyzer-profiles-table td td td { padding: 1px 8px; }' -; - -loopalyzer.prepareHtml = function loopalyzerPrepareHtml() { -// $('#loopalyzer-charts').append($('
' + hour + '
')); + '#loopalyzer-charts, #loopalyzer-profiles { padding: 20px; } ' + + '#loopalyzer-basal, #loopalyzer-bg, #loopalyzer-tempbasal, #loopalyzer-iob, #loopalyzer-cob, #loopalyzer-profiles {' + + ' width: 100%;' + + ' height: 100%;' + + '}' + + '#loopalyzer-profiles-table table { margin: 0 10px; border-collapse: collapse; border: 0px; }' + + '#loopalyzer-profiles-table td { vertical-align: top; }' + + '#loopalyzer-profiles-table td table { margin: 0 10px; border-collapse: collapse; border: 0px; }' + + '#loopalyzer-profiles-table td caption { text-align: left; font-weight: bold; }' + + '#loopalyzer-profiles-table td th { background-color: #4CAF50; color: white; }' + + '#loopalyzer-profiles-table td td { text-align: right; vertical-align: top; padding: 0 1px; }' + + '#loopalyzer-profiles-table td td td { padding: 1px 8px; }'; + +loopalyzer.prepareHtml = function loopalyzerPrepareHtml () { + // $('#loopalyzer-charts').append($('
')); }; // loopalyzer.ss = require('simple-statistics'); @@ -111,17 +110,17 @@ loopalyzer.getSGVs = function(datastorage, daysToShow) { // Loop thru the days to show, for each day find the matching SGVs and insert into the bins entry array daysToShow.forEach(function(day) { var entries = []; // Array with all SGVs for this day, we'll fill this and then insert into the bins later - for (var i=0; i<288; i++) entries.push(NaN); // Fill the array with NaNs so we have something in case we don't find an SGV + for (let i = 0; i < 288; i++) entries.push(NaN); // Fill the array with NaNs so we have something in case we don't find an SGV var fromDate = moment(day); var toDate = moment(day); - fromDate.set({'hours':0, 'minutes':0, 'seconds':0, 'milliseconds':0}); - toDate.set({'hours':0, 'minutes':5, 'seconds':0, 'milliseconds':0}); // toDate is 5 mins ahead - for (var i=0; i<288; i++) { + fromDate.set({ 'hours': 0, 'minutes': 0, 'seconds': 0, 'milliseconds': 0 }); + toDate.set({ 'hours': 0, 'minutes': 5, 'seconds': 0, 'milliseconds': 0 }); // toDate is 5 mins ahead + for (let i = 0; i < 288; i++) { var found = false; data.some(function(record) { var recDate = moment(record.displayTime); if (!found && recDate.isAfter(fromDate) && recDate.isBefore(toDate)) { - entries[i]=record.sgv; + entries[i] = record.sgv; found = true; } return found; // Breaks .some loop if found is true @@ -141,10 +140,10 @@ loopalyzer.getBasals = function(datastorage, daysToShow, profile) { var dayStart = moment(day).startOf('day'); var dayEnd = moment(day).endOf('day'); var basals = []; - for (var i=0; i<288; i++) basals.push(NaN); // Clear the basals by filling with NaNs + for (var i = 0; i < 288; i++) basals.push(NaN); // Clear the basals by filling with NaNs var index = 0; - for (var dt=dayStart; dt < dayEnd; dt.add(5, 'minutes')) { + for (var dt = dayStart; dt < dayEnd; dt.add(5, 'minutes')) { var basal = profile.getTempBasal(dt.toDate()); if (basal) basals[index++] = basal.basal; @@ -162,10 +161,10 @@ loopalyzer.getTempBasalDeltas = function(datastorage, daysToShow, profile) { var dayStart = moment(day).startOf('day'); var dayEnd = moment(day).endOf('day'); var temps = []; - for (var i=0; i<288; i++) temps.push(NaN); // Clear the basals by filling with NaNs + for (var i = 0; i < 288; i++) temps.push(NaN); // Clear the basals by filling with NaNs var index = 0; - for (var dt=dayStart; dt < dayEnd; dt.add(5, 'minutes')) { + for (var dt = dayStart; dt < dayEnd; dt.add(5, 'minutes')) { var basal = profile.getTempBasal(dt.toDate()); if (basal) temps[index++] = basal.tempbasal - basal.basal; @@ -188,37 +187,38 @@ loopalyzer.getIOBs = function(datastorage, daysToShow, profile, client, treatmen var iobs = []; if (iobStatusAvailable) { // var dayStartMills = dayStart.milliseconds(); - for (var i=0; i<288; i++) iobs.push(NaN); // Clear the IOBs by filling with NaNs + for (var i = 0; i < 288; i++) iobs.push(NaN); // Clear the IOBs by filling with NaNs var iobArray = client.plugins('iob').IOBDeviceStatusesInTimeRange(datastorage.devicestatus, dayStart.valueOf(), dayEnd.valueOf()); if (laDebug) console.log('getIOBs iobArray', iobArray); - iobArray.forEach(function(entry){ - var index = Math.floor(moment(entry.mills).diff(dayStart,'minutes') / 5); + iobArray.forEach(function(entry) { + var index = Math.floor(moment(entry.mills).diff(dayStart, 'minutes') / 5); iobs[index] = entry.iob; }); - if (daysToShow.length===1) loopalyzer.fillNanWithTreatments(iobs, treatments); + if (daysToShow.length === 1) loopalyzer.fillNanWithTreatments(iobs, treatments); // Loop thru these entries and where no IOB has been found, interpolate between nearby to get a continuous array - var startIndex = 0, stopIndex = 0; + var startIndex = 0 + , stopIndex = 0; while (startIndex < iobs.length && isNaN(iobs[startIndex])) { startIndex++; // Advance start to the first real number } if (startIndex < iobs.length) { - stopIndex = startIndex+1; - while (stopIndex=0 && isNaN(array[start])) {}; - while (stop++ = 0 && isNaN(array[start])) {} + // eslint-disable-next-line no-empty + while (stop++ < array.length && isNaN(array[stop])) {} // var gap = stop - start; // if (isNaN(array[start]) || isNaN(array[stop]) || gap > interpolationGap || (gap < interpolationGap && array[start]= interpolationGap || array[start]==0)) ) { - var interpolate = (isNaN(array[start]) || isNaN(array[stop]) ? true : loopalyzer.canInterpolate(array,start,stop)); + var interpolate = (isNaN(array[start]) || isNaN(array[stop]) ? true : loopalyzer.canInterpolate(array, start, stop)); if (!interpolate) { array[index] = treatment.amount; } @@ -331,12 +336,12 @@ loopalyzer.fillNanWithTreatments = function(array, treatments) { /* Returns true if we can interpolate between this start and end */ loopalyzer.canInterpolate = function(array, start, stop) { var interpolate = false; - if (array[stop] <= array[start]*interpolationRatio) { + if (array[stop] <= array[start] * interpolationRatio) { // Falling - if (stop-start0}).forEach(function(treatment){ + datastorage.treatments.filter(function(treatment) { return treatment.carbs && treatment.carbs > 0 }).forEach(function(treatment) { if (moment(treatment.created_at).isBetween(startDate, endDate)) { - treatments.push({date:treatment.created_at, amount:treatment.carbs}); + treatments.push({ date: treatment.created_at, amount: treatment.carbs }); } }) if (laDebug) console.log('Carb treatments', treatments); @@ -360,11 +365,11 @@ loopalyzer.getCarbTreatments = function(datastorage, daysToShow) { loopalyzer.getInsulinTreatments = function(datastorage, daysToShow) { var treatments = []; // Holds the treatments [date, amount] var startDate = moment(daysToShow[0]); - var endDate = moment(daysToShow[daysToShow.length-1]).add(1, 'days'); + var endDate = moment(daysToShow[daysToShow.length - 1]).add(1, 'days'); - datastorage.treatments.filter(function(treatment){return treatment.insulin && treatment.insulin >0}).forEach(function(treatment){ + datastorage.treatments.filter(function(treatment) { return treatment.insulin && treatment.insulin > 0 }).forEach(function(treatment) { if (moment(treatment.created_at).isBetween(startDate, endDate)) { - treatments.push({date:treatment.created_at, amount:treatment.insulin}); + treatments.push({ date: treatment.created_at, amount: treatment.insulin }); } }) if (laDebug) console.log('Insulin treatments', treatments); @@ -376,12 +381,12 @@ loopalyzer.getInsulinTreatments = function(datastorage, daysToShow) { loopalyzer.getAllTreatmentTimestampsForADay = function(datastorage, day) { var timestamps = []; var dayStart = moment(day).startOf('day'); - var carbTreatments = loopalyzer.getCarbTreatments(datastorage,[day]); - var insulinTreatments = loopalyzer.getInsulinTreatments(datastorage,[day]); - carbTreatments.forEach(function(entry) { timestamps.push(entry.date)}); - insulinTreatments.forEach(function(entry) { timestamps.push(entry.date)}); - timestamps.sort(function(a,b) { return (a= 0; i--) { if (datastorage.devicestatus[i].loop && datastorage.devicestatus[i].loop.predicted) { var predicted = datastorage.devicestatus[i].loop.predicted; - if (moment(predicted.startDate).isSame(dayStart,'day')) + if (moment(predicted.startDate).isSame(dayStart, 'day')) predictions.push(datastorage.devicestatus[i].loop.predicted); } else if (datastorage.devicestatus[i].openaps && datastorage.devicestatus[i].openaps.suggested && datastorage.devicestatus[i].openaps.suggested.predBGs) { var entry = {}; @@ -408,7 +413,7 @@ loopalyzer.getAllPredictionsForADay = function(datastorage, day) { // Remove duplicates before we're done var p = []; predictions.forEach(function(prediction) { - if (p.length === 0 || prediction.startDate !== p[p.length-1].startDate) + if (p.length === 0 || prediction.startDate !== p[p.length - 1].startDate) p.push(prediction); }) return p; @@ -421,13 +426,13 @@ loopalyzer.findPredicted = function(predictions, timestamp, offset) { var ts = moment(timestamp).add(offset, 'minutes'); var predicted = null; if (offset && offset < 0) { // If offset is negative, start searching from first prediction going forward - for (var i = 0; i < predictions.length; i++) { + for (let i = 0; i < predictions.length; i++) { if (predictions[i] && predictions[i].startDate && moment(predictions[i].startDate) <= ts) { predicted = i; } } - } else { // If offset is positive or zero, start searching from last prediction going backward - for (var i = predictions.length - 1; i > 0; i--) { + } else { // If offset is positive or zero, start searching from last prediction going backward + for (let i = predictions.length - 1; i > 0; i--) { if (predictions[i] && predictions[i].startDate && moment(predictions[i].startDate) >= ts) { predicted = i; } @@ -436,7 +441,6 @@ loopalyzer.findPredicted = function(predictions, timestamp, offset) { return predicted; } - loopalyzer.getPredictions = function(datastorage, daysToShow, client) { if (!datastorage.devicestatus) @@ -448,110 +452,112 @@ loopalyzer.getPredictions = function(datastorage, daysToShow, client) { // Fill the bins array with the timestamp, one per 5 minutes var bins = []; var date = moment(); - date.set({'hours':0, 'minutes':0, 'seconds':0, 'milliseconds':0}); - for (var i=0; i<288; i++) { - bins.push([date.toDate(),[]]); + date.set({ 'hours': 0, 'minutes': 0, 'seconds': 0, 'milliseconds': 0 }); + for (var i = 0; i < 288; i++) { + bins.push([date.toDate(), []]); date.add(5, 'minutes'); } daysToShow.forEach(function(day) { - var p = []; // Array with all prediction SGVs for this day, we'll fill this and then insert into the bins later - for (var i=0; i<288; i++) p.push(NaN); - var treatmentTimestamps = loopalyzer.getAllTreatmentTimestampsForADay(datastorage, day); - var predictions = loopalyzer.getAllPredictionsForADay(datastorage, day); - - if (predictions.length > 0 && treatmentTimestamps.length > 0) { - - // Iterate over all treatments, find the predictions for each and add them to the entries array p, aligned on timestamp - for (var treatmentsIndex = 0; treatmentsIndex < treatmentTimestamps.length; treatmentsIndex++) { - var timestamp = treatmentTimestamps[treatmentsIndex]; - var predictedIndex = loopalyzer.findPredicted(predictions, timestamp, predictedOffset); // Find predictions offset before or after timestamp - - if (predictedIndex != null) { - var entry = predictions[predictedIndex]; // Start entry - var d = moment(entry.startDate); - var end = moment(day).endOf('day'); // Default to stop and end of the day - if (truncatePredictions) { - if (predictedOffset >= 0) { - // But if we are looking forward we want to stop at the next treatment - if (treatmentsIndex < treatmentTimestamps.length - 1) { - end = moment(treatmentTimestamps[treatmentsIndex + 1]); - } - } else { - // And if we are looking backward then we want to stop at "this" treatment - end = moment(treatmentTimestamps[treatmentsIndex]); + var p = []; // Array with all prediction SGVs for this day, we'll fill this and then insert into the bins later + for (var i = 0; i < 288; i++) p.push(NaN); + var treatmentTimestamps = loopalyzer.getAllTreatmentTimestampsForADay(datastorage, day); + var predictions = loopalyzer.getAllPredictionsForADay(datastorage, day); + + if (predictions.length > 0 && treatmentTimestamps.length > 0) { + + // Iterate over all treatments, find the predictions for each and add them to the entries array p, aligned on timestamp + for (var treatmentsIndex = 0; treatmentsIndex < treatmentTimestamps.length; treatmentsIndex++) { + var timestamp = treatmentTimestamps[treatmentsIndex]; + var predictedIndex = loopalyzer.findPredicted(predictions, timestamp, predictedOffset); // Find predictions offset before or after timestamp + + if (predictedIndex != null) { + var entry = predictions[predictedIndex]; // Start entry + var d = moment(entry.startDate); + var end = moment(day).endOf('day'); // Default to stop and end of the day + if (truncatePredictions) { + if (predictedOffset >= 0) { + // But if we are looking forward we want to stop at the next treatment + if (treatmentsIndex < treatmentTimestamps.length - 1) { + end = moment(treatmentTimestamps[treatmentsIndex + 1]); } + } else { + // And if we are looking backward then we want to stop at "this" treatment + end = moment(treatmentTimestamps[treatmentsIndex]); } - for (var entryIndex in entry.values) { - if (!d.isAfter(end)) { - var dayStart = moment(d).startOf('day'); - var minutesAfterMidnight = moment(d).diff(dayStart, 'minutes'); - var index = Math.floor(minutesAfterMidnight/5); - p[index] = client.utils.scaleMgdl(entry.values[entryIndex]); - d.add(5, 'minutes'); - } + } + for (var entryIndex in entry.values) { + if (!d.isAfter(end)) { + var dayStart = moment(d).startOf('day'); + var minutesAfterMidnight = moment(d).diff(dayStart, 'minutes'); + var index = Math.floor(minutesAfterMidnight / 5); + p[index] = client.utils.scaleMgdl(entry.values[entryIndex]); + d.add(5, 'minutes'); } } } } - for (var i=0; i<288; i++) { - bins[i][1].push(p[i]); - } - }) - return bins; - } - // - // PREDICTIONS ENDS - + } + for (let i = 0; i < 288; i++) { + bins[i][1].push(p[i]); + } + }) + return bins; +} +// +// PREDICTIONS ENDS // VARIOUS UTILITY FUNCTIONS // /* Create an empty bins array with date stamps for today */ loopalyzer.getEmptyBins = function() { - var bins=[]; + var bins = []; var todayStart = moment().startOf('day'); var todayEnd = moment().endOf('day'); - for (var dt=todayStart; dt < todayEnd; dt.add(5, 'minutes')) { + for (var dt = todayStart; dt < todayEnd; dt.add(5, 'minutes')) { bins.push([dt.toDate(), []]); } - return bins; + return bins; } /* Takes an array of 288 values and adds to the bins */ loopalyzer.addArrayToBins = function(bins, values) { if (bins && bins.length === 288 && values && values.length === 288) { - values.forEach(function(value,index) { + values.forEach(function(value, index) { bins[index][1].push(value); }); - } else + } else console.log('addArrayToBins - array must have 288 items', values); } /* Fill all NaNs in an array by interpolating between adjacent values */ loopalyzer.interpolateArray = function(values, allowNegative) { - var startIndex=0, stopIndex=0, k=0, m=0; + var startIndex = 0 + , stopIndex = 0 + , k = 0 + , m = 0; while (isNaN(values[startIndex])) { startIndex++; // Advance start to the first real number } - stopIndex = startIndex+1; - while (stopIndexmax) max = xBins[i][1]; + if (!isNaN(xBins[i][1]) && xBins[i][1] > max) max = xBins[i][1]; } return max; } /* Compute avg value in bins */ loopalyzer.avg = function(xBins) { - var out=[]; - xBins.forEach(function(entry){ + var out = []; + xBins.forEach(function(entry) { var sum = 0; var count = 0; - entry[1].forEach(function(value){ - if (value && value != NaN) { + entry[1].forEach(function(value) { + if (value && !isNaN(value)) { sum += value; count++; } @@ -599,36 +605,36 @@ loopalyzer.avg = function(xBins) { // Timeshifts a bins array with subarrays for multiple days loopalyzer.timeShiftBins = function(bins, timeShift) { - if (bins && bins.length>0) { - timeShift.forEach(function(minutes, dayIndex){ - if (minutes !==0) { + if (bins && bins.length > 0) { + timeShift.forEach(function(minutes, dayIndex) { + if (minutes !== 0) { var tempBin = []; - bins.forEach(function(){ + bins.forEach(function() { tempBin.push(NaN); // Fill tempBin with NaNs }) - var minutesBy5 = Math.floor(minutes/5); - if (minutesBy5>0) { - var count = 288-minutesBy5; + var minutesBy5 = Math.floor(minutes / 5); + if (minutesBy5 > 0) { + let count = 288 - minutesBy5; // If minutes>0 it means we should shift forward in time // Example: Shift by 15 mins = 3 buckets // bin : 0 1 2 3 4 5 6 7 8 9 10 // tempBin: NaN NaN NaN 0 1 2 3 4 5 6 7 - for (var i=0; i0) { - daysToShow.forEach(function(day, dayIndex){ + if (bin && bin.length > 0) { + daysToShow.forEach(function(day, dayIndex) { var minutesToAdd = timeShift[dayIndex]; var date = moment(day); - bin.forEach(function(entry, entryIndex){ + bin.forEach(function(entry, entryIndex) { var entryDate = moment(entry.date); if (entryDate.isSame(date, 'day')) { entryDate.add(minutesToAdd, 'minutes'); - bin[entryIndex].date=entryDate.toDate(); + bin[entryIndex].date = entryDate.toDate(); } }) }) @@ -654,7 +660,7 @@ loopalyzer.timeShiftSingleBin = function(bin, daysToShow, timeShift) { } /* Returns true if the profile values in a is identical to values in b, false otherwise */ -loopalyzer.isSameProfileValues = function(a,b) { +loopalyzer.isSameProfileValues = function(a, b) { // Because the order of the keys are random when stringifying we do our own custom stringify ourselves var aString = ''; var bString = ''; @@ -697,12 +703,12 @@ loopalyzer.isSameProfileValues = function(a,b) { return (aString == bString); } -loopalyzer.renderProfilesTable = function (datastoreProfiles, daysToShow, client) { +loopalyzer.renderProfilesTable = function(datastoreProfiles, daysToShow, client) { // Loop thru the daysToShow and get the timestamp of the first day displayed var beginningOfFirstDay = null; var endOfLastDay = null; - daysToShow.forEach(function (day) { + daysToShow.forEach(function(day) { var dayStart = moment(day).startOf('day'); var dayEnd = moment(day).endOf('day'); if (!beginningOfFirstDay || dayStart < beginningOfFirstDay) @@ -719,16 +725,17 @@ loopalyzer.renderProfilesTable = function (datastoreProfiles, daysToShow, client // these on ascending startDate (create a clone array so we don't modify the Store array). And only save the profiles // that have basal, carbratio, or sens. var profilesArray1 = []; - datastoreProfiles.forEach(function (entry) { + datastoreProfiles.forEach(function(entry) { var newEntry = {}; newEntry.startDate = entry.startDate; - var store=entry.store; + var store = entry.store; if (store) { - for(var key in store){ + for (var key in store) { if (laDebug) console.log('profile ' + key); - if (store.hasOwnProperty(key)){ - var defaultProfile=store[key]; - newEntry.profileName=key; + // eslint-disable-next-line no-prototype-builtins + if (store.hasOwnProperty(key)) { + var defaultProfile = store[key]; + newEntry.profileName = key; if (defaultProfile.basal) newEntry.basal = defaultProfile.basal; if (defaultProfile.carbratio) newEntry.carbratio = defaultProfile.carbratio; if (defaultProfile.sens) newEntry.sens = defaultProfile.sens; @@ -738,9 +745,9 @@ loopalyzer.renderProfilesTable = function (datastoreProfiles, daysToShow, client } } }) - profilesArray1.sort(function (a, b) { return (a.startDate > b.startDate ? 1 : -1) }); // Ascending + profilesArray1.sort(function(a, b) { return (a.startDate > b.startDate ? 1 : -1) }); // Ascending if (laDebug) { - profilesArray1.forEach(function (entry) { + profilesArray1.forEach(function(entry) { console.log('profilesArray1 - ' + entry.startDate); }) } @@ -750,30 +757,30 @@ loopalyzer.renderProfilesTable = function (datastoreProfiles, daysToShow, client var profilesArray2 = []; var profileToCompareWith = profilesArray1[0]; profilesArray2.push(profileToCompareWith); // Push the first profile, which should always be included. - profilesArray1.forEach(function (entry) { + profilesArray1.forEach(function(entry) { if (laDebug) { console.log('Comparing ' + JSON.stringify(profileToCompareWith.startDate) + ' to ' + JSON.stringify(entry.startDate)); console.log(profileToCompareWith, entry); } - if (!loopalyzer.isSameProfileValues(profileToCompareWith, entry)) { + if (!loopalyzer.isSameProfileValues(profileToCompareWith, entry)) { profilesArray2.push(entry); profileToCompareWith = entry; - if (laDebug) + if (laDebug) console.log('ADDING IT'); } else { // Do NOT push the entry to profilesArray2, and keep comparing with the same (olders unique) profile - if (laDebug) + if (laDebug) console.log('SKIPPING IT'); } }) if (laDebug) console.log('profilesArray2 has ' + profilesArray2.length + ' profiles'); // Sort the newest Profile first - profilesArray2.sort(function (a, b) { return (a.startDate > b.startDate ? 1 : -1) }); // Ascending + profilesArray2.sort(function(a, b) { return (a.startDate > b.startDate ? 1 : -1) }); // Ascending // Third, find the latest profile with a startDate before beginningOfFirstDay var latestProfile = profilesArray2[0]; // This is the oldest one - profilesArray2.forEach(function (entry) { + profilesArray2.forEach(function(entry) { if (laDebug) console.log(entry.startDate + ' isBefore ' + beginningOfFirstDay + ' = ' + moment(entry.startDate).isBefore(beginningOfFirstDay)); if (moment(entry.startDate).isBefore(beginningOfFirstDay)) @@ -785,7 +792,7 @@ loopalyzer.renderProfilesTable = function (datastoreProfiles, daysToShow, client // the other profiles with a startDate between beginningOfFirstDay and endOfLastDay var profiles = []; profiles.push(latestProfile); // Add the latest one - profilesArray2.forEach(function (entry) { + profilesArray2.forEach(function(entry) { if (laDebug) console.log(entry.startDate + ' isAfter ' + beginningOfFirstDay + ' = ' + moment(entry.startDate).isAfter(beginningOfFirstDay)); if (moment(entry.startDate).isAfter(beginningOfFirstDay)) @@ -794,7 +801,7 @@ loopalyzer.renderProfilesTable = function (datastoreProfiles, daysToShow, client // Now we have an array of all the profiles that are relevant for the days we are displaying. if (laDebug) { - profiles.forEach(function (entry) { + profiles.forEach(function(entry) { console.log('profiles - ' + entry.startDate); }) } @@ -803,7 +810,7 @@ loopalyzer.renderProfilesTable = function (datastoreProfiles, daysToShow, client var translate = client.translate; var tableHtml = ''; - profiles.forEach(function (theProfile, index) { + profiles.forEach(function(theProfile, index) { if (index < 3) { tableHtml += '
'; @@ -814,7 +821,7 @@ loopalyzer.renderProfilesTable = function (datastoreProfiles, daysToShow, client // Add Basal as a table in the first td tableHtml += '
'; if (theProfile.basal) { - theProfile.basal.forEach(function (entry) { + theProfile.basal.forEach(function(entry) { tableHtml += '' }); } @@ -823,7 +830,7 @@ loopalyzer.renderProfilesTable = function (datastoreProfiles, daysToShow, client // Add Carb Ratio as a table in the second td tableHtml += '
' + entry.time + '' + parseFloat(entry.value).toFixed(3) + '
'; if (theProfile.carbratio) { - theProfile.carbratio.forEach(function (entry) { + theProfile.carbratio.forEach(function(entry) { tableHtml += '' }); } @@ -832,7 +839,7 @@ loopalyzer.renderProfilesTable = function (datastoreProfiles, daysToShow, client // Add Sensitivity as a table in the third td tableHtml += ''; - } else - if (index == 3) { + } else + if (index == 3) { // Add ellipsis if too many profiles to display, but only one ellipsis even if there are more profiles tableHtml += ''; } @@ -857,16 +864,16 @@ loopalyzer.renderProfilesTable = function (datastoreProfiles, daysToShow, client }; // Main method -loopalyzer.report = function(datastorage,sorteddaystoshow,options) { +loopalyzer.report = function(datastorage, sorteddaystoshow, options) { if (laDebug) console.log('Loopalyzer ' + laVersion); // Copy the sorteddaystoshow into new array (clone) and re-sort ascending (so we don't mess with original array) var daysToShow = []; - sorteddaystoshow.forEach(function(day){daysToShow.push(day)}); - daysToShow.sort(function(a,b) { return (a1) dateInfo += ' - ' + moment(daysToShow[daysToShow.length-1]).format('ddd MMM D'); // .split(',')[0]; + if (daysToShow.length > 1) dateInfo += ' - ' + moment(daysToShow[daysToShow.length - 1]).format('ddd MMM D'); // .split(',')[0]; $("#loopalyzer-dateinfo").html(dateInfo); loopalyzer.prepareHtml(); $("#loopalyzer-buttons").show(); - if (daysToShow.length==1) { + if (daysToShow.length == 1) { // Disable and gray out timeShift if only a single day $("#rp_loopalyzertimeshift").prop('checked', false); $("#rp_loopalyzertimeshift").attr("disabled", true); @@ -925,23 +931,23 @@ loopalyzer.generateReport = function(datastorage,daysToShow,options) { if ($("#rp_loopalyzerprofiles").is(":checked") && (datastorage.profiles && datastorage.profiles.length > 0)) { $("#loopalyzer-profiles-table").show(); loopalyzer.renderProfilesTable(datastorage.profiles, daysToShow, client); - } else + } else $("#loopalyzer-profiles-table").hide(); // Pull all necessary treatment information profile.updateTreatments(datastorage.profileSwitchTreatments, datastorage.tempbasalTreatments, datastorage.combobolusTreatments); - var carbTreatments = loopalyzer.getCarbTreatments(datastorage,daysToShow); - var insulinTreatments = loopalyzer.getInsulinTreatments(datastorage,daysToShow); - var sgvBin = loopalyzer.getSGVs(datastorage,daysToShow); - var basalsBin = loopalyzer.getBasals(datastorage,daysToShow,profile); - var tempBasalsBin = loopalyzer.getTempBasalDeltas(datastorage,daysToShow,profile); - var iobBin = loopalyzer.getIOBs(datastorage,daysToShow, profile, client, insulinTreatments); - var cobBin = loopalyzer.getCOBs(datastorage,daysToShow, profile, client, carbTreatments); + var carbTreatments = loopalyzer.getCarbTreatments(datastorage, daysToShow); + var insulinTreatments = loopalyzer.getInsulinTreatments(datastorage, daysToShow); + var sgvBin = loopalyzer.getSGVs(datastorage, daysToShow); + var basalsBin = loopalyzer.getBasals(datastorage, daysToShow, profile); + var tempBasalsBin = loopalyzer.getTempBasalDeltas(datastorage, daysToShow, profile); + var iobBin = loopalyzer.getIOBs(datastorage, daysToShow, profile, client, insulinTreatments); + var cobBin = loopalyzer.getCOBs(datastorage, daysToShow, profile, client, carbTreatments); var predictionsBin = []; if ($("#rp_loopalyzerpredictions").is(":checked")) { - predictionsBin = loopalyzer.getPredictions(datastorage,daysToShow,client); + predictionsBin = loopalyzer.getPredictions(datastorage, daysToShow, client); } // Prepare an array with the minutes to timeShift each day (0 as default since timeShift is off by default) @@ -950,76 +956,80 @@ loopalyzer.generateReport = function(datastorage,daysToShow,options) { var timeShiftStartTime = null; // If timeShifting this is the average time the meals were eaten var timeShiftStopTime = null; // and this is the start + DIA according to profile var doTimeShift = false; - daysToShow.forEach(function(){ timeShifts.push(0); firstCarbs.push(NaN) }); + daysToShow.forEach(function() { timeShifts.push(0); + firstCarbs.push(NaN) }); // Check to see if we are doing timeShift or not - if ($("#rp_loopalyzertimeshift").is(":checked") && daysToShow.length>1) { + if ($("#rp_loopalyzertimeshift").is(":checked") && daysToShow.length > 1) { var mealMinCarbs = $("#rp_loopalyzermincarbs").val(); var t1 = $("#rp_loopalyzert1").val(); var t2 = $("#rp_loopalyzert2").val(); - if (t2>t1) { + if (t2 > t1) { var h1 = t1.split(':')[0]; var m1 = t1.split(':')[1]; var h2 = t2.split(':')[0]; var m2 = t2.split(':')[1]; - + var timeShiftBegin = moment(); - timeShiftBegin.set({'hours':h1, 'minutes':m1, 'seconds':0}); - + timeShiftBegin.set({ 'hours': h1, 'minutes': m1, 'seconds': 0 }); + var timeShiftEnd = moment(); - timeShiftEnd.set({'hours':h2, 'minutes':m2, 'seconds':0}); - + timeShiftEnd.set({ 'hours': h2, 'minutes': m2, 'seconds': 0 }); + //Loop through the carb treatments and find the first meal each day - daysToShow.forEach(function(day, dayIndex){ + daysToShow.forEach(function(day, dayIndex) { var timeShiftBegin = moment(day); var timeShiftEnd = moment(day); - timeShiftBegin.set({'hours':h1, 'minutes':m1, 'seconds':0}); - timeShiftEnd.set({'hours':h2, 'minutes':m2, 'seconds':0}); - + timeShiftBegin.set({ 'hours': h1, 'minutes': m1, 'seconds': 0 }); + timeShiftEnd.set({ 'hours': h2, 'minutes': m2, 'seconds': 0 }); + var found = false; - carbTreatments.forEach(function(entry){ + carbTreatments.forEach(function(entry) { if (!found && entry.amount >= mealMinCarbs) { var date = moment(entry.date); - if ( (date.isSame(timeShiftBegin,'minute') || date.isAfter(timeShiftBegin,'minute')) && - (date.isSame(timeShiftEnd,'minute') || date.isBefore(timeShiftEnd,'minute')) ) { - var startOfDay = moment(entry.date); - startOfDay.set({'hours':0, 'minutes':0, 'seconds':0}); - var minutesAfterMidnight = date.diff(startOfDay, 'minutes'); - firstCarbs[dayIndex]=minutesAfterMidnight; - found = true; - doTimeShift = true; + if ((date.isSame(timeShiftBegin, 'minute') || date.isAfter(timeShiftBegin, 'minute')) && + (date.isSame(timeShiftEnd, 'minute') || date.isBefore(timeShiftEnd, 'minute'))) { + var startOfDay = moment(entry.date); + startOfDay.set({ 'hours': 0, 'minutes': 0, 'seconds': 0 }); + var minutesAfterMidnight = date.diff(startOfDay, 'minutes'); + firstCarbs[dayIndex] = minutesAfterMidnight; + found = true; + doTimeShift = true; } } }) }) - + // Calculate the average starting time, in minutes after midnight - var averageMinutesAfterMidnight = 0, sum = 0, count = 0; - firstCarbs.forEach(function(minutesAfterMidnight){ + var sum = 0 + , count = 0; + + firstCarbs.forEach(function(minutesAfterMidnight) { if (minutesAfterMidnight) { // Avoid NaN sum += minutesAfterMidnight; count++; } }); + var averageMinutesAfterMidnight = Math.round(sum / count); - + var dia = profile.getDIA(); if (!dia || dia <= 0) - dia=6; // Default to 6h if DIA not set in profile + dia = 6; // Default to 6h if DIA not set in profile timeShiftStartTime = moment(todayJSON); timeShiftStartTime.minutes(averageMinutesAfterMidnight); timeShiftStopTime = moment(todayJSON); - if (averageMinutesAfterMidnight + dia*60 < 24*60) - timeShiftStopTime.minutes(averageMinutesAfterMidnight + dia*60); // If not beyond midnight, stop at end of DIA + if (averageMinutesAfterMidnight + dia * 60 < 24 * 60) + timeShiftStopTime.minutes(averageMinutesAfterMidnight + dia * 60); // If not beyond midnight, stop at end of DIA else - timeShiftStopTime.minutes(24*60-1); // If beyond midnight, stop at midnight - + timeShiftStopTime.minutes(24 * 60 - 1); // If beyond midnight, stop at midnight + // Compute the timeShift (+ / -) that we should add to each entry (sgv, iob, carbs, etc) for each day - firstCarbs.forEach(function(minutesAfterMidnight,index){ + firstCarbs.forEach(function(minutesAfterMidnight, index) { if (minutesAfterMidnight) { // Avoid NaN var delta = Math.round(averageMinutesAfterMidnight - minutesAfterMidnight); - timeShifts[index]=delta; + timeShifts[index] = delta; } }); @@ -1050,7 +1060,7 @@ loopalyzer.generateReport = function(datastorage,daysToShow,options) { var low = options.targetLow; // Set up the charts basics - function tickFormatter(val,axis) { + function tickFormatter (val, axis) { if (val <= axis.min) { return ''; } if (val >= axis.max) { return ''; } return val + ''; @@ -1068,200 +1078,195 @@ loopalyzer.generateReport = function(datastorage,daysToShow,options) { var borderWidth = 1; var labelWidth = 25; var xaxisCfg = { - mode: 'time', - timezone: 'browser', - timeformat: '%H:%M', - tickColor: tickColor, - tickSize: [1, "hour"], - font: { size: 0 } + mode: 'time' + , timezone: 'browser' + , timeformat: '%H:%M' + , tickColor: tickColor + , tickSize: [1, "hour"] + , font: { size: 0 } }; var hiddenAxis = { - position: "right", - show: true, - labelWidth: 10, - tickColor: "#FFFFFF", - font: { size: 0} + position: "right" + , show: true + , labelWidth: 10 + , tickColor: "#FFFFFF" + , font: { size: 0 } } // For drawing the carbs and insulin treatments var markings = []; var markingColor = "#000000"; - // Chart 1: Basal markings = []; if (doTimeShift) - markings.push( { xaxis: { from: timeShiftStartTime.toDate(), to: timeShiftStopTime.toDate()}, color: timeShiftBackgroundColor } ); + markings.push({ xaxis: { from: timeShiftStartTime.toDate(), to: timeShiftStopTime.toDate() }, color: timeShiftBackgroundColor }); var chartBasalData = [{ - data: basalsAvg, - label: translate('Basal profile'), - id: 'basals', - color: basalColor, - points: { show: false }, - bars: { show: true, fill: true, barWidth: barWidth }, - yaxis: 1 + data: basalsAvg + , label: translate('Basal profile') + , id: 'basals' + , color: basalColor + , points: { show: false } + , bars: { show: true, fill: true, barWidth: barWidth } + , yaxis: 1 }]; var chartBasalOptions = { - xaxis: xaxisCfg, - yaxes: [{ - tickColor: tickColor, - labelWidth: labelWidth, - tickFormatter: function(val,axis) { return tickFormatter(val,axis); } - }, - hiddenAxis], - grid: { - borderWidth: borderWidth, - markings: markings + xaxis: xaxisCfg + , yaxes: [{ + tickColor: tickColor + , labelWidth: labelWidth + , tickFormatter: function(val, axis) { return tickFormatter(val, axis); } + } + , hiddenAxis] + , grid: { + borderWidth: borderWidth + , markings: markings } }; - $.plot( '#loopalyzer-basal', chartBasalData, chartBasalOptions ); - + $.plot('#loopalyzer-basal', chartBasalData, chartBasalOptions); // Chart 2: Blood glucose markings = []; if (doTimeShift) - markings.push( { xaxis: { from: timeShiftStartTime.toDate(), to: timeShiftStopTime.toDate()}, color: timeShiftBackgroundColor } ); + markings.push({ xaxis: { from: timeShiftStartTime.toDate(), to: timeShiftStopTime.toDate() }, color: timeShiftBackgroundColor }); markings.push({ yaxis: { from: low, to: high }, color: glucoseRangeColor }); var chartBGData = [{ - label: translate('Blood glucose'), - data: sgvAvg, - id: 'glucose', - color: glucoseColor, - points: { show: false }, - lines: { show: true } + label: translate('Blood glucose') + , data: sgvAvg + , id: 'glucose' + , color: glucoseColor + , points: { show: false } + , lines: { show: true } }]; - if (predictionsAvg && predictionsAvg.length>0) { + if (predictionsAvg && predictionsAvg.length > 0) { chartBGData.push({ - label: translate('Predictions'), - data: predictionsAvg, - id: 'predictions', - color: predictionsColor, - points: { show: true, fill: true, radius: 0.75, fillColor: predictionsColor }, - lines: { show: false } + label: translate('Predictions') + , data: predictionsAvg + , id: 'predictions' + , color: predictionsColor + , points: { show: true, fill: true, radius: 0.75, fillColor: predictionsColor } + , lines: { show: false } }); } var chartBGOptions = { - xaxis: xaxisCfg, - yaxes: [{ - min: 0, - max: options.units === 'mmol' ? 20 : 400, - tickColor: tickColor, - labelWidth: labelWidth, - tickFormatter: function(val,axis) { return tickFormatter(val,axis); } - }, - hiddenAxis], - grid: { - borderWidth: borderWidth, - markings: markings + xaxis: xaxisCfg + , yaxes: [{ + min: 0 + , max: options.units === 'mmol' ? 20 : 400 + , tickColor: tickColor + , labelWidth: labelWidth + , tickFormatter: function(val, axis) { return tickFormatter(val, axis); } + } + , hiddenAxis] + , grid: { + borderWidth: borderWidth + , markings: markings } }; - $.plot( '#loopalyzer-bg', chartBGData, chartBGOptions ); - + $.plot('#loopalyzer-bg', chartBGData, chartBGOptions); // Chart 3: Delta temp basals markings = []; if (doTimeShift) - markings.push( { xaxis: { from: timeShiftStartTime.toDate(), to: timeShiftStopTime.toDate()}, color: timeShiftBackgroundColor } ); - markings.push( { yaxis: { from: 0, to: 0 }, color: insulinColor, lineWidth: 2 }); + markings.push({ xaxis: { from: timeShiftStartTime.toDate(), to: timeShiftStopTime.toDate() }, color: timeShiftBackgroundColor }); + markings.push({ yaxis: { from: 0, to: 0 }, color: insulinColor, lineWidth: 2 }); var chartTempBasalData = [{ - data: tempBasalsAvg, - label: translate('Temp basal delta'), - id: 'tempBasals', - color: insulinColor, - points: { show: false }, - bars: { show: true, barWidth: barWidth } + data: tempBasalsAvg + , label: translate('Temp basal delta') + , id: 'tempBasals' + , color: insulinColor + , points: { show: false } + , bars: { show: true, barWidth: barWidth } }]; var chartTempBasalOptions = { - xaxis: xaxisCfg, - yaxes: [{ - tickColor: tickColor, - labelWidth: labelWidth, - tickFormatter: function(val,axis) { return tickFormatter(val,axis); } - }, - hiddenAxis], - grid: { - borderWidth: borderWidth, - markings: markings + xaxis: xaxisCfg + , yaxes: [{ + tickColor: tickColor + , labelWidth: labelWidth + , tickFormatter: function(val, axis) { return tickFormatter(val, axis); } + } + , hiddenAxis] + , grid: { + borderWidth: borderWidth + , markings: markings } }; - $.plot( '#loopalyzer-tempbasal', chartTempBasalData, chartTempBasalOptions ); - + $.plot('#loopalyzer-tempbasal', chartTempBasalData, chartTempBasalOptions); // Chart 4: IOB markings = []; if (doTimeShift) - markings.push( { xaxis: { from: timeShiftStartTime.toDate(), to: timeShiftStopTime.toDate()}, color: timeShiftBackgroundColor } ); - insulinTreatments.forEach(function(treatment){ + markings.push({ xaxis: { from: timeShiftStartTime.toDate(), to: timeShiftStopTime.toDate() }, color: timeShiftBackgroundColor }); + insulinTreatments.forEach(function(treatment) { var startDate = moment(treatment.date); var endDate = moment(treatment.date); startDate.set(todayJSON); endDate.set(todayJSON); endDate.add(5, 'minutes'); - markings.push( { xaxis: { from: startDate.toDate(), to: endDate.toDate()}, yaxis: { from: 0, to: treatment.amount }, color: markingColor } ); + markings.push({ xaxis: { from: startDate.toDate(), to: endDate.toDate() }, yaxis: { from: 0, to: treatment.amount }, color: markingColor }); }) var chartIOBData = [{ - data: iobAvg, - label: translate('IOB'), - id: 'iobs', - color: insulinColor, - points: { show: false }, - bars: { show: true, fill: true, barWidth: barWidth } + data: iobAvg + , label: translate('IOB') + , id: 'iobs' + , color: insulinColor + , points: { show: false } + , bars: { show: true, fill: true, barWidth: barWidth } }]; var chartIOBOptions = { - xaxis: xaxisCfg, - yaxes: [{ - tickColor: tickColor, - labelWidth: labelWidth, - tickFormatter: function(val,axis) { return tickFormatter(val,axis); } - }, - hiddenAxis], - grid: { - borderWidth: borderWidth, - markings: markings + xaxis: xaxisCfg + , yaxes: [{ + tickColor: tickColor + , labelWidth: labelWidth + , tickFormatter: function(val, axis) { return tickFormatter(val, axis); } + } + , hiddenAxis] + , grid: { + borderWidth: borderWidth + , markings: markings } }; - $.plot( '#loopalyzer-iob', chartIOBData, chartIOBOptions ); - + $.plot('#loopalyzer-iob', chartIOBData, chartIOBOptions); // Chart 5: COB markings = []; if (doTimeShift) - markings.push( { xaxis: { from: timeShiftStartTime.toDate(), to: timeShiftStopTime.toDate()}, color: timeShiftBackgroundColor } ); - carbTreatments.forEach(function(treatment){ + markings.push({ xaxis: { from: timeShiftStartTime.toDate(), to: timeShiftStopTime.toDate() }, color: timeShiftBackgroundColor }); + carbTreatments.forEach(function(treatment) { var startDate = moment(treatment.date); var endDate = moment(treatment.date); startDate.set(todayJSON); endDate.set(todayJSON); endDate.add(5, 'minutes'); - markings.push( { xaxis: { from: startDate.toDate(), to: endDate.toDate()}, yaxis: { from: 0, to: treatment.amount }, color: markingColor } ); + markings.push({ xaxis: { from: startDate.toDate(), to: endDate.toDate() }, yaxis: { from: 0, to: treatment.amount }, color: markingColor }); }) delete xaxisCfg.font; // Remove the font config so HH:MM is shown on the last chart var chartCOBData = [{ - data: cobAvg, - label: translate('COB'), - id: 'cobs', - color: carbColor, - points: { show: false }, - bars: { show: true, fil: true, barWidth: barWidth } + data: cobAvg + , label: translate('COB') + , id: 'cobs' + , color: carbColor + , points: { show: false } + , bars: { show: true, fil: true, barWidth: barWidth } }]; var chartCOBOptions = { - xaxis: xaxisCfg, - yaxes: [{ - tickColor: tickColor, - labelWidth: labelWidth, - tickFormatter: function(val,axis) { return tickFormatter(val,axis); } - }, - hiddenAxis], - grid: { - borderWidth: borderWidth, - markings: markings + xaxis: xaxisCfg + , yaxes: [{ + tickColor: tickColor + , labelWidth: labelWidth + , tickFormatter: function(val, axis) { return tickFormatter(val, axis); } + } + , hiddenAxis] + , grid: { + borderWidth: borderWidth + , markings: markings } }; - $.plot( '#loopalyzer-cob', chartCOBData, chartCOBOptions ); + $.plot('#loopalyzer-cob', chartCOBData, chartCOBOptions); }; diff --git a/lib/report_plugins/profiles.js b/lib/report_plugins/profiles.js index c31b8b2fa9a..580367891de 100644 --- a/lib/report_plugins/profiles.js +++ b/lib/report_plugins/profiles.js @@ -6,33 +6,32 @@ var profiles = { , pluginType: 'report' }; -function init() { +function init () { return profiles; } module.exports = init; -profiles.html = function html(client) { +profiles.html = function html (client) { var translate = client.translate; var ret = - '

' + translate('Profiles') + '

' - + '
' + translate('Database records') + ' ' - + '
' - + '
' - + '
' - + '
' - ; + '

' + translate('Profiles') + '

' + + '
' + translate('Database records') + ' ' + + '
' + + '
' + + '
' + + '
'; return ret; }; profiles.css = - '#profiles-chart {' - + ' width: 100%;' - + ' height: 100%;' - + '}' - ; + '#profiles-chart {' + + ' width: 100%;' + + ' height: 100%;' + + '}'; -profiles.report = function report_profiles(datastorage, sorteddaystoshow, options) { +// eslint-disable-next-line no-unused-vars +profiles.report = function report_profiles (datastorage, sorteddaystoshow, options) { var Nightscout = window.Nightscout; var client = Nightscout.client; var translate = client.translate; @@ -41,10 +40,10 @@ profiles.report = function report_profiles(datastorage, sorteddaystoshow, option var databaseRecords = $('#profiles-databaserecords'); databaseRecords.empty(); - for (var r = 0; r < profileRecords.length; r++ ) { + for (var r = 0; r < profileRecords.length; r++) { databaseRecords.append(''); } - databaseRecords.unbind().bind('change',recordChange); + databaseRecords.unbind().bind('change', recordChange); recordChange(); @@ -58,11 +57,10 @@ profiles.report = function report_profiles(datastorage, sorteddaystoshow, option var tr = $('
'); $('#profiles-default').val(currentrecord.defaultProfile); - for (var key in currentrecord.store) { - if (currentrecord.store.hasOwnProperty(key)) { - tr.append(displayRecord(currentrecord.store[key], key)) - } - } + + Object.keys(currentrecord.store).forEach(key => { + tr.append(displayRecord(currentrecord.store[key], key)); + }); table.append(tr); @@ -73,7 +71,7 @@ profiles.report = function report_profiles(datastorage, sorteddaystoshow, option } } - function displayRecord(record, name) { + function displayRecord (record, name) { var td = $('
' + entry.time + '' + parseFloat(entry.value).toFixed(1) + '
'; if (theProfile.sens) { - theProfile.sens.forEach(function (entry) { + theProfile.sens.forEach(function(entry) { tableHtml += '' }); } @@ -841,8 +848,8 @@ loopalyzer.renderProfilesTable = function (datastoreProfiles, daysToShow, client // Close theProfile table tableHtml += '
' + entry.time + '' + parseFloat(entry.value).toFixed(1) + '
.....
'); var table = $(''); @@ -91,7 +89,7 @@ profiles.report = function report_profiles(datastorage, sorteddaystoshow, option return td; } - function displayRanges(array, array2) { + function displayRanges (array, array2) { var text = ''; for (var i = 0; i < array.length; i++) { text += array[i].time + ' : ' + array[i].value + (array2 ? ' - ' + array2[i].value : '') + '
'; diff --git a/lib/report_plugins/success.js b/lib/report_plugins/success.js index d4ee4b9173e..a08ef8d045e 100644 --- a/lib/report_plugins/success.js +++ b/lib/report_plugins/success.js @@ -8,66 +8,60 @@ var success = { , pluginType: 'report' }; -function init() { +function init () { return success; } module.exports = init; -success.html = function html(client) { +success.html = function html (client) { var translate = client.translate; var ret = - '

' + translate('Weekly Success') + '

' - + '
' - ; + '

' + translate('Weekly Success') + '

' + + '
'; return ret; }; -success.css = - '#success-placeholder td {'+ - ' border: 1px #ccc solid;'+ - ' margin: 0;'+ - ' padding: 1px;'+ - ' text-align:center;'+ - '}'+ - '#success-placeholder .bad {'+ - ' background-color: #fcc;'+ - '}'+ - - '#success-placeholder .good {'+ - ' background-color: #cfc;'+ - '}'+ - - '#success-placeholder th:first-child {'+ - ' width: 30%;'+ - '}'+ - '#success-placeholder th {'+ - ' width: 10%;'+ - '}'+ - '#success-placeholder table {'+ - ' width: 100%;'+ - '}' - ; - - - -success.report = function report_success(datastorage, sorteddaystoshow, options) { +success.css = + `#success-placeholder td { + border: 1px #ccc solid; + margin: 0; + padding: 1px; + text-align:center; + } + #success-placeholder .bad { + background-color: #fcc; + } + #success-placeholder .good { + background-color: #cfc; + } + #success-placeholder th:first-child { + width: 30%; + } + #success-placeholder th { + width: 10%; + } + #success-placeholder table { + width: 100%; + }`; + +success.report = function report_success (datastorage, sorteddaystoshow, options) { var Nightscout = window.Nightscout; var client = Nightscout.client; var translate = client.translate; var ss = require('simple-statistics'); - var low = options.targetLow, - high = options.targetHigh; + var low = options.targetLow + , high = options.targetHigh; var data = datastorage.allstatsrecords; - + var now = Date.now(); var period = 7 * times.hours(24).msecs; var firstDataPoint = data.reduce(function(min, record) { - return Math.min(min, record.displayTime); - }, Number.MAX_VALUE); + return Math.min(min, record.displayTime); + }, Number.MAX_VALUE); if (firstDataPoint < 1390000000000) { firstDataPoint = 1390000000000; } @@ -79,39 +73,39 @@ success.report = function report_success(datastorage, sorteddaystoshow, options) if (quarters === 0) { // insufficent data - grid.append('

'+translate('There is not sufficient data to run this report. Select more days.')+'

'); + grid.append('

' + translate('There is not sufficient data to run this report. Select more days.') + '

'); return; } var dim = function(n) { var a = []; for (var i = 0; i < n; i++) { - a[i]=0; + a[i] = 0; } return a; }; var sum = function(a) { - return a.reduce(function(sum,v) { - return sum+v; + return a.reduce(function(sum, v) { + return sum + v; }, 0); }; var averages = { - percentLow: 0, - percentInRange: 0, - percentHigh: 0, - standardDeviation: 0, - lowerQuartile: 0, - upperQuartile: 0, - average: 0 + percentLow: 0 + , percentInRange: 0 + , percentHigh: 0 + , standardDeviation: 0 + , lowerQuartile: 0 + , upperQuartile: 0 + , average: 0 }; quarters = dim(quarters).map(function(blank, n) { - var starting = new Date(now - (n+1) * period), - ending = new Date(now - n * period); + var starting = new Date(now - (n + 1) * period) + , ending = new Date(now - n * period); return { - starting: starting, - ending: ending, - records: data.filter(function(record) { - return record.displayTime > starting && record.displayTime <= ending; + starting: starting + , ending: ending + , records: data.filter(function(record) { + return record.displayTime > starting && record.displayTime <= ending; }) }; }).filter(function(quarter) { @@ -121,8 +115,8 @@ success.report = function report_success(datastorage, sorteddaystoshow, options) return record.sgv; }); quarter.standardDeviation = ss.standard_deviation(bgValues); - quarter.average = bgValues.length > 0? (sum(bgValues) / bgValues.length): 'N/A'; - quarter.lowerQuartile = ss.quantile(bgValues, 0.25); + quarter.average = bgValues.length > 0 ? (sum(bgValues) / bgValues.length) : 'N/A'; + quarter.lowerQuartile = ss.quantile(bgValues, 0.25); quarter.upperQuartile = ss.quantile(bgValues, 0.75); quarter.numberLow = bgValues.filter(function(bg) { return bg < low; @@ -148,9 +142,9 @@ success.report = function report_success(datastorage, sorteddaystoshow, options) var lowComparison = function(quarter, averages, field, invert) { if (quarter[field] < averages[field] * 0.8) { - return (invert? 'bad': 'good'); + return (invert ? 'bad' : 'good'); } else if (quarter[field] > averages[field] * 1.2) { - return (invert? 'good': 'bad'); + return (invert ? 'good' : 'bad'); } else { return ''; } @@ -172,44 +166,44 @@ success.report = function report_success(datastorage, sorteddaystoshow, options) } }; - table.append(''); + table.append(''); table.append('' + quarters.filter(function(quarter) { return quarter.records.length > 0; }).map(function(quarter) { var INVERT = true; return '' + [ - quarter.starting.toLocaleDateString() + ' - ' + quarter.ending.toLocaleDateString(), - { - klass: lowComparison(quarter, averages, 'percentLow'), - text: Math.round(quarter.percentLow) + '%' - }, - { - klass: lowComparison(quarter, averages, 'percentInRange', INVERT), - text: Math.round(quarter.percentInRange) + '%' - }, - { - klass: lowComparison(quarter, averages, 'percentHigh'), - text: Math.round(quarter.percentHigh) + '%' - }, - { - klass: lowComparison(quarter, averages, 'standardDeviation'), - text: (quarter.standardDeviation > 10? Math.round(quarter.standardDeviation): quarter.standardDeviation.toFixed(1)) - }, - { - klass: lowQuartileEvaluation(quarter, averages), - text: quarter.lowerQuartile - }, - { - klass: lowComparison(quarter, averages, 'average'), - text: quarter.average.toFixed(1) - }, - { - klass: upperQuartileEvaluation(quarter, averages), - text: quarter.upperQuartile + quarter.starting.toLocaleDateString() + ' - ' + quarter.ending.toLocaleDateString() + , { + klass: lowComparison(quarter, averages, 'percentLow') + , text: Math.round(quarter.percentLow) + '%' + } + , { + klass: lowComparison(quarter, averages, 'percentInRange', INVERT) + , text: Math.round(quarter.percentInRange) + '%' + } + , { + klass: lowComparison(quarter, averages, 'percentHigh') + , text: Math.round(quarter.percentHigh) + '%' + } + , { + klass: lowComparison(quarter, averages, 'standardDeviation') + , text: (quarter.standardDeviation > 10 ? Math.round(quarter.standardDeviation) : quarter.standardDeviation.toFixed(1)) + } + , { + klass: lowQuartileEvaluation(quarter, averages) + , text: quarter.lowerQuartile + } + , { + klass: lowComparison(quarter, averages, 'average') + , text: quarter.average.toFixed(1) + } + , { + klass: upperQuartileEvaluation(quarter, averages) + , text: quarter.upperQuartile } ].map(function(v) { if (typeof v === 'object') { - return ''; + return ''; } else { return ''; } diff --git a/lib/report_plugins/treatments.js b/lib/report_plugins/treatments.js index e6221c8b656..c0215b59b4a 100644 --- a/lib/report_plugins/treatments.js +++ b/lib/report_plugins/treatments.js @@ -44,6 +44,16 @@ treatments.html = function html(client) { + ' ' + ' ' + '
' + + ' ' + + '
' + + ' ' + + '
' + '
'+translate('Period')+''+translate('Low')+''+translate('In Range')+''+translate('High')+''+translate('Standard Deviation')+''+translate('Low Quartile')+''+translate('Average')+''+translate('Upper Quartile')+'
' + translate('Period') + '' + translate('Low') + '' + translate('In Range') + '' + translate('High') + '' + translate('Standard Deviation') + '' + translate('Low Quartile') + '' + translate('Average') + '' + translate('Upper Quartile') + '
' + v.text + '' + v.text + '' + v + '').css('width','150px').attr('align','left').append(translate('Blood Glucose'))) .append($('').css('width','50px').attr('align','left').append(translate('Insulin'))) .append($('').css('width','50px').attr('align','left').append(translate('Carbs'))) + .append($('').css('width','50px').attr('align','left').append(translate('Protein'))) + .append($('').css('width','50px').attr('align','left').append(translate('Fat'))) .append($('').css('width','50px').attr('align','left').append(translate('Duration'))) .append($('').css('width','50px').attr('align','left').append(translate('Percent'))) .append($('').css('width','50px').attr('align','left').append(translate('Basal value'))) @@ -309,6 +327,8 @@ treatments.report = function report_treatments(datastorage, sorteddaystoshow, op .append($('').attr('align','center').append(tr.glucose ? tr.glucose + ' ('+translate(tr.glucoseType)+')' : '')) .append($('').attr('align','center').append(tr.insulin ? tr.insulin.toFixed(2) : '')) .append($('').attr('align','center').append(tr.carbs ? tr.carbs : '')) + .append($('').attr('align','center').append(tr.protein ? tr.protein : '')) + .append($('').attr('align','center').append(tr.fat ? tr.fat : '')) .append($('').attr('align','center').append(tr.duration ? tr.duration.toFixed(0) : '')) .append($('').attr('align','center').append(tr.percent ? tr.percent : '')) .append($('').attr('align','center').append('absolute' in tr ? tr.absolute.toFixed(2) : '')) diff --git a/lib/sandbox.js b/lib/sandbox.js index 3379bf509ea..ceac9a3fe29 100644 --- a/lib/sandbox.js +++ b/lib/sandbox.js @@ -4,21 +4,21 @@ var _ = require('lodash'); var units = require('./units')(); var times = require('./times'); -function init ( ) { +function init () { var sbx = {}; - function reset () { - sbx.properties = { }; + function reset () { + sbx.properties = {}; } - function extend ( ) { + function extend () { sbx.unitsLabel = unitsLabel(); sbx.data = sbx.data || {}; //default to prevent adding checks everywhere - sbx.extendedSettings = {empty: true}; + sbx.extendedSettings = { empty: true }; } - function withExtendedSettings(plugin, allExtendedSettings, sbx) { + function withExtendedSettings (plugin, allExtendedSettings, sbx) { var sbx2 = _.extend({}, sbx); sbx2.extendedSettings = allExtendedSettings && allExtendedSettings[plugin.name] || {}; return sbx2; @@ -48,7 +48,7 @@ function init ( ) { sbx.settings = env.settings; sbx.data = ctx.ddata.clone(); sbx.notifications = safeNotifications(ctx); - + sbx.levels = ctx.levels; sbx.language = ctx.language; sbx.translate = ctx.language.translate; @@ -60,7 +60,7 @@ function init ( ) { sbx.data.profile = profile; delete sbx.data.profiles; - sbx.properties = { }; + sbx.properties = {}; sbx.withExtendedSettings = function getPluginExtendedSettingsOnly (plugin) { return withExtendedSettings(plugin, env.extendedSettings, sbx); @@ -89,7 +89,7 @@ function init ( ) { sbx.data = data; sbx.pluginBase = ctx.pluginBase; sbx.notifications = safeNotifications(ctx); - + sbx.levels = ctx.levels; sbx.language = ctx.language; sbx.translate = ctx.language.translate; @@ -99,7 +99,7 @@ function init ( ) { sbx.pluginBase.forecastPoints = []; } - sbx.extendedSettings = {empty: true}; + sbx.extendedSettings = { empty: true }; sbx.withExtendedSettings = function getPluginExtendedSettingsOnly (plugin) { return withExtendedSettings(plugin, sbx.settings.extendedSettings, sbx); }; @@ -116,7 +116,7 @@ function init ( ) { * @param setter */ sbx.offerProperty = function offerProperty (name, setter) { - if (!sbx.properties.hasOwnProperty(name)) { + if (!Object.keys(sbx.properties).includes(name)) { var value = setter(); if (value) { sbx.properties[name] = value; @@ -124,7 +124,7 @@ function init ( ) { } }; - sbx.isCurrent = function isCurrent(entry) { + sbx.isCurrent = function isCurrent (entry) { return entry && sbx.time - entry.mills <= times.mins(15).msecs; }; @@ -137,7 +137,7 @@ function init ( ) { sbx.lastNEntries = function lastNEntries (entries, n) { var lastN = []; - _.takeRightWhile(entries, function (entry) { + _.takeRightWhile(entries, function(entry) { if (sbx.entryMills(entry) <= sbx.time) { lastN.push(entry); } @@ -158,32 +158,32 @@ function init ( ) { return sbx.prevEntry(sbx.data.sgvs); }; - sbx.lastSGVEntry = function lastSGVEntry ( ) { + sbx.lastSGVEntry = function lastSGVEntry () { return sbx.lastEntry(sbx.data.sgvs); }; - sbx.lastSGVMgdl = function lastSGVMgdl ( ) { + sbx.lastSGVMgdl = function lastSGVMgdl () { var last = sbx.lastSGVEntry(); return last && last.mgdl; }; - sbx.lastSGVMills = function lastSGVMills ( ) { + sbx.lastSGVMills = function lastSGVMills () { return sbx.entryMills(sbx.lastSGVEntry()); }; - sbx.entryMills = function entryMills(entry) { + sbx.entryMills = function entryMills (entry) { return entry && entry.mills; }; - sbx.lastScaledSGV = function lastScaledSVG ( ) { + sbx.lastScaledSGV = function lastScaledSVG () { return sbx.scaleEntry(sbx.lastSGVEntry()); }; - sbx.lastDisplaySVG = function lastDisplaySVG ( ) { + sbx.lastDisplaySVG = function lastDisplaySVG () { return sbx.displayBg(sbx.lastSGVEntry()); }; - sbx.buildBGNowLine = function buildBGNowLine ( ) { + sbx.buildBGNowLine = function buildBGNowLine () { var line = 'BG Now: ' + sbx.lastDisplaySVG(); var delta = sbx.properties.delta && sbx.properties.delta.display; @@ -216,7 +216,7 @@ function init ( ) { return lines; }; - sbx.prepareDefaultLines = function prepareDefaultLines() { + sbx.prepareDefaultLines = function prepareDefaultLines () { var lines = [sbx.buildBGNowLine()]; sbx.appendPropertyLine('rawbg', lines); sbx.appendPropertyLine('ar2', lines); @@ -227,7 +227,7 @@ function init ( ) { return lines; }; - sbx.buildDefaultMessage = function buildDefaultMessage() { + sbx.buildDefaultMessage = function buildDefaultMessage () { return sbx.prepareDefaultLines().join('\n'); }; @@ -272,14 +272,10 @@ function init ( ) { if (sbx.properties.roundingStyle === 'medtronic') { var denominator = 0.1; var digits = 1; - if (insulin > 0.5 && iob < 1) { + if (insulin <= 0.5) { denominator = 0.05; digits = 2; } - if (insulin <= 0.5) { - denominator = 0.025; - digits = 3; - } return (Math.floor(insulin / denominator) * denominator).toFixed(digits); } @@ -287,7 +283,7 @@ function init ( ) { }; - function unitsLabel ( ) { + function unitsLabel () { return sbx.settings.units === 'mmol' ? 'mmol/L' : 'mg/dl'; } @@ -299,4 +295,3 @@ function init ( ) { } module.exports = init; - diff --git a/lib/server/bootevent.js b/lib/server/bootevent.js index ab8a55f18ac..9e53c4f77ac 100644 --- a/lib/server/bootevent.js +++ b/lib/server/bootevent.js @@ -10,33 +10,40 @@ function boot (env, language) { // Check Node version. // Latest Node 8 LTS and Latest Node 10 LTS are recommended and supported. // Latest Node version on Azure is tolerated, but not recommended - // Other versions will not start + // Latest Node (non LTS) version works, but is not recommended + // Older Node versions or Node versions with known security issues will not work. // More explicit: // < 8 does not work, not supported - // >= 8.15.0 works, supported and recommended + // >= 8.15.1 works, supported and recommended // == 9.x does not work, not supported - // == 10.14.1 works, not fully supported and not recommended (Azure version) - // == 10.14.2 does not work, not supported and not recommended, - // >= 10.15.1 works, supported and recommended - // >= 11.6.0 does not work, not recommended, will not be supported. We only support Node LTS releases + // == 10.15.2 works, not fully supported and not recommended (Azure version) + // >= 10.16.0 works, supported and recommended + // == 11.x does not work, not supported + // >= 12.6.0 does work, not recommended, will not be supported. We only support Node LTS releases /////////////////////////////////////////////////// - function checkNode (ctx, next) { + function checkNodeVersion (ctx, next) { var semver = require('semver'); var nodeVersion = process.version; - if ( semver.satisfies(nodeVersion, '^8.15.0') || semver.satisfies(nodeVersion, '^10.15.1')) { + if ( semver.satisfies(nodeVersion, '^8.15.1') || semver.satisfies(nodeVersion, '^10.16.0')) { //Latest Node 8 LTS and Latest Node 10 LTS are recommended and supported. - console.debug('Node version ' + nodeVersion + ' is supported'); + //Require at least Node 8 LTS and Node 10 LTS without known security issues + console.debug('Node LTS version ' + nodeVersion + ' is supported'); next(); } - else if ( semver.eq(nodeVersion, '10.14.1')) { + else if ( semver.eq(nodeVersion, '10.15.2')) { //Latest Node version on Azure is tolerated, but not recommended - console.log('WARNING: Node version v10.14.1 and Microsoft Azure are not recommended.'); + console.log('WARNING: Node version v10.15.2 and Microsoft Azure are not recommended.'); console.log('WARNING: Please migrate to another hosting provider. Your Node version is outdated and insecure'); next(); + } + else if ( semver.satisfies(nodeVersion, '^12.6.0')) { + //Latest Node version + console.debug('Node version ' + nodeVersion + ' is not a LTS version. Not recommended. Not supported'); + next(); } else { // Other versions will not start - console.log( 'ERROR: Node version ' + nodeVersion + ' is not supported. Please upgrade your Node'); + console.log( 'ERROR: Node version ' + nodeVersion + ' is not supported. Please use a secure LTS version or upgrade your Node'); process.exit(1); } } @@ -62,6 +69,7 @@ function boot (env, language) { try { href = url.parse(configURL).href; } catch (e) { + console.error('Parsing config URL from IMPORT_CONFIG failed'); } if(configURL && href) { var request = require('request'); @@ -264,7 +272,7 @@ function boot (env, language) { } return require('bootevent')( ) - .acquire(checkNode) + .acquire(checkNodeVersion) .acquire(checkEnv) .acquire(augmentSettings) .acquire(setupStorage) diff --git a/lib/server/clocks.js b/lib/server/clocks.js new file mode 100644 index 00000000000..282acd01951 --- /dev/null +++ b/lib/server/clocks.js @@ -0,0 +1,35 @@ +'use strict'; + +const express = require('express'); +const path = require('path'); + +// eslint-disable-next-line no-unused-vars +function clockviews(env, ctx) { + + const app = new express(); + let locals = {}; + + app.set('view engine', 'ejs'); + app.engine('html', require('ejs').renderFile); + app.set("views", path.join(__dirname, "../../views/clockviews/")); + + app.get('/:face', (req, res) => { + + const face = req.params.face; + console.log('Clockface requested:', face); + + res.render('shared.html', { + face, + locals + }); + + }); + + app.setLocals = function (_locals) { + locals = _locals; + } + + return app; +} + +module.exports = clockviews; \ No newline at end of file diff --git a/lib/server/devicestatus.js b/lib/server/devicestatus.js index e74c0124841..d35c6be87cb 100644 --- a/lib/server/devicestatus.js +++ b/lib/server/devicestatus.js @@ -1,14 +1,17 @@ 'use strict'; +var moment = require('moment'); var find_options = require('./query'); function storage (collection, ctx) { - var ObjectID = require('mongodb').ObjectID; function create(obj, fn) { - if (! obj.hasOwnProperty('created_at')){ - obj.created_at = (new Date()).toISOString(); - } + + // Normalize all dates to UTC + const d = moment(obj.created_at).isValid() ? moment.parseZone(obj.created_at) : moment(); + obj.created_at = d.toISOString(); + obj.utcOffset = d.utcOffset(); + api().insert(obj, function (err, doc) { if (err != null && err.message) { console.log('Error inserting the device status object', err.message); diff --git a/lib/server/entries.js b/lib/server/entries.js index 84f8f234bfa..d7258f13b79 100644 --- a/lib/server/entries.js +++ b/lib/server/entries.js @@ -3,6 +3,7 @@ var es = require('event-stream'); var find_options = require('./query'); var ObjectID = require('mongodb').ObjectID; +var moment = require('moment'); /**********\ * Entries @@ -87,6 +88,16 @@ function storage(env, ctx) { totalCreated = 0; docs.forEach(function(doc) { + + // Normalize dates to be in UTC, store offset in utcOffset + + var _sysTime = moment(doc.dateString).isValid() ? moment.parseZone(doc.dateString) : moment(doc.date); + _sysTime = _sysTime.isValid() ? _sysTime : moment(); + + doc.utcOffset = _sysTime.utcOffset(); + doc.sysTime = _sysTime.toISOString(); + if (doc.dateString) doc.dateString = doc.sysTime; + var query = (doc.sysTime && doc.type) ? {sysTime: doc.sysTime, type: doc.type} : doc; api( ).update(query, doc, {upsert: true}, function (err) { firstErr = firstErr || err; diff --git a/lib/server/pushnotify.js b/lib/server/pushnotify.js index 49748851659..ae30e67d7f0 100644 --- a/lib/server/pushnotify.js +++ b/lib/server/pushnotify.js @@ -1,15 +1,15 @@ 'use strict'; -var _ = require('lodash'); -var crypto = require('crypto'); -var NodeCache = require('node-cache'); +const _ = require('lodash'); +const crypto = require('crypto'); +const NodeCache = require('node-cache'); -var levels = require('../levels'); -var times = require('../times'); +const levels = require('../levels'); +const times = require('../times'); -function init(env, ctx) { +function init (env, ctx) { - function pushnotify() { + function pushnotify () { return pushnotify; } @@ -23,19 +23,22 @@ function init(env, ctx) { return; } - var key = null; - if (notify.isAnnouncement) { - //Announcement notifications are sent if they are different from whats been recently sent - key = notifyToHash(notify); - } else if (levels.isAlarm(notify.level)) { - //Alarms can be snoozed - //for WARN and higher use the plugin name and notification level so that louder alarms aren't triggered too often - key = notify.plugin.name + '_' + notify.level; - } else { - //INFO and lower notifications should be sent as long as they are different from whats been recently sent - key = notifyToHash(notify); - } + var key = notify.notifyhash || false; + if (!key) { + if (notify.isAnnouncement) { + //Announcement notifications are sent if they are different from whats been recently sent + key = notifyToHash(notify); + } else if (levels.isAlarm(notify.level)) { + //Alarms can be snoozed + //for WARN and higher use the plugin name and notification level so that louder alarms aren't triggered too often + key = notify.plugin.name + '_' + notify.level; + } else { + //INFO and lower notifications should be sent as long as they are different from whats been recently sent + key = notifyToHash(notify); + } + } + notify.key = key; if (recentlySent.get(key)) { @@ -69,12 +72,12 @@ function init(env, ctx) { return !!notify; }; - function cancelPushoverNotifications ( ) { + function cancelPushoverNotifications () { if (ctx.pushover) { var receiptKeys = receipts.keys(); - _.each(receiptKeys, function eachKey(receipt) { - ctx.pushover.cancelWithReceipt(receipt, function cancelCallback(err) { + _.each(receiptKeys, function eachKey (receipt) { + ctx.pushover.cancelWithReceipt(receipt, function cancelCallback (err) { if (err) { console.error('error canceling receipt:' + receipt + ', err: ', err); } else { @@ -89,7 +92,7 @@ function init(env, ctx) { function sendPushoverNotifications (notify) { if (ctx.pushover) { //add the key to the cache before sending, but with a short TTL - ctx.pushover.send(notify, function pushoverCallback(err, result) { + ctx.pushover.send(notify, function pushoverCallback (err, result) { if (err) { console.warn('Unable to send pushover', notify, err); } else { @@ -152,5 +155,4 @@ function init(env, ctx) { return pushnotify(); } - -module.exports = init; \ No newline at end of file +module.exports = init; diff --git a/lib/server/query.js b/lib/server/query.js index 0b5de5601b9..8279d5ad1e8 100644 --- a/lib/server/query.js +++ b/lib/server/query.js @@ -1,9 +1,10 @@ 'use strict'; -var traverse = require('traverse'); -var ObjectID = require('mongodb').ObjectID; +const traverse = require('traverse'); +const ObjectID = require('mongodb').ObjectID; +const moment = require('moment'); -var TWO_DAYS = 172800000; +const TWO_DAYS = 172800000; /** * @module query utilities * Assist in translating objects from query-string representation into @@ -56,6 +57,26 @@ function default_options (opts) { function enforceDateFilter (query, opts) { var dateValue = query[opts.dateField]; + // rewrite dates to ISO UTC strings so queries work as expected + if (dateValue) { + Object.keys(dateValue).forEach(function(key) { + let dateString = dateValue[key]; + if (isNaN(dateString)) { + dateString = dateString.replace(' ', '+'); // some clients don't excape the plus + + const validDate = moment(dateString).isValid(); + + if (!validDate) { + console.error('API request using an invalid date:', dateString); + throw new Error('Cannot parse ' + dateString + ' as a valid ISO-8601 date'); + } + + const d = moment.parseZone(dateString); + dateValue[key] = d.toISOString(); + } + }); + } + if (!dateValue && !query.dateString && true !== opts.noDateFilter) { var minDate = Date.now( ) - opts.deltaAgo; query[opts.dateField] = { @@ -94,7 +115,11 @@ function create (params, opts) { var query = finder && finder.find ? finder.find : { }; // Ensure some kind of sane date constraint tied to an index is expressed in the query. - enforceDateFilter(query, opts); + // unless an ID is provided, in which case assume the user knows what they are doing. + if (! query._id ) { + enforceDateFilter(query, opts); + } + // Help queries for _id. updateIdQuery(query); diff --git a/lib/server/treatments.js b/lib/server/treatments.js index aa8f1e0d8af..c02bd50f317 100644 --- a/lib/server/treatments.js +++ b/lib/server/treatments.js @@ -2,6 +2,7 @@ var _ = require('lodash'); var async = require('async'); +var moment = require('moment'); var find_options = require('./query'); @@ -24,6 +25,7 @@ function storage (env, ctx) { errs.push(err); callback(err, docs) }); + // eslint-disable-next-line no-unused-vars }, function (err, docs) { errs = _.compact(errs); done(errs.length > 0 ? errs : null, allDocs); @@ -143,12 +145,20 @@ function storage (env, ctx) { function prepareData(obj) { + // Convert all dates to UTC dates + + const d = moment(obj.created_at).isValid() ? moment.parseZone(obj.created_at) : moment(); + obj.created_at = d.toISOString(); + var results = { - //TODO: validate format of created_at - created_at: obj.created_at || new Date().toISOString() + created_at: obj.created_at , preBolusCarbs: '' }; + const offset = d.utcOffset(); + obj.utcOffset = offset; + results.offset = offset; + obj.glucose = Number(obj.glucose); obj.targetTop = Number(obj.targetTop); obj.targetBottom = Number(obj.targetBottom); diff --git a/lib/server/websocket.js b/lib/server/websocket.js index 11451a50586..fb0aa38b349 100644 --- a/lib/server/websocket.js +++ b/lib/server/websocket.js @@ -34,6 +34,7 @@ function init (env, ctx, server) { }; // This is little ugly copy but I was unable to pass testa after making module from status and share with /api/v1/status + // eslint-disable-next-line no-unused-vars function status (profile) { var versionNum = 0; var verParse = /(\d+)\.(\d+)\.(\d+)*/.exec(env.version); diff --git a/lib/settings.js b/lib/settings.js index e4d15f99f63..2d16abd0f2d 100644 --- a/lib/settings.js +++ b/lib/settings.js @@ -3,7 +3,7 @@ var _ = require('lodash'); var levels = require('./levels'); -function init ( ) { +function init () { var settings = { units: 'mg/dL' @@ -41,12 +41,14 @@ function init ( ) { , bgTargetTop: 180 , bgTargetBottom: 80 , bgLow: 55 - }, - insecureUseHttp: false, - secureHstsHeader: true, - secureHstsHeaderIncludeSubdomains: false, - secureHstsHeaderPreload: false, - secureCsp: false + } + , insecureUseHttp: false + , secureHstsHeader: true + , secureHstsHeaderIncludeSubdomains: false + , secureHstsHeaderPreload: false + , secureCsp: false + , showClockClosebutton: true + , deNormalizeDates: false }; var valueMappers = { @@ -67,7 +69,8 @@ function init ( ) { , insecureUseHttp: mapTruthy , secureHstsHeader: mapTruthy , secureCsp: mapTruthy - + , showClockClosebutton: mapTruthy + , deNormalizeDates: mapTruthy }; function mapNumberArray (value) { @@ -77,7 +80,7 @@ function init ( ) { if (isNaN(value)) { var rawValues = value && value.split(' ') || []; - return _.map(rawValues, function (num) { + return _.map(rawValues, function(num) { return isNaN(num) ? null : Number(num); }); } else { @@ -153,18 +156,18 @@ function init ( ) { } function anyEnabled (features) { - return _.findIndex(features, function (feature) { + return _.findIndex(features, function(feature) { return enable.indexOf(feature) > -1; }) > -1; } - function prepareAlarmTypes ( ) { + function prepareAlarmTypes () { var alarmTypes = _.filter(getAndPrepare('alarmTypes'), function onlyKnownTypes (type) { return type === 'predict' || type === 'simple'; }); if (alarmTypes.length === 0) { - var thresholdWasSet = _.findIndex(wasSet, function (name) { + var thresholdWasSet = _.findIndex(wasSet, function(name) { return name.indexOf('bg') === 0; }) > -1; alarmTypes = thresholdWasSet ? ['simple'] : ['predict']; @@ -209,7 +212,7 @@ function init ( ) { adjustShownPlugins(); } - function verifyThresholds() { + function verifyThresholds () { var thresholds = settings.thresholds; if (thresholds.bgTargetBottom >= thresholds.bgTargetTop) { @@ -234,7 +237,7 @@ function init ( ) { } } - function adjustShownPlugins ( ) { + function adjustShownPlugins () { var showPluginsUnset = settings.showPlugins && 0 === settings.showPlugins.length; settings.showPlugins += ' delta direction upbat'; @@ -245,7 +248,7 @@ function init ( ) { if (showPluginsUnset) { //assume all enabled features are plugins and they should be shown for now //it would be better to use the registered plugins, but it's not loaded yet... - _.forEach(settings.enable, function showFeature(feature) { + _.forEach(settings.enable, function showFeature (feature) { if (isEnabled(feature)) { settings.showPlugins += ' ' + feature; } @@ -289,7 +292,7 @@ function init ( ) { var snoozeTime; if (notify.eventName === 'high' && notify.level === levels.URGENT && settings.alarmUrgentHigh) { - snoozeTime = settings.alarmUrgentHighMins; + snoozeTime = settings.alarmUrgentHighMins; } else if (notify.eventName === 'high' && settings.alarmHigh) { snoozeTime = settings.alarmHighMins; } else if (notify.eventName === 'low' && notify.level === levels.URGENT && settings.alarmUrgentLow) { diff --git a/lib/utils.js b/lib/utils.js index 1d407ccda05..fe1778f8120 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -26,7 +26,7 @@ function init(ctx) { }; utils.toFixed = function toFixed(value) { - if (value === undefined || value === 0) { + if (!value) { return '0'; } else { var fixed = value.toFixed(2); @@ -34,6 +34,15 @@ function init(ctx) { } }; + utils.toFixedMin = function toFixedMin(value,digits) { + if (!value) { + return '0'; + } + var mult = Math.pow(10,digits); + var fixed = Math.sign(value) * Math.round(Math.abs(value)*mult) / mult + return String(fixed); + }; + // some helpers for input "date" utils.mergeInputTime = function mergeInputTime(timestring, datestring) { return moment(datestring + ' ' + timestring, 'YYYY-MM-D HH:mm'); @@ -70,4 +79,4 @@ function init(ctx) { return utils; } -module.exports = init; \ No newline at end of file +module.exports = init; diff --git a/my.env.template b/my.env.template new file mode 100644 index 00000000000..0ca76ea5209 --- /dev/null +++ b/my.env.template @@ -0,0 +1,14 @@ +CUSTOMCONNSTR_mongo=mongodb://.... +CUSTOMCONNSTR_mongo_collection= +MONGO_PROFILE_COLLECTION= +API_SECRET=1234567890abc +HOSTNAME=0.0.0.0 +ENABLE="devicestatus rawbg upbat careportal iob profile cage bage avg cob basal treatments sage boluscalc pump openaps iage speech" +SHOW_PLUGINS="rawbg-on careportal upbat iob profile cage cob basal avg treatments boluscalc pump openaps iage speech" +DISPLAY_UNITS="mmol" +TIME_FORMAT=24 +ALARM_TYPES="predict" +LANGUAGE=en +INSECURE_USE_HTTP=true +PORT=1337 +NODE_ENV=development \ No newline at end of file diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index faa7b310f6d..f54cc8fa3b3 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,192 +1,351 @@ { "name": "nightscout", - "version": "0.11.1", + "version": "0.12.3-dev", "lockfileVersion": 1, "requires": true, "dependencies": { - "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", "dev": true, "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" + "@babel/highlight": "^7.0.0" } }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", + "@babel/generator": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.0.tgz", + "integrity": "sha512-/v5I+a1jhGSKLgZDcmAUZ4K/VePi43eRkUs3yePW1HB1iANOD5tqJXwGSG4BZhSksP8J9ejSlwGeTiiOFZOrXQ==", + "dev": true, + "requires": { + "@babel/types": "^7.4.0", + "jsesc": "^2.5.1", + "lodash": "^4.17.11", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + }, + "dependencies": { + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "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 + } + } + }, + "@babel/helper-function-name": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", + "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", + "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.0.tgz", + "integrity": "sha512-7Cuc6JZiYShaZnybDmfwhY4UYHzI6rlqhWjaIqbsJGsIqPimEYy5uh3akSRLMg65LSdSEnJ8a8/bWQN6u2oMGw==", + "dev": true, + "requires": { + "@babel/types": "^7.4.0" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + }, + "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" + } + }, + "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 + }, + "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/parser": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.3.tgz", + "integrity": "sha512-gxpEUhTS1sGA63EGQGuA+WESPR/6tz6ng7tSHFCmaTJK/cGK8y37cBTspX+U2xCAue2IQVvF6Z0oigmjwD8YGQ==", "dev": true }, + "@babel/template": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.0.tgz", + "integrity": "sha512-SOWwxxClTTh5NdbbYZ0BmaBVzxzTh2tO/TeLTbF6MO6EzVhHTnff8CdBXx3mEtazFBoysmEM6GU/wF+SuSx4Fw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.4.0", + "@babel/types": "^7.4.0" + } + }, + "@babel/traverse": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.3.tgz", + "integrity": "sha512-HmA01qrtaCwwJWpSKpA948cBvU5BrmviAief/b3AVw936DtcdsTexlbyzNuDnthwhOQ37xshn7hvQaEQk7ISYQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.4.0", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.0", + "@babel/parser": "^7.4.3", + "@babel/types": "^7.4.0", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.11" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.0.tgz", + "integrity": "sha512-aPvkXyU2SPOnztlgo8n9cEiXW755mgyvueUPcpStqdzoSPm0fjO0vQBjLkt3JKJW7ufikfcnMTTPsN1xaTsBPA==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" + } + }, + "@webassemblyjs/ast": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", + "integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==", + "requires": { + "@webassemblyjs/helper-module-context": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/wast-parser": "1.8.5" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz", + "integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==" + }, "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", - "dev": true + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz", + "integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==" }, "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", - "dev": true + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz", + "integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==" }, "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", - "dev": true, + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz", + "integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==", "requires": { - "@webassemblyjs/wast-printer": "1.7.11" + "@webassemblyjs/wast-printer": "1.8.5" } }, "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", - "dev": true + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz", + "integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==" }, "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz", + "integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==", + "requires": { + "@webassemblyjs/ast": "1.8.5", + "mamacro": "^0.0.3" + } }, "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", - "dev": true + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz", + "integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==" }, "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", - "dev": true, + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz", + "integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==", "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5" } }, "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", - "dev": true, + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz", + "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==", "requires": { "@xtuc/ieee754": "^1.2.0" } }, "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", - "dev": true, + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz", + "integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==", "requires": { - "@xtuc/long": "4.2.1" + "@xtuc/long": "4.2.2" } }, "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", - "dev": true + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz", + "integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==" }, "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", - "dev": true, + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz", + "integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==", "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/helper-wasm-section": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5", + "@webassemblyjs/wasm-opt": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5", + "@webassemblyjs/wast-printer": "1.8.5" } }, "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", - "dev": true, + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz", + "integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==", "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/ieee754": "1.8.5", + "@webassemblyjs/leb128": "1.8.5", + "@webassemblyjs/utf8": "1.8.5" } }, "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", - "dev": true, + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz", + "integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==", "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5" } }, "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", - "dev": true, + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz", + "integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==", "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-api-error": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/ieee754": "1.8.5", + "@webassemblyjs/leb128": "1.8.5", + "@webassemblyjs/utf8": "1.8.5" } }, "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", - "dev": true, + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz", + "integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==", "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/floating-point-hex-parser": "1.8.5", + "@webassemblyjs/helper-api-error": "1.8.5", + "@webassemblyjs/helper-code-frame": "1.8.5", + "@webassemblyjs/helper-fsm": "1.8.5", + "@xtuc/long": "4.2.2" } }, "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", - "dev": true, + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz", + "integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==", "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/wast-parser": "1.8.5", + "@xtuc/long": "4.2.2" } }, "@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" }, "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", - "dev": true + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" }, "abab": { "version": "1.0.4", @@ -213,28 +372,28 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==" }, - "acorn-dynamic-import": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", - "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", - "dev": true - }, "acorn-globals": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.0.tgz", - "integrity": "sha512-hMtHj3s5RnuhvHPowpBYvJVj3rAar82JiDQHvGs1zO0l10ocX/xEdBShNHTJaboucJUsScghp74pH3s7EnHHQw==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.2.tgz", + "integrity": "sha512-BbzvZhVtZP+Bs1J1HcwrQe8ycfO0wStkSGxuul3He3GkHOIZ6eTqOkPuw9IP1X3+IkOo4wiJmwkobzXYz4wewQ==", "requires": { "acorn": "^6.0.1", "acorn-walk": "^6.0.1" }, "dependencies": { "acorn": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.7.tgz", - "integrity": "sha512-HNJNgE60C9eOTgn974Tlp3dpLZdUr+SoxxDwPaY9J/kDNOLQTkaDgwBUXAF4SSsrAwD9RpdxuHK/EbuF+W9Ahw==" + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==" } } }, + "acorn-jsx": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", + "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==", + "dev": true + }, "acorn-walk": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", @@ -246,9 +405,9 @@ "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" }, "ajv": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.8.1.tgz", - "integrity": "sha512-eqxCp82P+JfqL683wwsL73XmFs1eG6qjw+RD3YHx+Jll1r0jNd4dh8QG9NYAeNGA/hnZjeEDgtTskgJULbxpWQ==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", + "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", "requires": { "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", @@ -259,14 +418,12 @@ "ajv-errors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==" }, "ajv-keywords": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.3.0.tgz", - "integrity": "sha512-CMzN9S62ZOO4sA/mJZIO4S++ZM7KFWzH3PPWkveLhy4OZ9i1/VatgwWMD46w/XbGCBy7Ye0gCk+Za6mmyfKK7g==", - "dev": true + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.0.tgz", + "integrity": "sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw==" }, "amdefine": { "version": "1.0.1", @@ -275,6 +432,60 @@ "dev": true, "optional": true }, + "ansi-align": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", + "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "dev": true, + "requires": { + "string-width": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "ansi-colors": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", + "dev": true + }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, + "ansi-html": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", + "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", + "dev": true + }, "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", @@ -285,21 +496,19 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "append-transform": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", + "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", "dev": true, "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" + "default-require-extensions": "^2.0.0" }, "dependencies": { "normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, "requires": { "remove-trailing-separator": "^1.0.1" } @@ -309,7 +518,12 @@ "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, "argparse": { @@ -324,20 +538,17 @@ "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" }, "arr-flatten": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" }, "arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" }, "array-equal": { "version": "1.0.0", @@ -349,15 +560,10 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, - "array-slice": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", - "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=" - }, "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" }, "arraybuffer.slice": { "version": "0.0.7", @@ -376,7 +582,6 @@ "version": "4.10.1", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, "requires": { "bn.js": "^4.0.0", "inherits": "^2.0.1", @@ -384,25 +589,23 @@ } }, "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", "requires": { + "object-assign": "^4.1.1", "util": "0.10.3" }, "dependencies": { "inherits": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" }, "util": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, "requires": { "inherits": "2.0.1" } @@ -417,7 +620,12 @@ "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + }, + "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": { @@ -426,10 +634,9 @@ "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=" }, "async-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", - "dev": true + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==" }, "async-limiter": { "version": "1.0.0", @@ -444,8 +651,7 @@ "atob": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" }, "aws-sign2": { "version": "0.7.0", @@ -467,6 +673,32 @@ "js-tokens": "^3.0.2" } }, + "babel-eslint": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.2.tgz", + "integrity": "sha512-UdsurWPtgiPgpJ06ryUnuaSXC2s0WoSZnQmEpbAH65XZSdwowgN5MvyP7e88nW07FYXv72erVtpBkxyDVKhH1Q==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "eslint-scope": "3.7.1", + "eslint-visitor-keys": "^1.0.0" + }, + "dependencies": { + "eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + } + } + }, "backo2": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", @@ -475,14 +707,12 @@ "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=" }, "base": { "version": "0.11.2", "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, "requires": { "cache-base": "^1.0.1", "class-utils": "^0.3.5", @@ -497,7 +727,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, "requires": { "is-descriptor": "^1.0.0" } @@ -506,7 +735,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -515,7 +743,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -524,7 +751,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -541,8 +767,7 @@ "base64-js": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", - "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", - "dev": true + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==" }, "base64id": { "version": "1.0.0", @@ -592,28 +817,20 @@ "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" }, - "binary-extensions": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.0.tgz", - "integrity": "sha512-EgmjVLMn22z7eGGv3kcnHwSnJXmFHjISTY9E/S5lIcTD3Oxw05QTcBLNkJFzcb3cNueUdF/IN4U+d78V0zO8Hw==", - "dev": true - }, "blob": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==" }, "bluebird": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", - "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==", - "dev": true + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.4.tgz", + "integrity": "sha512-FG+nFEZChJrbQ9tIccIfZJBz3J7mLrAhxakAbnrJWn8d7aKOC+LWifa0G+p4ZqKp4y13T7juYvdhq9NzKdsrjw==" }, "bn.js": { "version": "4.11.8", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" }, "body-parser": { "version": "1.18.3", @@ -640,48 +857,122 @@ "chainsaw": "~0.1.0" } }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-0.1.5.tgz", - "integrity": "sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY=", - "requires": { - "expand-range": "^0.1.0" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-process-hrtime": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", - "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==" - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "boxen": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", + "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", "dev": true, "requires": { - "buffer-xor": "^1.0.3", + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^2.0.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^1.2.0", + "widest-line": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "chalk": { + "version": "2.4.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" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "supports-color": { + "version": "5.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" + } + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "browser-process-hrtime": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", + "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==" + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "requires": { + "buffer-xor": "^1.0.3", "cipher-base": "^1.0.0", "create-hash": "^1.1.0", "evp_bytestokey": "^1.0.3", @@ -693,7 +984,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, "requires": { "browserify-aes": "^1.0.4", "browserify-des": "^1.0.0", @@ -704,7 +994,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, "requires": { "cipher-base": "^1.0.1", "des.js": "^1.0.0", @@ -716,7 +1005,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, "requires": { "bn.js": "^4.1.0", "randombytes": "^2.0.1" @@ -726,7 +1014,6 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", - "dev": true, "requires": { "bn.js": "^4.1.1", "browserify-rsa": "^4.0.0", @@ -741,21 +1028,19 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, "requires": { "pako": "~1.0.5" } }, "bson": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.0.tgz", - "integrity": "sha512-9Aeai9TacfNtWXOYarkFJRW2CWo+dRon+fuLZYJmvLV3+MiUp0bEI6IAZfXEIg7/Pl/7IWlLaDnhzTsD81etQA==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.1.tgz", + "integrity": "sha512-jCGVYLoYMHDkOsbwJZBCqwMHyH4c+wzgI9hG7Z6SZJRXWr+x58pdIbm2i9a/jFGCkRJqRUr8eoI7lDWa0hTkxg==" }, "buffer": { "version": "4.9.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", - "dev": true, "requires": { "base64-js": "^1.0.2", "ieee754": "^1.1.4", @@ -765,8 +1050,7 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" } } }, @@ -783,14 +1067,12 @@ "buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" }, "builtin-status-codes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=" }, "bytes": { "version": "3.0.0", @@ -801,7 +1083,6 @@ "version": "11.3.2", "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.2.tgz", "integrity": "sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg==", - "dev": true, "requires": { "bluebird": "^3.5.3", "chownr": "^1.1.1", @@ -823,7 +1104,6 @@ "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", @@ -832,6 +1112,19 @@ "once": "^1.3.0", "path-is-absolute": "^1.0.0" } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "requires": { + "yallist": "^3.0.2" + } + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" } } }, @@ -839,7 +1132,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, "requires": { "collection-visit": "^1.0.0", "component-emitter": "^1.2.1", @@ -852,22 +1144,63 @@ "unset-value": "^1.0.0" } }, + "caching-transform": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", + "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==", + "dev": true, + "requires": { + "hasha": "^3.0.0", + "make-dir": "^2.0.0", + "package-hash": "^3.0.0", + "write-file-atomic": "^2.4.2" + }, + "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } + } + }, "callsite": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=" }, - "camelcase": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", - "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, "camelize": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" }, + "capture-stack-trace": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", + "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==", + "dev": true + }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -900,6 +1233,12 @@ "supports-color": "^2.0.0" } }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, "check-types": { "version": "7.4.0", "resolved": "https://registry.npmjs.org/check-types/-/check-types-7.4.0.tgz", @@ -910,11 +1249,11 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.0.tgz", "integrity": "sha512-5t6G2SH8eO6lCvYOoUpaRnF5Qfd//gd7qJAkwRUw9qlGVkiQ13uwQngqbWWaurOsaAm9+kUGbITADxt6H0XFNQ==", - "dev": true, "requires": { "anymatch": "^2.0.0", "async-each": "^1.0.1", "braces": "^2.3.2", + "fsevents": "^1.2.7", "glob-parent": "^3.1.0", "inherits": "^2.0.3", "is-binary-path": "^1.0.0", @@ -925,17 +1264,39 @@ "upath": "^1.1.0" }, "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==" }, "braces": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, "requires": { "arr-flatten": "^1.1.0", "array-unique": "^0.3.2", @@ -953,33 +1314,89 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + } + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } } } }, "chownr": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", - "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", - "dev": true + "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==" }, "chrome-trace-event": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.0.tgz", - "integrity": "sha512-xDbVgyfDTT2piup/h8dK/y4QZfJRSa73bw1WZ8b4XM1o7fsFubUVGYcE+1ANtOzJJELGpYoG2961z0Z6OAld9A==", - "dev": true, + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", + "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", "requires": { "tslib": "^1.9.0" } }, + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "dev": true + }, "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, "requires": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -989,7 +1406,6 @@ "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, "requires": { "arr-union": "^3.1.0", "define-property": "^0.2.5", @@ -1001,7 +1417,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -1016,6 +1431,27 @@ "source-map": "~0.6.0" } }, + "cli-boxes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, "cliui": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", @@ -1033,6 +1469,16 @@ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", @@ -1059,7 +1505,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, "requires": { "map-visit": "^1.0.0", "object-visit": "^1.0.0" @@ -1078,11 +1523,6 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, - "colors": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz", - "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==" - }, "combined-stream": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", @@ -1092,15 +1532,14 @@ } }, "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==" + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==" }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" }, "component-bind": { "version": "1.0.0", @@ -1118,23 +1557,23 @@ "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=" }, "compressible": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.15.tgz", - "integrity": "sha512-4aE67DL33dSW9gw4CI2H/yTxqHLNcxp0yS6jB+4h+wr3e43+1z7vm0HU9qXOH8j+qjKuL8+UtkOxYQSMq60Ylw==", + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.16.tgz", + "integrity": "sha512-JQfEOdnI7dASwCuSPWIeVYwc/zMsu/+tRhoUvEfXz2gxOA2DNjmG5vhtFdBlhWPPGo+RdT9S3tgc/uH5qgDiiA==", "requires": { - "mime-db": ">= 1.36.0 < 2" + "mime-db": ">= 1.38.0 < 2" } }, "compression": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.3.tgz", - "integrity": "sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", "requires": { "accepts": "~1.3.5", "bytes": "3.0.0", - "compressible": "~2.0.14", + "compressible": "~2.0.16", "debug": "2.6.9", - "on-headers": "~1.0.1", + "on-headers": "~1.0.2", "safe-buffer": "5.1.2", "vary": "~1.1.2" } @@ -1142,14 +1581,12 @@ "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", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, "requires": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", @@ -1157,11 +1594,41 @@ "typedarray": "^0.0.6" } }, + "configstore": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", + "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "dev": true, + "requires": { + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + }, + "dependencies": { + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, "console-browserify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", - "dev": true, "requires": { "date-now": "^0.1.4" } @@ -1169,8 +1636,7 @@ "constants-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=" }, "content-disposition": { "version": "0.5.2", @@ -1187,6 +1653,15 @@ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, + "convert-source-map": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", + "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, "cookie": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", @@ -1207,7 +1682,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, "requires": { "aproba": "^1.1.1", "fs-write-stream-atomic": "^1.0.8", @@ -1220,29 +1694,66 @@ "copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "cp-file": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", + "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "make-dir": "^2.0.0", + "nested-error-stacks": "^2.0.0", + "pify": "^4.0.1", + "safe-buffer": "^5.0.1" + }, + "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } + } + }, "create-ecdh": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, "requires": { "bn.js": "^4.1.0", "elliptic": "^6.0.0" } }, - "create-hash": { - "version": "1.2.0", + "create-error-class": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "dev": true, + "requires": { + "capture-stack-trace": "^1.0.0" + } + }, + "create-hash": { + "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, "requires": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", @@ -1255,7 +1766,6 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, "requires": { "cipher-base": "^1.0.3", "create-hash": "^1.1.0", @@ -1269,20 +1779,25 @@ "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, "requires": { "nice-try": "^1.0.4", "path-key": "^2.0.1", "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + } } }, "crypto-browserify": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, "requires": { "browserify-cipher": "^1.0.0", "browserify-sign": "^4.0.0", @@ -1297,6 +1812,12 @@ "randomfill": "^1.0.3" } }, + "crypto-random-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", + "dev": true + }, "css-loader": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-1.0.1.tgz", @@ -1337,9 +1858,9 @@ "integrity": "sha1-yRlAd+Dr2s1pHV9ZAVudgZ840BU=" }, "cssom": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.4.tgz", - "integrity": "sha512-+7prCSORpXNeR4/fUP3rL+TzqtiFfhMvTd7uEqMdgPvLPt4+uzFUeufx5RHjGTACCargg/DiEt/moMQmvnfkog==" + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.6.tgz", + "integrity": "sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A==" }, "cssstyle": { "version": "0.3.1", @@ -1352,8 +1873,7 @@ "cyclist": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", - "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=", - "dev": true + "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=" }, "d3": { "version": "3.5.17", @@ -1403,8 +1923,7 @@ "date-now": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", - "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", - "dev": true + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=" }, "debug": { "version": "2.6.9", @@ -1417,13 +1936,17 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true }, "deep-is": { @@ -1431,11 +1954,19 @@ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, + "default-require-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", + "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", + "dev": true, + "requires": { + "strip-bom": "^3.0.0" + } + }, "define-property": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, "requires": { "is-descriptor": "^1.0.2", "isobject": "^3.0.1" @@ -1445,7 +1976,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -1454,7 +1984,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -1463,7 +1992,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -1486,7 +2014,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", - "dev": true, "requires": { "inherits": "^2.0.1", "minimalistic-assert": "^1.0.0" @@ -1500,8 +2027,7 @@ "detect-file": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", - "dev": true + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=" }, "diff": { "version": "3.5.0", @@ -1513,7 +2039,6 @@ "version": "5.0.3", "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, "requires": { "bn.js": "^4.1.0", "miller-rabin": "^4.0.0", @@ -1525,11 +2050,19 @@ "resolved": "https://registry.npmjs.org/dns-prefetch-control/-/dns-prefetch-control-0.1.0.tgz", "integrity": "sha1-YN20V3dOF48flBXwyrsOhbCzALI=" }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, "domain-browser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==" }, "domexception": { "version": "1.0.1", @@ -1544,16 +2077,30 @@ "resolved": "https://registry.npmjs.org/dont-sniff-mimetype/-/dont-sniff-mimetype-1.0.0.tgz", "integrity": "sha1-WTKJDcn04vGeXrAqIAJuXl78j1g=" }, + "dot-prop": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", + "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "dev": true, + "requires": { + "is-obj": "^1.0.0" + } + }, "duplexer": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, "duplexify": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, "requires": { "end-of-stream": "^1.0.0", "inherits": "^2.0.1", @@ -1571,9 +2118,9 @@ } }, "ecdsa-sig-formatter": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.10.tgz", - "integrity": "sha1-HFlQAPBKiJffuFAAiSoPTDOvhsM=", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", "requires": { "safe-buffer": "^5.0.1" } @@ -1589,10 +2136,9 @@ "integrity": "sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==" }, "elliptic": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", - "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", - "dev": true, + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.0.tgz", + "integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==", "requires": { "bn.js": "^4.4.0", "brorand": "^1.0.1", @@ -1603,6 +2149,11 @@ "minimalistic-crypto-utils": "^1.0.0" } }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + }, "emojis-list": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", @@ -1617,7 +2168,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "dev": true, "requires": { "once": "^1.4.0" } @@ -1709,22 +2259,38 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", - "dev": true, "requires": { "graceful-fs": "^4.1.2", "memory-fs": "^0.4.0", "tapable": "^1.0.0" } }, + "env-cmd": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/env-cmd/-/env-cmd-8.0.2.tgz", + "integrity": "sha512-gHX8MnQXw1iS7dc2KeJdBdxca7spIkxkNwIuORLwm8kDg6xHh5wWnv1Yv3pc64nLZR6kufQSCmwTz16sRmd/rg==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.5" + } + }, "errno": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, "requires": { "prr": "~1.0.1" } }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, "errorhandler": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.5.0.tgz", @@ -1734,6 +2300,12 @@ "escape-html": "~1.0.3" } }, + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -1745,9 +2317,9 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "escodegen": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.0.tgz", - "integrity": "sha512-IeMV45ReixHS53K/OmfKAIztN/igDHzTJUhZM3k1jMhIZWjk45SMwAtBsEXiJp3vSPmTcu6CXn7mDvFHRN66fw==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.1.tgz", + "integrity": "sha512-JwiqFD9KdGVVpeuRa68yU3zZnBEOcPs0nKW7wZzXky8Z7tffdYUHbe11bPCV5jYlK6DVdKLWLm0f5I/QlL0Kmw==", "requires": { "esprima": "^3.1.3", "estraverse": "^4.2.0", @@ -1756,26 +2328,209 @@ "source-map": "~0.6.1" } }, - "eslint-scope": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", - "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", + "eslint": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.0.1.tgz", + "integrity": "sha512-DyQRaMmORQ+JsWShYsSg4OPTjY56u1nCjAmICrE8vLWqyLKxhFXOthwMj1SA8xwfrv0CofLNVnqbfyhwCkaO0w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^4.0.3", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^6.0.0", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^3.1.0", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.2.2", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "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", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "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" + } + } + } + }, + "eslint-loader": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-2.1.2.tgz", + "integrity": "sha512-rA9XiXEOilLYPOIInvVH5S/hYfyTPyxag6DZhoQOduM+3TkghAEQ3VcFO8VnX4J4qg/UIBzp72aOf/xvYmpmsg==", "dev": true, + "requires": { + "loader-fs-cache": "^1.0.0", + "loader-utils": "^1.0.2", + "object-assign": "^4.0.1", + "object-hash": "^1.1.4", + "rimraf": "^2.6.1" + } + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", "requires": { "esrecurse": "^4.1.0", "estraverse": "^4.1.1" } }, + "eslint-utils": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", + "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "dev": true + }, + "espree": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.0.0.tgz", + "integrity": "sha512-lJvCS6YbCn3ImT3yKkPe0+tJ+mH6ljhGNjHQH9mRtiO6gjhVAOhVXW1yjnwqGwTkK3bGbye+hb00nFNmu0l/1Q==", + "dev": true, + "requires": { + "acorn": "^6.0.7", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + }, + "dependencies": { + "acorn": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", + "dev": true + } + } + }, "esprima": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, "esrecurse": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, "requires": { "estraverse": "^4.1.0" } @@ -1812,14 +2567,12 @@ "events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", - "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", - "dev": true + "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==" }, "evp_bytestokey": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, "requires": { "md5.js": "^1.3.4", "safe-buffer": "^5.1.1" @@ -1829,7 +2582,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, "requires": { "cross-spawn": "^6.0.0", "get-stream": "^4.0.0", @@ -1840,21 +2592,10 @@ "strip-eof": "^1.0.0" } }, - "expand-braces": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/expand-braces/-/expand-braces-0.1.2.tgz", - "integrity": "sha1-SIsdHSRRyz06axks/AMPRMWFX+o=", - "requires": { - "array-slice": "^0.2.3", - "array-unique": "^0.2.1", - "braces": "^0.1.2" - } - }, "expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, "requires": { "debug": "^2.3.3", "define-property": "^0.2.5", @@ -1869,7 +2610,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -1878,41 +2618,24 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } } } }, - "expand-range": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz", - "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=", - "requires": { - "is-number": "^0.1.1", - "repeat-string": "^0.2.2" - } - }, "expand-tilde": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dev": true, "requires": { "homedir-polyfill": "^1.0.1" } }, - "expect-ct": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/expect-ct/-/expect-ct-0.1.1.tgz", - "integrity": "sha512-ngXzTfoRGG7fYens3/RMb6yYoVLvLMfmsSllP/mZPxNHgFq41TmPSLF/nLY7fwoclI2vElvAmILFWGUYqdjfCg==" - }, "expose-loader": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/expose-loader/-/expose-loader-0.7.5.tgz", - "integrity": "sha512-iPowgKUZkTPX5PznYsmifVj9Bob0w2wTHVkt/eYNPSzyebkUgIedmskf/kcfEIWpiWjg3JRjnW+a17XypySMuw==", - "dev": true + "integrity": "sha512-iPowgKUZkTPX5PznYsmifVj9Bob0w2wTHVkt/eYNPSzyebkUgIedmskf/kcfEIWpiWjg3JRjnW+a17XypySMuw==" }, "express": { "version": "4.16.4", @@ -1977,7 +2700,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, "requires": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" @@ -1987,18 +2709,38 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, "requires": { "is-plain-object": "^2.0.4" } } } }, + "external-editor": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", + "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "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" + } + } + } + }, "extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, "requires": { "array-unique": "^0.3.2", "define-property": "^1.0.0", @@ -2010,17 +2752,10 @@ "to-regex": "^3.0.1" }, "dependencies": { - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, "define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, "requires": { "is-descriptor": "^1.0.0" } @@ -2029,7 +2764,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -2038,7 +2772,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -2047,7 +2780,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -2056,7 +2788,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -2090,22 +2821,33 @@ "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==" }, - "feature-policy": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/feature-policy/-/feature-policy-0.2.0.tgz", - "integrity": "sha512-2hGrlv6efG4hscYVZeaYjpzpT6I2OZgYqE2yDUzeAcKj2D1SH0AsEzqJNXzdoglEddcIXQQYop3lD97XpG75Jw==" - }, "figgy-pudding": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", - "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==", - "dev": true + "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==" + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } }, "file-loader": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-3.0.1.tgz", "integrity": "sha512-4sNIOXgtH/9WZq4NvlfU3Opn5ynUsqBwSLyM+I7UOwdGigTBYfVVQEwe/msZNX/j4pCJTIM14Fsw66Svo1oVrw==", - "dev": true, "requires": { "loader-utils": "^1.0.2", "schema-utils": "^1.0.0" @@ -2118,50 +2860,11 @@ "dev": true }, "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - } + "to-regex-range": "^5.0.1" } }, "finalhandler": { @@ -2186,82 +2889,118 @@ } }, "find-cache-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.0.0.tgz", - "integrity": "sha512-LDUY6V1Xs5eFskUVYtIwatojt6+9xC9Chnlk/jYOOvn3FAFfSaWddxahDGyNHh0b2dMXa6YW2m0tk8TdVaXHlA==", - "dev": true, + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", "requires": { "commondir": "^1.0.1", - "make-dir": "^1.0.0", + "make-dir": "^2.0.0", "pkg-dir": "^3.0.0" + }, + "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + } } }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, "requires": { "locate-path": "^3.0.0" } }, "findup-sync": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", - "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", - "dev": true, + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", "requires": { "detect-file": "^1.0.0", - "is-glob": "^3.1.0", + "is-glob": "^4.0.0", "micromatch": "^3.0.4", "resolve-dir": "^1.0.1" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } } }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "dev": true + }, "flot": { - "version": "0.8.0-alpha", - "resolved": "https://registry.npmjs.org/flot/-/flot-0.8.0-alpha.tgz", - "integrity": "sha1-nLvHFHwQpH0lSduQvSmH7BunhLo=" + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/flot/-/flot-0.8.3.tgz", + "integrity": "sha512-xg2otcTJDvS+ERK+my4wxG/ASq90QURXtoM4LhacCq0jQW2jbyjdttbRNqU2cPykrpMvJ6b2uSp6SAgYAzj9tQ==" }, "flush-write-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.0.tgz", - "integrity": "sha512-6MHED/cmsyux1G4/Cek2Z776y9t7WCNd3h2h/HW91vFeU7pzMhA8XvAlDhHcanG5IWuIh/xcC7JASY4WQpG6xg==", - "dev": true, + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", "requires": { "inherits": "^2.0.3", - "readable-stream": "^3.1.1" + "readable-stream": "^2.3.6" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "foreground-child": { + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", + "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", + "dev": true, + "requires": { + "cross-spawn": "^4", + "signal-exit": "^3.0.0" }, "dependencies": { - "readable-stream": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.1.1.tgz", - "integrity": "sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA==", + "cross-spawn": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", + "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", "dev": true, "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" } } } }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -2292,16 +3031,10 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, "requires": { "map-cache": "^0.2.2" } }, - "frameguard": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/frameguard/-/frameguard-3.0.0.tgz", - "integrity": "sha1-e8rUae57lukdEs6zlZx4I1qScuk=" - }, "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", @@ -2316,7 +3049,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, "requires": { "inherits": "^2.0.1", "readable-stream": "^2.0.0" @@ -2326,7 +3058,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, "requires": { "graceful-fs": "^4.1.2", "iferr": "^0.1.5", @@ -2337,1639 +3068,4086 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "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" - } + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "optional": true, "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" }, "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, + "abbrev": { + "version": "1.1.1", + "bundled": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "optional": true, "requires": { - "is-extglob": "^2.1.0" + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" } - } - } - }, - "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "requires": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - } - }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - } - }, - "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", - "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 - }, - "gzip-size": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.0.0.tgz", - "integrity": "sha512-5iI7omclyqrnWw4XbXAmGhPsABkSIDQonv2K0h61lybgofWa6iZyvrI3r2zsJH4P8Nb64fFVzlvfhs0g7BBxAA==", - "dev": true, - "requires": { - "duplexer": "^0.1.1", - "pify": "^3.0.0" - } - }, - "handlebars": { - "version": "4.0.12", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.12.tgz", - "integrity": "sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA==", - "dev": true, - "requires": { - "async": "^2.5.0", - "optimist": "^0.6.1", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4" - }, - "dependencies": { - "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", - "dev": true, + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "optional": true, "requires": { - "lodash": "^4.17.10" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } - } - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-binary2": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", - "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", - "requires": { - "isarray": "2.0.1" - } - }, - "has-cors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", - "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "optional": true, "requires": { - "kind-of": "^3.0.2" + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "optional": true + }, + "needle": { + "version": "2.3.0", + "bundled": true, + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "bundled": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "bundled": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" }, "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } + "minimist": { + "version": "1.2.0", + "bundled": true, + "optional": true } } }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "optional": true, "requires": { - "is-buffer": "^1.1.5" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } - } - } - }, - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "helmet": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.15.0.tgz", - "integrity": "sha512-j9JjtAnWJj09lqe/PEICrhuDaX30TeokXJ9tW6ZPhVH0+LMoihDeJ58CdWeTGzM66p6EiIODmgAaWfdeIWI4Gg==", - "requires": { - "dns-prefetch-control": "0.1.0", - "dont-sniff-mimetype": "1.0.0", - "expect-ct": "0.1.1", - "feature-policy": "0.2.0", - "frameguard": "3.0.0", - "helmet-crossdomain": "0.3.0", - "helmet-csp": "2.7.1", - "hide-powered-by": "1.0.0", - "hpkp": "2.0.0", - "hsts": "2.1.0", - "ienoopen": "1.0.0", - "nocache": "2.0.0", - "referrer-policy": "1.1.0", - "x-xss-protection": "1.1.0" + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "optional": true + }, + "semver": { + "version": "5.7.0", + "bundled": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "optional": true + } } }, - "helmet-crossdomain": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/helmet-crossdomain/-/helmet-crossdomain-0.3.0.tgz", - "integrity": "sha512-YiXhj0E35nC4Na5EPE4mTfoXMf9JTGpN4OtB4aLqShKuH9d2HNaJX5MQoglO6STVka0uMsHyG5lCut5Kzsy7Lg==" + "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 }, - "helmet-csp": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.7.1.tgz", - "integrity": "sha512-sCHwywg4daQ2mY0YYwXSZRsgcCeerUwxMwNixGA7aMLkVmPTYBl7gJoZDHOZyXkqPrtuDT3s2B1A+RLI7WxSdQ==", + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "requires": { - "camelize": "1.0.0", - "content-security-policy-builder": "2.0.0", - "dasherize": "2.0.0", - "platform": "1.3.5" + "pump": "^3.0.0" } }, - "hide-powered-by": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hide-powered-by/-/hide-powered-by-1.0.0.tgz", - "integrity": "sha1-SoWtZYgfYoV/xwr3F0oRhNzM4ys=" + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" + "assert-plus": "^1.0.0" } }, - "homedir-polyfill": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", - "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "requires": { - "parse-passwd": "^1.0.0" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, - "hoopy": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", - "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", - "dev": true - }, - "hpkp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hpkp/-/hpkp-2.0.0.tgz", - "integrity": "sha1-EOFCJk52IVpdMMROxD3mTe5tFnI=" - }, - "hsts": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hsts/-/hsts-2.1.0.tgz", - "integrity": "sha512-zXhh/DqgrTXJ7erTN6Fh5k/xjMhDGXCqdYN3wvxUvGUQvnxcFfUd8E+6vLg/nk3ss1TYMb+DhRl25fYABioTvA==" - }, - "html-encoding-sniffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", - "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "requires": { - "whatwg-encoding": "^1.0.1" + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "^2.1.0" + } + } } }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "dev": true, "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" + "ini": "^1.3.4" } }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "global-prefix": "^3.0.0" + }, + "dependencies": { + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + } + } } }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "iconv-lite": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" } }, - "icss-replace-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", - "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=" + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true }, - "icss-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-2.1.0.tgz", - "integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=", + "got": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "dev": true, "requires": { - "postcss": "^6.0.1" + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" + }, + "dependencies": { + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + } } }, - "ieee754": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", - "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", - "dev": true - }, - "ienoopen": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ienoopen/-/ienoopen-1.0.0.tgz", - "integrity": "sha1-NGpCj0dKrI9QzzeE6i0PFvYr2ms=" + "graceful-fs": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", + "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==" }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, - "import-local": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", - "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "gzip-size": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", + "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==", "dev": true, "requires": { - "pkg-dir": "^3.0.0", - "resolve-cwd": "^2.0.0" + "duplexer": "^0.1.1", + "pify": "^4.0.1" } }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "handlebars": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz", + "integrity": "sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==", "dev": true, "requires": { - "once": "^1.3.0", - "wrappy": "1" + "neo-async": "^2.6.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" } }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" }, - "interpret": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", - "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", - "dev": true + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } }, - "invert-kv": { + "has-ansi": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "dev": true + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } }, - "ipaddr.js": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", - "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=" + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "requires": { + "isarray": "2.0.1" + } }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "requires": { - "kind-of": "^3.0.2" + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" }, "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "requires": { "is-buffer": "^1.1.5" } } } }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hasha": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", + "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", "dev": true, "requires": { - "binary-extensions": "^1.0.0" + "is-stream": "^1.0.1" } }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", "dev": true }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, + "heapdump": { + "version": "0.3.14", + "resolved": "https://registry.npmjs.org/heapdump/-/heapdump-0.3.14.tgz", + "integrity": "sha512-omSf+s4yDxHWsh8uNdzhDQFi9tkuBEaxn3pUnHetcEB4XD5L/bWDAFmtnSHP2HmtfnYqkaK6Y76TbhfSOPP7/A==", "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } + "nan": "^2.13.2" } }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, + "helmet": { + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.18.0.tgz", + "integrity": "sha512-TsKlGE5UVkV0NiQ4PllV9EVfZklPjyzcMEMjWlyI/8S6epqgRT+4s4GHVgc25x0TixsKvp3L7c91HQQt5l0+QA==", "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "depd": "2.0.0", + "dns-prefetch-control": "0.1.0", + "dont-sniff-mimetype": "1.0.0", + "expect-ct": "0.2.0", + "feature-policy": "0.3.0", + "frameguard": "3.1.0", + "helmet-crossdomain": "0.3.0", + "helmet-csp": "2.7.1", + "hide-powered-by": "1.0.0", + "hpkp": "2.0.0", + "hsts": "2.2.0", + "ienoopen": "1.1.0", + "nocache": "2.1.0", + "referrer-policy": "1.2.0", + "x-xss-protection": "1.1.0" }, "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "expect-ct": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/expect-ct/-/expect-ct-0.2.0.tgz", + "integrity": "sha512-6SK3MG/Bbhm8MsgyJAylg+ucIOU71/FzyFalcfu5nY19dH8y/z0tBJU0wrNBXD4B27EoQtqPF/9wqH0iYAd04g==" + }, + "feature-policy": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/feature-policy/-/feature-policy-0.3.0.tgz", + "integrity": "sha512-ZtijOTFN7TzCujt1fnNhfWPFPSHeZkesff9AXZj+UEjYBynWNUIYpC87Ve4wHzyexQsImicLu7WsC2LHq7/xrQ==" + }, + "frameguard": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/frameguard/-/frameguard-3.1.0.tgz", + "integrity": "sha512-TxgSKM+7LTA6sidjOiSZK9wxY0ffMPY3Wta//MqwmX0nZuEHc8QrkV8Fh3ZhMJeiH+Uyh/tcaarImRy8u77O7g==" + }, + "nocache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz", + "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==" + }, + "referrer-policy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.2.0.tgz", + "integrity": "sha512-LgQJIuS6nAy1Jd88DCQRemyE3mS+ispwlqMk3b0yjZ257fI1v9c+/p6SD5gP5FGyXUIgrNOAfmyioHwZtYv2VA==" } } }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true + "helmet-crossdomain": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/helmet-crossdomain/-/helmet-crossdomain-0.3.0.tgz", + "integrity": "sha512-YiXhj0E35nC4Na5EPE4mTfoXMf9JTGpN4OtB4aLqShKuH9d2HNaJX5MQoglO6STVka0uMsHyG5lCut5Kzsy7Lg==" }, - "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 + "helmet-csp": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.7.1.tgz", + "integrity": "sha512-sCHwywg4daQ2mY0YYwXSZRsgcCeerUwxMwNixGA7aMLkVmPTYBl7gJoZDHOZyXkqPrtuDT3s2B1A+RLI7WxSdQ==", + "requires": { + "camelize": "1.0.0", + "content-security-policy-builder": "2.0.0", + "dasherize": "2.0.0", + "platform": "1.3.5" + } }, - "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 + "hide-powered-by": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hide-powered-by/-/hide-powered-by-1.0.0.tgz", + "integrity": "sha1-SoWtZYgfYoV/xwr3F0oRhNzM4ys=" }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", "requires": { - "is-extglob": "^2.1.1" + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" } }, - "is-number": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-0.1.1.tgz", - "integrity": "sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY=" - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", "requires": { - "isobject": "^3.0.1" + "parse-passwd": "^1.0.0" } }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "hoopy": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", + "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", "dev": true }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "hosted-git-info": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", + "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", "dev": true }, - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" - }, - "isexe": { + "hpkp": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "resolved": "https://registry.npmjs.org/hpkp/-/hpkp-2.0.0.tgz", + "integrity": "sha1-EOFCJk52IVpdMMROxD3mTe5tFnI=" }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "istanbul": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", - "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", - "dev": true, + "hsts": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/hsts/-/hsts-2.2.0.tgz", + "integrity": "sha512-ToaTnQ2TbJkochoVcdXYm4HOCliNozlviNsg+X2XQLQvZNI/kCHR9rZxVYpJB3UPcHz80PgxRyWQ7PdU1r+VBQ==", "requires": { - "abbrev": "1.0.x", - "async": "1.x", - "escodegen": "1.8.x", - "esprima": "2.7.x", - "glob": "^5.0.15", - "handlebars": "^4.0.1", - "js-yaml": "3.x", - "mkdirp": "0.5.x", - "nopt": "3.x", - "once": "1.x", - "resolve": "1.1.x", - "supports-color": "^3.1.0", - "which": "^1.1.1", - "wordwrap": "^1.0.0" + "depd": "2.0.0" }, "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, - "escodegen": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", - "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", - "dev": true, - "requires": { - "esprima": "^2.7.1", - "estraverse": "^1.9.1", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.2.0" - } - }, - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", - "dev": true - }, - "estraverse": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", - "dev": true - }, - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, - "source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", - "dev": true, - "optional": true, - "requires": { - "amdefine": ">=0.0.4" - } - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" } } }, - "jquery": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.3.1.tgz", - "integrity": "sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg==" + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "requires": { + "whatwg-encoding": "^1.0.1" + } }, - "jquery-ui-bundle": { - "version": "1.12.1-migrate", - "resolved": "https://registry.npmjs.org/jquery-ui-bundle/-/jquery-ui-bundle-1.12.1-migrate.tgz", - "integrity": "sha1-uTQ+LDEHQ1J2Ms/4vtsMXpYAsUw=" + "html-entities": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", + "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", + "dev": true }, - "jquery.tooltips": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/jquery.tooltips/-/jquery.tooltips-1.0.0.tgz", - "integrity": "sha1-/Ko2Il0IXQ/NY71E4rAGtUGDHHI=" + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } }, - "js-storage": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/js-storage/-/js-storage-1.0.4.tgz", - "integrity": "sha512-ND6iVfDo5r2PSpkzXa+s+S6TzZkRD1EaN4NvtwRWp2rrL1pmS9wdcbmv3eYZYOkBcPiQjyQUWZRcT0aQ4Wuk8g==" + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" }, - "js-yaml": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", - "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", - "dev": true, + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "dependencies": { - "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 - } + "safer-buffer": ">= 2.1.2 < 3" } }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + "icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=" }, - "jsdom": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.11.0.tgz", - "integrity": "sha512-ou1VyfjwsSuWkudGxb03FotDajxAto6USAlmMZjE2lc0jCznt7sBWkhfRBRaWwbnmDqdMSTKTLT5d9sBFkkM7A==", + "icss-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-2.1.0.tgz", + "integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=", "requires": { - "abab": "^1.0.4", - "acorn": "^5.3.0", - "acorn-globals": "^4.1.0", - "array-equal": "^1.0.0", - "cssom": ">= 0.3.2 < 0.4.0", - "cssstyle": ">= 0.3.1 < 0.4.0", - "data-urls": "^1.0.0", - "domexception": "^1.0.0", - "escodegen": "^1.9.0", - "html-encoding-sniffer": "^1.0.2", - "left-pad": "^1.2.0", - "nwsapi": "^2.0.0", - "parse5": "4.0.0", - "pn": "^1.1.0", - "request": "^2.83.0", - "request-promise-native": "^1.0.5", - "sax": "^1.2.4", - "symbol-tree": "^3.2.2", - "tough-cookie": "^2.3.3", - "w3c-hr-time": "^1.0.1", - "webidl-conversions": "^4.0.2", - "whatwg-encoding": "^1.0.3", - "whatwg-mimetype": "^2.1.0", - "whatwg-url": "^6.4.1", - "ws": "^4.0.0", - "xml-name-validator": "^3.0.0" + "postcss": "^6.0.1" } }, - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + "ienoopen": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ienoopen/-/ienoopen-1.1.0.tgz", + "integrity": "sha512-MFs36e/ca6ohEKtinTJ5VvAJ6oDRAYFdYXweUnGY9L9vcoqFOU4n2ZhmJ0C4z/cwGZ3YIQRSB3XZ1+ghZkY5NQ==" }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + "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 }, - "json5": { + "ignore-by-default": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "requires": { - "minimist": "^1.2.0" - } + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", + "dev": true }, - "jsonwebtoken": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.4.0.tgz", - "integrity": "sha512-coyXjRTCy0pw5WYBpMvWOMN+Kjaik2MwTUIq9cna/W7NpO9E+iYbumZONAz3hcr+tXFJECoQVrtmIoC3Oz0gvg==", + "import-fresh": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", + "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", + "dev": true, "requires": { - "jws": "^3.1.5", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.1.1" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" }, "dependencies": { - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + "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 } } }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true }, - "jwa": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.2.0.tgz", - "integrity": "sha512-Grku9ZST5NNQ3hqNUodSkDfEBqAmGA1R8yiyPHOnLzEKI0GaCQC/XhFmsheXYuXzFQJdILbh+lYBiliqG5R/Vg==", + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.10", - "safe-buffer": "^5.0.1" + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" } }, - "jws": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.1.tgz", - "integrity": "sha512-bGA2omSrFUkd72dhh05bIAN832znP4wOU3lfuXtRBuGTbsmNmDXMQg28f0Vsxaxgk4myF5YkKQpz6qeRpMgX9g==", + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "requires": { - "jwa": "^1.2.0", - "safe-buffer": "^5.0.1" + "once": "^1.3.0", + "wrappy": "1" } }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "dev": true, - "requires": { - "invert-kv": "^2.0.0" + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, + "inquirer": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.0.tgz", + "integrity": "sha512-scfHejeG/lVZSpvCXpsB4j/wQNPM5JC8kiElOI0OUTwmc1RTpXr4H32/HOlQHcZiYl2z2VElwuCVDRG8vFmbnA==", + "dev": true, + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.12", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "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" + } + }, + "lodash": { + "version": "4.17.14", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.14.tgz", + "integrity": "sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw==", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + } + } + }, + "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" + } + } } }, - "left-pad": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz", - "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==" + "interpret": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==" }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==" + }, + "ipaddr.js": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", + "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } } }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, - "loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^2.0.0", - "json5": "^1.0.1" - } + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "is-ci": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", + "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", "dev": true, "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "ci-info": "^1.5.0" } }, - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.includes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } }, - "lodash.isboolean": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } }, - "lodash.isinteger": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" }, - "lodash.isnumber": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + "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=" }, - "lodash.isstring": { + "is-glob": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" - }, - "lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" - }, - "lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "requires": { - "yallist": "^3.0.2" + "is-extglob": "^2.1.1" } }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", "dev": true, "requires": { - "pify": "^3.0.0" + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" } }, - "map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "is-npm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", + "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", "dev": true, "requires": { - "p-defer": "^1.0.0" + "path-is-inside": "^1.0.1" } }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, - "map-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", - "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=" + "is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", + "dev": true }, - "map-visit": { + "is-retry-allowed": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", + "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-typedarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "istanbul": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", + "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", "dev": true, "requires": { - "object-visit": "^1.0.0" + "abbrev": "1.0.x", + "async": "1.x", + "escodegen": "1.8.x", + "esprima": "2.7.x", + "glob": "^5.0.15", + "handlebars": "^4.0.1", + "js-yaml": "3.x", + "mkdirp": "0.5.x", + "nopt": "3.x", + "once": "1.x", + "resolve": "1.1.x", + "supports-color": "^3.1.0", + "which": "^1.1.1", + "wordwrap": "^1.0.0" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", + "dev": true, + "requires": { + "esprima": "^2.7.1", + "estraverse": "^1.9.1", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.2.0" + } + }, + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "dev": true + }, + "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" + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + }, + "source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", + "dev": true, + "optional": true, + "requires": { + "amdefine": ">=0.0.4" + } + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "^1.0.0" + } + } } }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-LXTBICkMARVgo579kWDm8SqfB6nvSDKNqIOBEjmJRnL04JvoMHCYGWaMddQnseJYtkEuEvO/sIcOxPLk9gERug==", + "dev": true + }, + "istanbul-lib-hook": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.6.tgz", + "integrity": "sha512-829DKONApZ7UCiPXcOYWSgkFXa4+vNYoNOt3F+4uDJLKL1OotAoVwvThoEj1i8jmOj7odbYcR3rnaHu+QroaXg==", "dev": true, "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" + "append-transform": "^1.0.0" } }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, - "mem": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.1.0.tgz", - "integrity": "sha512-I5u6Q1x7wxO0kdOpYBB28xueHADYps5uty/zg936CiG8NTe5sJL8EjrCuLneuDW3PlMdZBGDIn8BirEVdovZvg==", + "istanbul-lib-instrument": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.2.0.tgz", + "integrity": "sha512-06IM3xShbNW4NgZv5AP4QH0oHqf1/ivFo8eFys0ZjPXHGldHJQWb3riYOKXqmOqfxXBfxu4B+g/iuhOPZH0RJg==", "dev": true, "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^1.0.0", - "p-is-promise": "^2.0.0" + "@babel/generator": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "istanbul-lib-coverage": "^2.0.4", + "semver": "^6.0.0" } }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "istanbul-lib-report": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.7.tgz", + "integrity": "sha512-wLH6beJBFbRBLiTlMOBxmb85cnVM1Vyl36N48e4e/aTKSM3WbOx7zbVIH1SQ537fhhsPbX0/C5JB4qsmyRXXyA==", "dev": true, "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" + "istanbul-lib-coverage": "^2.0.4", + "make-dir": "^2.1.0", + "supports-color": "^6.0.0" + }, + "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, - "memory-pager": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", - "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", - "optional": true - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "istanbul-lib-source-maps": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.5.tgz", + "integrity": "sha512-eDhZ7r6r1d1zQPVZehLc3D0K14vRba/eBYkz3rw16DLOrrTzve9RmnkcwrrkWVgO1FL3EK5knujVe5S8QHE9xw==", "dev": true, "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.4", + "make-dir": "^2.1.0", + "rimraf": "^2.6.2", + "source-map": "^0.6.1" }, "dependencies": { - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "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" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } + } + }, + "istanbul-reports": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.3.tgz", + "integrity": "sha512-T6EbPuc8Cb620LWAYyZ4D8SSn06dY9i1+IgUX2lTH8gbwflMc9Obd33zHTyNX653ybjpamAHS9toKS3E6cGhTw==", + "dev": true, + "requires": { + "handlebars": "^4.1.0" + } + }, + "jquery": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.0.tgz", + "integrity": "sha512-ggRCXln9zEqv6OqAGXFEcshF5dSBvCkzj6Gm2gzuR5fWawaX8t7cxKVkkygKODrDAzKdoYw3l/e3pm3vlT4IbQ==" + }, + "jquery-ui-bundle": { + "version": "1.12.1-migrate", + "resolved": "https://registry.npmjs.org/jquery-ui-bundle/-/jquery-ui-bundle-1.12.1-migrate.tgz", + "integrity": "sha1-uTQ+LDEHQ1J2Ms/4vtsMXpYAsUw=" + }, + "jquery.tooltips": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jquery.tooltips/-/jquery.tooltips-1.0.0.tgz", + "integrity": "sha1-/Ko2Il0IXQ/NY71E4rAGtUGDHHI=" + }, + "js-storage": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/js-storage/-/js-storage-1.0.4.tgz", + "integrity": "sha512-ND6iVfDo5r2PSpkzXa+s+S6TzZkRD1EaN4NvtwRWp2rrL1pmS9wdcbmv3eYZYOkBcPiQjyQUWZRcT0aQ4Wuk8g==" + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "js-yaml": { + "version": "3.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" + }, + "dependencies": { + "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 + } + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "jsdom": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.11.0.tgz", + "integrity": "sha512-ou1VyfjwsSuWkudGxb03FotDajxAto6USAlmMZjE2lc0jCznt7sBWkhfRBRaWwbnmDqdMSTKTLT5d9sBFkkM7A==", + "requires": { + "abab": "^1.0.4", + "acorn": "^5.3.0", + "acorn-globals": "^4.1.0", + "array-equal": "^1.0.0", + "cssom": ">= 0.3.2 < 0.4.0", + "cssstyle": ">= 0.3.1 < 0.4.0", + "data-urls": "^1.0.0", + "domexception": "^1.0.0", + "escodegen": "^1.9.0", + "html-encoding-sniffer": "^1.0.2", + "left-pad": "^1.2.0", + "nwsapi": "^2.0.0", + "parse5": "4.0.0", + "pn": "^1.1.0", + "request": "^2.83.0", + "request-promise-native": "^1.0.5", + "sax": "^1.2.4", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.3.3", + "w3c-hr-time": "^1.0.1", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.3", + "whatwg-mimetype": "^2.1.0", + "whatwg-url": "^6.4.1", + "ws": "^4.0.0", + "xml-name-validator": "^3.0.0" + } + }, + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "requires": { + "minimist": "^1.2.0" + } + }, + "jsonwebtoken": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "requires": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + } + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + }, + "latest-version": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", + "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "dev": true, + "requires": { + "package-json": "^4.0.0" + } + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "requires": { + "invert-kv": "^2.0.0" + } + }, + "left-pad": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz", + "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==" + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "loader-fs-cache": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.2.tgz", + "integrity": "sha512-70IzT/0/L+M20jUlEqZhZyArTU6VKLRTYRDAYN26g4jfzpJqjipLL3/hgYpySqI9PwsVRHHFja0LfEmsx9X2Cw==", + "dev": true, + "requires": { + "find-cache-dir": "^0.1.1", + "mkdirp": "0.5.1" + }, + "dependencies": { + "find-cache-dir": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz", + "integrity": "sha1-yN765XyKUqinhPnjHFfHQumToLk=", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "mkdirp": "^0.5.1", + "pkg-dir": "^1.0.0" + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "pkg-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", + "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "dev": true, + "requires": { + "find-up": "^1.0.0" + } + } + } + }, + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==" + }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=" + }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "dev": true + }, + "lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" + }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" + }, + "lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" + }, + "lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "mamacro": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz", + "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==" + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "requires": { + "p-defer": "^1.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" + }, + "map-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=" + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "requires": { + "object-visit": "^1.0.0" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "memory-cache": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/memory-cache/-/memory-cache-0.2.0.tgz", + "integrity": "sha1-eJCwHVLADI68nVM+H46xfjA0hxo=" + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "optional": true + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "merge-source-map": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", + "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", + "dev": true, + "requires": { + "source-map": "^0.6.1" + } + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "dependencies": { + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.2.tgz", + "integrity": "sha512-zJBfZDkwRu+j3Pdd2aHsR5GfH2jIWhmL1ZzBoc+X+3JEti2hbArWcyJ+1laC1D2/U/W1a/+Cegj0/OnEU2ybjg==" + }, + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "requires": { + "mime-db": "1.40.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimed-connect-to-nightscout": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/minimed-connect-to-nightscout/-/minimed-connect-to-nightscout-1.2.2.tgz", + "integrity": "sha512-HSZTxoBIdQ4xtllmE7A/rk3WtkHzf+67ex7c4PF7JmLX6vJMcr/2blEGWnnexO/hxL82DQ9UczY6xr6YZw55Mg==", + "requires": { + "common": "^0.2.5", + "lodash": "^4.17.11", + "request": "^2.88.0" + }, + "dependencies": { + "ajv": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", + "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==" + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "camelcase": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.2.0.tgz", + "integrity": "sha512-IXFsBS2pC+X0j0N/GE7Dm7j3bsEBp+oTpb7F50dwEVX7rf3IgwO9XatnegTsDtniKCUtEJH4fSU6Asw7uoVLfQ==" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "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==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "common": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/common/-/common-0.2.5.tgz", + "integrity": "sha1-PHGC9ni9HjaBzVzDSMdZ/o3SI5Q=" + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=" + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "requires": { + "once": "^1.4.0" + } + }, + "es-abstract": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", + "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-keys": "^1.0.12" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "expect.js": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/expect.js/-/expect.js-0.3.1.tgz", + "integrity": "sha1-sKWaDS7/VDdUTr8M6qYBWEHQm1s=" + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "findup-sync": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", + "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^3.1.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "flat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", + "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "requires": { + "is-buffer": "~2.0.3" + }, + "dependencies": { + "is-buffer": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", + "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==" + } + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "requires": { + "map-cache": "^0.2.2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "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.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==" + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "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=" + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "^2.1.0" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "requires": { + "has": "^1.0.1" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "requires": { + "has-symbols": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "js-yaml": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", + "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", "requires": { - "arr-flatten": "^1.1.0", + "invert-kv": "^2.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "requires": { + "chalk": "^2.0.1" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "requires": { + "p-defer": "^1.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "requires": { + "object-visit": "^1.0.0" + } + }, + "mem": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.2.0.tgz", + "integrity": "sha512-5fJxa68urlY0Ir8ijatKa3eRz5lwXnRCTvo9+TbTGAuTFJOwpGcY0X05moBd0nW45965Njt4CDI2GFQoG8DvqA==", + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" + "to-regex": "^3.0.2" + } + }, + "mime-db": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", + "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==" + }, + "mime-types": { + "version": "2.1.22", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz", + "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==", + "requires": { + "mime-db": "~1.38.0" + } + }, + "mimic-fn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.0.0.tgz", + "integrity": "sha512-jbex9Yd/3lmICXwYT6gA/j2mNQGU48wCh/VzRd+/Y/PjYQtlg1gLMdZqvu9s/xH7qKvngxRObl56XZR609IMbA==" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" }, "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "requires": { - "is-extendable": "^0.1.0" + "is-plain-object": "^2.0.4" } } } - } - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, - "mime": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", - "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==" - }, - "mime-db": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", - "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==" - }, - "mime-types": { - "version": "2.1.21", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", - "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", - "requires": { - "mime-db": "~1.37.0" - } - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "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" - } - }, - "minimed-connect-to-nightscout": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/minimed-connect-to-nightscout/-/minimed-connect-to-nightscout-1.1.1.tgz", - "integrity": "sha512-Cts3oJPtLdRCOeBRu5tqoIRoZjAsYuNN4LhAdtZG8P42MJxFZdsRDc13BdDNEq7GCxhVcNtvan3XwTnobm0xFg==", - "requires": { - "common": "0.2.x", - "lodash": "^4.17.10", - "request": "^2.87.0" - }, - "dependencies": { - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" + "minimist": "0.0.8" } }, - "asn1": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "mocha": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.0.2.tgz", + "integrity": "sha512-RtTJsmmToGyeTznSOMoM6TPEk1A84FQaHIciKrRqARZx+B5ccJ5tXlmJzEKGBxZdqk9UjpRsesZTUkZmR5YnuQ==", + "requires": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "findup-sync": "2.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.12.0", + "log-symbols": "2.2.0", + "minimatch": "3.0.4", + "ms": "2.1.1", + "node-environment-flags": "1.0.4", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "12.0.5", + "yargs-parser": "11.1.1", + "yargs-unparser": "1.5.0" + }, + "dependencies": { + "jade": { + "version": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz", + "integrity": "sha1-jxDXl32NefL2/4YqgbBRPMslaGw=", + "requires": { + "commander": "0.6.1", + "mkdirp": "0.3.0" + }, + "dependencies": { + "commander": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz", + "integrity": "sha1-+mihT2qUXVTbvlDYzbMyDp47GgY=" + }, + "mkdirp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", + "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=" + } + } + }, + "mkdirp": { + "version": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", + "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=", + "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=" + } + } + } + } }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" }, - "aws4": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", - "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==" + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "optional": true, + "node-environment-flags": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.4.tgz", + "integrity": "sha512-M9rwCnWVLW7PX+NUWe3ejEdiLYinRpsEre9hMkU/6NS4h+EEulYaDH1gCEZ2gyXsmw+RXYDaV2JkkTNcsPDJ0Q==", "requires": { - "tweetnacl": "^0.14.3" + "object.getownpropertydescriptors": "^2.0.3" } }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "path-key": "^2.0.0" } }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" }, - "combined-stream": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", - "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "requires": { - "delayed-stream": "~1.0.0" + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } } }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" + "object-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.0.tgz", + "integrity": "sha512-6OO5X1+2tYkNyNEx6TsCxEqFfRWaqx6EtMiSbGrw8Ob8v9Ne+Hl8rBAgLBZn5wjEz3s/s6U1WXFUFOcxxAwUpg==" }, - "common": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/common/-/common-0.2.5.tgz", - "integrity": "sha1-PHGC9ni9HjaBzVzDSMdZ/o3SI5Q=" + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "requires": { + "isobject": "^3.0.0" + } }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "object.getownpropertydescriptors": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", + "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" + } }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "requires": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { - "assert-plus": "^1.0.0" + "wrappy": "1" } }, - "debug": { + "os-locale": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", "requires": { - "ms": "2.0.0" + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" } }, - "delayed-stream": { + "p-defer": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=" }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" }, - "ecc-jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", - "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", - "optional": true, + "p-is-promise": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.0.0.tgz", + "integrity": "sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg==" + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", "requires": { - "jsbn": "~0.1.0" + "p-try": "^2.0.0" } }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } }, - "expect.js": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/expect.js/-/expect.js-0.3.1.tgz", - "integrity": "sha1-sKWaDS7/VDdUTr8M6qYBWEHQm1s=" + "p-try": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.1.0.tgz", + "integrity": "sha512-H2RyIJ7+A3rjkwKC2l5GGtU4H1vkxKCAGsWasNVd0Set+6i4znxbWy6/j16YDPJDWxhsgZiKAstMEP8wCdSpjA==" }, - "extend": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + "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=" }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" }, - "form-data": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", - "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "1.0.6", - "mime-types": "^2.1.12" - } + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } + "psl": { + "version": "1.1.31", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", + "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==" }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "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" + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, - "har-validator": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", - "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "requires": { - "ajv": "^5.1.0", - "har-schema": "^2.0.0" + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=" + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "node-uuid": { + "version": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz", + "integrity": "sha1-baWhdmjEs91ZYjvaEc9/pMH2Cm8=" + } } }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", "requires": { - "once": "^1.3.0", - "wrappy": "1" + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" } }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "optional": true + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "requires": { + "ret": "~0.1.10" + } }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } } }, - "lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" - }, - "mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==" - }, - "mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "requires": { - "mime-db": "~1.33.0" + "shebang-regex": "^1.0.0" } }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "requires": { - "brace-expansion": "^1.1.7" + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } } }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "requires": { - "minimist": "0.0.8" + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } } }, - "mocha": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", - "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "requires": { - "browser-stdout": "1.3.1", - "commander": "2.15.1", - "debug": "3.1.0", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.5", - "he": "1.1.1", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "supports-color": "5.4.0" + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", "requires": { - "wrappy": "1" + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" } }, - "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=" - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" }, - "request": { - "version": "2.87.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", - "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.6.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.1", - "forever-agent": "~0.6.1", - "form-data": "~2.3.1", - "har-validator": "~5.0.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.17", - "oauth-sign": "~0.8.2", - "performance-now": "^2.1.0", - "qs": "~6.5.1", - "safe-buffer": "^5.1.1", - "tough-cookie": "~2.3.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.1.0" + "extend-shallow": "^3.0.0" } }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, "sshpk": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", - "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -3982,20 +7160,112 @@ "tweetnacl": "~0.14.0" } }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", "requires": { "has-flag": "^3.0.0" } }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, "tough-cookie": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", - "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", "requires": { + "psl": "^1.1.24", "punycode": "^1.4.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + } } }, "tunnel-agent": { @@ -4009,8 +7279,93 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "optional": true + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" + } + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" }, "uuid": { "version": "3.3.2", @@ -4027,10 +7382,116 @@ "extsprintf": "^1.2.0" } }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + }, + "yargs": { + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yargs-unparser": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.5.0.tgz", + "integrity": "sha512-HK25qidFTCVuj/D1VfNiEndpLIeJN78aqgR23nL3y4N0U/91cOAzqfHlF8n2BvoNDcZmJKin3ddNSvOxSr8flw==", + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.11", + "yargs": "^12.0.5" + } } } }, @@ -4043,7 +7504,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, "requires": { "concat-stream": "^1.5.0", "duplexify": "^3.4.2", @@ -4058,10 +7518,9 @@ } }, "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", - "dev": true, + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "requires": { "for-in": "^1.0.2", "is-extendable": "^1.0.1" @@ -4071,7 +7530,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, "requires": { "is-plain-object": "^2.0.4" } @@ -4082,7 +7540,6 @@ "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" }, @@ -4090,8 +7547,7 @@ "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" } } }, @@ -4129,20 +7585,6 @@ "ms": "2.0.0" } }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, "supports-color": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", @@ -4163,34 +7605,100 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/moment-locales-webpack-plugin/-/moment-locales-webpack-plugin-1.0.7.tgz", "integrity": "sha512-KjYpaAhmuzGFZl6534FlZoK7QtW3vqlxd+A17W9DlgHJ5yhXANy7AZJl7iYtZpWjAfMTAWiVrQ7YDZdkFO6uRw==", - "dev": true, "requires": { "lodash.difference": "^4.5.0" } }, "moment-timezone": { - "version": "0.5.23", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.23.tgz", - "integrity": "sha512-WHFH85DkCfiNMDX5D3X7hpNH3/PUhjTGcD0U1SgfBGZxJ3qUmJh5FdvaFjcClxOvB3rzdfj4oRffbI38jEnC1w==", + "version": "0.5.25", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.25.tgz", + "integrity": "sha512-DgEaTyN/z0HFaVcVbSyVCUU6HeFdnNC3vE4c9cgu2dgMTvjBUBdBzWfasTBmAW45u5OIMeCJtU8yNjM22DHucw==", "requires": { "moment": ">= 2.9.0" } }, + "moment-timezone-data-webpack-plugin": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/moment-timezone-data-webpack-plugin/-/moment-timezone-data-webpack-plugin-1.1.0.tgz", + "integrity": "sha512-szKf9rbRoY9u3WNcwK6D0tdCREk/OZkcF1k163Xc5m7GcqBh28LgNVWisb4sje6/qdG3WUkFD5hJ7/lmKOkBAA==", + "requires": { + "find-cache-dir": "^3.0.0", + "make-dir": "^3.0.0" + }, + "dependencies": { + "find-cache-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.0.0.tgz", + "integrity": "sha512-t7ulV1fmbxh5G9l/492O1p5+EBbr3uwpt6odhFTMc+nWyhmbloe+ja9BZ8pIBtqFWhOmCWVjx+pTW4zDkFoclw==", + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.0", + "pkg-dir": "^4.1.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==", + "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==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "make-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.0.tgz", + "integrity": "sha512-grNJDhb8b1Jm1qeqW5R/O63wUo4UXo2v2HMic6YT9i/HBlF93S8jkMgH7yugvY9ABDShH4VZMn8I+U8+fCNegw==", + "requires": { + "semver": "^6.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==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "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==" + }, + "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==", + "requires": { + "find-up": "^4.0.0" + } + } + } + }, "mongodb": { - "version": "3.1.13", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.1.13.tgz", - "integrity": "sha512-sz2dhvBZQWf3LRNDhbd30KHVzdjZx9IKC0L+kSZ/gzYquCF5zPOgGqRz6sSCqYZtKP2ekB4nfLxhGtzGHnIKxA==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.2.3.tgz", + "integrity": "sha512-jw8UyPsq4QleZ9z+t/pIVy3L++51vKdaJ2Q/XXeYxk/3cnKioAH8H6f5tkkDivrQL4PUgUOHe9uZzkpRFH1XtQ==", "requires": { - "mongodb-core": "3.1.11", + "mongodb-core": "^3.2.3", "safe-buffer": "^5.1.2" } }, "mongodb-core": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.1.11.tgz", - "integrity": "sha512-rD2US2s5qk/ckbiiGFHeu+yKYDXdJ1G87F6CG3YdaZpzdOm5zpoAZd/EKbPmFO6cQZ+XVXBXBJ660sSI0gc6qg==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.2.3.tgz", + "integrity": "sha512-UyI0rmvPPkjOJV8XGWa9VCTq7R4hBVipimhnAXeSXnuAPjuTqbyfA5Ec9RcYJ1Hhu+ISnc8bJ1KfGZd4ZkYARQ==", "requires": { - "bson": "^1.1.0", + "bson": "^1.1.1", "require_optional": "^1.0.1", "safe-buffer": "^5.1.2", "saslprep": "^1.0.0" @@ -4208,7 +7716,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, "requires": { "aproba": "^1.1.1", "copy-concurrently": "^1.0.0", @@ -4223,11 +7730,21 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" + }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -4240,37 +7757,34 @@ "regex-not": "^1.0.0", "snapdragon": "^0.8.1", "to-regex": "^3.0.1" - }, - "dependencies": { - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - } } }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, "negotiator": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" }, "neo-async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.0.tgz", - "integrity": "sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==" + }, + "nested-error-stacks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", + "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", "dev": true }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "nocache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.0.0.tgz", - "integrity": "sha1-ICtIAhoMTL3i34DeFaF0Q8i0OYA=" + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, "node-cache": { "version": "4.2.0", @@ -4282,10 +7796,9 @@ } }, "node-libs-browser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.0.tgz", - "integrity": "sha512-5MQunG/oyOaBdttrL40dA7bUfPORLRWMUJLQtMg7nluxUvk5XwnLdL9twQHFAjRx/y7mIMkLKT9++qPbbk6BZA==", - "dev": true, + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", "requires": { "assert": "^1.1.1", "browserify-zlib": "^0.2.0", @@ -4297,7 +7810,7 @@ "events": "^3.0.0", "https-browserify": "^1.0.0", "os-browserify": "^0.3.0", - "path-browserify": "0.0.0", + "path-browserify": "0.0.1", "process": "^0.11.10", "punycode": "^1.2.4", "querystring-es3": "^0.2.0", @@ -4309,14 +7822,766 @@ "tty-browserify": "0.0.0", "url": "^0.11.0", "util": "^0.11.0", - "vm-browserify": "0.0.4" + "vm-browserify": "^1.0.1" }, "dependencies": { "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + } + } + }, + "nodemon": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.0.tgz", + "integrity": "sha512-NHKpb/Je0Urmwi3QPDHlYuFY9m1vaVfTsRZG5X73rY46xPj0JpNe8WhUGQdkDXQDOxrBNIU3JrcflE9Y44EcuA==", + "dev": true, + "requires": { + "chokidar": "^2.1.5", + "debug": "^3.1.0", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.6", + "semver": "^5.5.0", + "supports-color": "^5.2.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.2", + "update-notifier": "^2.5.0" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + } + }, + "chokidar": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz", + "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + } + }, + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "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" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } } } }, @@ -4329,17 +8594,35 @@ "abbrev": "1" } }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } + } + }, "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 + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, "requires": { "path-key": "^2.0.0" } @@ -4351,15 +8634,90 @@ "dev": true }, "nwsapi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.0.tgz", - "integrity": "sha512-ZG3bLAvdHmhIjaQ/Db1qvBxsGvFMLIRpQszyqbg31VJ53UP++uZX1/gf3Ut96pdwN9AuDwlMqIYLm0UPCdUeHg==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.3.tgz", + "integrity": "sha512-RowAaJGEgYXEZfQ7tvvdtAQUKPyTR6T6wNu0fwlNsGQYr/h3yQc6oI8WnVZh3Y/Sylwc+dtAlvPqfFZjhTyk3A==" + }, + "nyc": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.0.0.tgz", + "integrity": "sha512-R1zC6UZak6pzn5BZQorkSH5GdOGafrwyeja+eimS5Tu+KJ/hCgBc8qA1QWSzxQmT2FDl2lbpqPw7tBDbSvhAHg==", + "dev": true, + "requires": { + "archy": "^1.0.0", + "caching-transform": "^3.0.2", + "convert-source-map": "^1.6.0", + "cp-file": "^6.2.0", + "find-cache-dir": "^2.1.0", + "find-up": "^3.0.0", + "foreground-child": "^1.5.6", + "glob": "^7.1.3", + "istanbul-lib-coverage": "^2.0.4", + "istanbul-lib-hook": "^2.0.6", + "istanbul-lib-instrument": "^3.2.0", + "istanbul-lib-report": "^2.0.7", + "istanbul-lib-source-maps": "^3.0.5", + "istanbul-reports": "^2.2.2", + "make-dir": "^2.1.0", + "merge-source-map": "^1.1.0", + "resolve-from": "^4.0.0", + "rimraf": "^2.6.3", + "signal-exit": "^3.0.2", + "spawn-wrap": "^1.4.2", + "test-exclude": "^5.2.2", + "uuid": "^3.3.2", + "yargs": "^13.2.2", + "yargs-parser": "^13.0.0" + }, + "dependencies": { + "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" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "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 + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } + } }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, "object-component": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", @@ -4369,7 +8727,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, "requires": { "copy-descriptor": "^0.1.0", "define-property": "^0.2.5", @@ -4380,7 +8737,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -4389,18 +8745,22 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } } } }, + "object-hash": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz", + "integrity": "sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==", + "dev": true + }, "object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, "requires": { "isobject": "^3.0.0" } @@ -4409,7 +8769,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, "requires": { "isobject": "^3.0.1" } @@ -4423,19 +8782,35 @@ } }, "on-headers": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", - "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1" } }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + }, + "dependencies": { + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + } + } + }, "opener": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.1.tgz", @@ -4482,43 +8857,49 @@ "os-browserify": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=" + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, "os-locale": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "dev": true, "requires": { "execa": "^1.0.0", "lcid": "^2.0.0", "mem": "^4.0.0" } }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, "p-defer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", - "dev": true + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=" }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" }, "p-is-promise": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.0.0.tgz", - "integrity": "sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg==", - "dev": true + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==" }, "p-limit": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", - "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", - "dev": true, + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", "requires": { "p-try": "^2.0.0" } @@ -4527,39 +8908,75 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, "requires": { "p-limit": "^2.0.0" } }, "p-try": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", - "dev": true + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "package-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", + "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^3.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, + "package-json": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", + "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "dev": true, + "requires": { + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } + } }, "pako": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.8.tgz", - "integrity": "sha512-6i0HVbUfcKaTv+EG8ZTr75az7GFXcLYk9UyLEg7Notv/Ma+z/UG3TCoz6GiNeOrn1E/e63I0X/Hpw18jHOTUnA==", - "dev": true + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", + "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==" }, "parallel-transform": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz", "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=", - "dev": true, "requires": { "cyclist": "~0.2.2", "inherits": "^2.0.3", "readable-stream": "^2.1.5" } }, - "parse-asn1": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.3.tgz", - "integrity": "sha512-VrPoetlz7B/FqjBLD2f5wBVZvsZVLnRUrxVLfRYhGXCODa/NWE4p3Wp+6+aV3ZPL3KM7/OZmxDIwwijD7yuucg==", + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-asn1": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz", + "integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==", "requires": { "asn1.js": "^4.0.0", "browserify-aes": "^1.0.0", @@ -4574,11 +8991,20 @@ "resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-0.1.1.tgz", "integrity": "sha1-ExFN3JiRwezSgANiRFVN5DZHoiY=" }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, "parse-passwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "dev": true + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" }, "parse5": { "version": "4.0.0", @@ -4602,44 +9028,50 @@ } }, "parseurl": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", - "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" }, "path-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", - "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", - "dev": true + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==" }, "path-dirname": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", "dev": true }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, "path-to-regexp": { @@ -4647,6 +9079,23 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, "pause-stream": { "version": "0.0.11", "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", @@ -4659,7 +9108,6 @@ "version": "3.0.17", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, "requires": { "create-hash": "^1.1.2", "create-hmac": "^1.1.4", @@ -4674,16 +9122,29 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", "dev": true }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, "pkg-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, "requires": { "find-up": "^3.0.0" } @@ -4701,8 +9162,7 @@ "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" }, "postcss": { "version": "6.0.23", @@ -4787,46 +9247,51 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" }, - "prettyjson": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prettyjson/-/prettyjson-1.2.1.tgz", - "integrity": "sha1-/P+rQdGcq0365eV15kJGYZsS0ok=", - "requires": { - "colors": "^1.1.2", - "minimist": "^1.2.0" - } + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" }, "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, "promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" }, "proxy-addr": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", - "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", + "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", "requires": { "forwarded": "~0.1.2", - "ipaddr.js": "1.8.0" + "ipaddr.js": "1.9.0" } }, "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, "psl": { @@ -4834,11 +9299,16 @@ "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==" }, + "pstree.remy": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.6.tgz", + "integrity": "sha512-NdF35+QsqD7EgNEI5mkI/X+UwaxVEbQaz9f4IooEmMUv6ZPmlTQYGjBPJGgrlzNdjSvIy4MWMg6Q6vCgBO2K+w==", + "dev": true + }, "public-encrypt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, "requires": { "bn.js": "^4.1.0", "browserify-rsa": "^4.0.0", @@ -4852,7 +9322,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -4862,7 +9331,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, "requires": { "duplexify": "^3.6.0", "inherits": "^2.0.3", @@ -4873,7 +9341,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -4899,14 +9366,12 @@ "querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" }, "querystring-es3": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=" }, "random-token": { "version": "0.0.8", @@ -4914,10 +9379,9 @@ "integrity": "sha1-HPhFrz+zHlf3yqS5oXNHjEZIO2E=" }, "randombytes": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", - "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", - "dev": true, + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "requires": { "safe-buffer": "^5.1.0" } @@ -4926,7 +9390,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, "requires": { "randombytes": "^2.0.5", "safe-buffer": "^5.1.0" @@ -4948,11 +9411,43 @@ "unpipe": "1.0.0" } }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", + "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", + "dev": true, + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + } + }, "readable-stream": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -4964,29 +9459,12 @@ }, "dependencies": { "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - } - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + } } }, - "referrer-policy": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.1.0.tgz", - "integrity": "sha1-NXdOtzW/UPtsB46DM0tHI1AgfXk=" - }, "regenerate": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", @@ -4996,12 +9474,17 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, "requires": { "extend-shallow": "^3.0.2", "safe-regex": "^1.1.0" } }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, "regexpu-core": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", @@ -5012,6 +9495,25 @@ "regjsparser": "^0.1.4" } }, + "registry-auth-token": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", + "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", + "dev": true, + "requires": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "dev": true, + "requires": { + "rc": "^1.0.1" + } + }, "regjsgen": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", @@ -5025,22 +9527,29 @@ "jsesc": "~0.5.0" } }, + "release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" }, "repeat-element": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" }, "repeat-string": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-0.2.2.tgz", - "integrity": "sha1-x6jTI2BoNiBZp+RlH8aITosftK4=" + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" }, "request": { "version": "2.88.0", @@ -5086,34 +9595,32 @@ } }, "request-promise-core": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz", - "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz", + "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==", "requires": { - "lodash": "^4.13.1" + "lodash": "^4.17.11" } }, "request-promise-native": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz", - "integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz", + "integrity": "sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==", "requires": { - "request-promise-core": "1.1.1", - "stealthy-require": "^1.1.0", - "tough-cookie": ">=2.3.3" + "request-promise-core": "1.1.2", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" } }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" }, "require_optional": { "version": "1.0.1", @@ -5122,19 +9629,28 @@ "requires": { "resolve-from": "^2.0.0", "semver": "^5.1.0" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + } } }, "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } }, "resolve-cwd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", - "dev": true, "requires": { "resolve-from": "^3.0.0" }, @@ -5142,8 +9658,7 @@ "resolve-from": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=" } } }, @@ -5151,10 +9666,21 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", - "dev": true, "requires": { "expand-tilde": "^2.0.0", "global-modules": "^1.0.0" + }, + "dependencies": { + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + } } }, "resolve-from": { @@ -5165,14 +9691,22 @@ "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } }, "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" }, "rewire": { "version": "2.5.2", @@ -5184,7 +9718,6 @@ "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" }, @@ -5193,7 +9726,6 @@ "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", @@ -5209,21 +9741,37 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, "requires": { "hash-base": "^3.0.0", "inherits": "^2.0.1" } }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, "run-queue": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, "requires": { "aproba": "^1.1.1" } }, + "rxjs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", + "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -5233,7 +9781,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, "requires": { "ret": "~0.1.10" } @@ -5261,7 +9808,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, "requires": { "ajv": "^6.1.0", "ajv-errors": "^1.0.0", @@ -5269,9 +9815,26 @@ } }, "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.0.0.tgz", + "integrity": "sha512-0UewU+9rFapKFnlbirLi3byoOuhrSsli/z/ihNnvM24vgF+8sNBiI1LZPBSH9wJKUwaUbw+s3hToDLCXkrghrQ==" + }, + "semver-diff": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", + "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "dev": true, + "requires": { + "semver": "^5.0.3" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } + } }, "send": { "version": "0.16.2", @@ -5306,10 +9869,9 @@ } }, "serialize-javascript": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.6.1.tgz", - "integrity": "sha512-A5MOagrPFga4YaKQSWHryl7AXvbQkEqpw4NNYMTNYUNV51bA8ABHgYFpqKx+YFFrw59xMV1qGH1R4AgoNIVgCw==", - "dev": true + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.7.0.tgz", + "integrity": "sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA==" }, "serve-static": { "version": "1.13.2", @@ -5325,14 +9887,12 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", - "dev": true, + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "requires": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", @@ -5344,7 +9904,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -5354,8 +9913,7 @@ "setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" }, "setprototypeof": { "version": "1.1.0", @@ -5366,16 +9924,15 @@ "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, "requires": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" } }, "share2nightscout-bridge": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/share2nightscout-bridge/-/share2nightscout-bridge-0.2.0.tgz", - "integrity": "sha512-GdM8iXueC1n0YSiopCeadiq2G7pBYMroNhpqekjtX+cBFG1bqJRxvM9OH7vp27icWKx8AF+ZHdjUfwU5xn9kQQ==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/share2nightscout-bridge/-/share2nightscout-bridge-0.2.1.tgz", + "integrity": "sha512-tzMlJHYNysMsPgCwbG0y+hHA6XtYtpZ13YCoXQ6aQqxsn8fln/JUkJU8jCt1LfeMkvY2BAq+d4oek4r0aACQoQ==", "requires": { "request": "^2.88.0" }, @@ -5724,7 +10281,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, "requires": { "shebang-regex": "^1.0.0" } @@ -5732,8 +10288,7 @@ "shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" }, "shiro-trie": { "version": "0.4.8", @@ -5797,19 +10352,39 @@ "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, "simple-statistics": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/simple-statistics/-/simple-statistics-0.7.0.tgz", "integrity": "sha1-xQ8Tu9yX6aT9ICVjgtoX5o7asco=" }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "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" + } + } + } + }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, "requires": { "base": "^0.11.1", "debug": "^2.2.0", @@ -5825,7 +10400,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -5834,7 +10408,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -5842,8 +10415,7 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" } } }, @@ -5851,7 +10423,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, "requires": { "define-property": "^1.0.0", "isobject": "^3.0.0", @@ -5862,7 +10433,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, "requires": { "is-descriptor": "^1.0.0" } @@ -5871,7 +10441,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -5880,7 +10449,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -5889,7 +10457,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -5902,7 +10469,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, "requires": { "kind-of": "^3.2.0" }, @@ -5911,7 +10477,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -6011,7 +10576,6 @@ "version": "0.5.2", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", - "dev": true, "requires": { "atob": "^2.1.1", "decode-uri-component": "^0.2.0", @@ -6021,9 +10585,9 @@ } }, "source-map-support": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", - "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", + "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -6032,8 +10596,7 @@ "source-map-url": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" }, "sparse-bitfield": { "version": "3.0.3", @@ -6044,6 +10607,52 @@ "memory-pager": "^1.0.2" } }, + "spawn-wrap": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.2.tgz", + "integrity": "sha512-vMwR3OmmDhnxCVxM8M+xO/FtIp6Ju/mNaDfCMMW7FDcLRTPFWUswec4LXJHTJE2hwTI9O0YBfygu4DalFl7Ylg==", + "dev": true, + "requires": { + "foreground-child": "^1.5.6", + "mkdirp": "^0.5.0", + "os-homedir": "^1.0.1", + "rimraf": "^2.6.2", + "signal-exit": "^3.0.2", + "which": "^1.3.0" + } + }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz", + "integrity": "sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA==", + "dev": true + }, "split": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", @@ -6056,7 +10665,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, "requires": { "extend-shallow": "^3.0.0" } @@ -6087,7 +10695,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, "requires": { "figgy-pudding": "^3.5.1" } @@ -6096,7 +10703,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, "requires": { "define-property": "^0.2.5", "object-copy": "^0.1.0" @@ -6106,7 +10712,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -6127,7 +10732,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, "requires": { "inherits": "~2.0.1", "readable-stream": "^2.0.2" @@ -6145,7 +10749,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, "requires": { "end-of-stream": "^1.1.0", "stream-shift": "^1.0.0" @@ -6155,7 +10758,6 @@ "version": "2.8.3", "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, "requires": { "builtin-status-codes": "^3.0.0", "inherits": "^2.0.1", @@ -6167,32 +10769,29 @@ "stream-shift": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", - "dev": true + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" }, "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "requires": { + "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "strip-ansi": "^5.1.0" }, "dependencies": { "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^4.1.0" } } } @@ -6201,7 +10800,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "requires": { "safe-buffer": "~5.1.0" } @@ -6214,17 +10812,27 @@ "ansi-regex": "^2.0.0" } }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true }, "style-loader": { "version": "0.23.1", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.23.1.tgz", "integrity": "sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg==", - "dev": true, "requires": { "loader-utils": "^1.1.0", "schema-utils": "^1.0.0" @@ -6287,36 +10895,107 @@ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" }, "swagger-ui-dist": { - "version": "3.20.6", - "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-3.20.6.tgz", - "integrity": "sha512-CN+2z6AP0/KR6Z7wPtBA9ZWr9z28dzA5R88VturLmDSVtYIAB3D6aTt1bCj39sUtLsVwxFVrBDbNtdXcZCvFHQ==" + "version": "3.22.1", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-3.22.1.tgz", + "integrity": "sha512-KITbEqXkXrjGH12A0lpVZlH3uODFkwUh8d15My1YD4N0PSZDnIiC1iMFT6ryyuJxDYWZh0qezKpPqa5FRowngw==" + }, + "swagger-ui-express": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-4.0.7.tgz", + "integrity": "sha512-ipXe53qDMjB2GlFcWARof15fMxX0n0wkwUturBpdovfJLaqod3WAqimwQGFXjwpWKA6hnxEPrd31yOzaYkP++A==", + "requires": { + "swagger-ui-dist": "^3.18.1" + } }, "symbol-tree": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=" }, + "table": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.1.tgz", + "integrity": "sha512-E6CK1/pZe2N75rGZQotFOdmzWQ1AILtgYbMAbAjvms0S1l5IDB47zG3nCnFGB/w+7nB3vKofbLXCH7HPBo864w==", + "dev": true, + "requires": { + "ajv": "^6.9.1", + "lodash": "^4.17.11", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + } + }, "tapable": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.1.tgz", - "integrity": "sha512-9I2ydhj8Z9veORCw5PRm4u9uebCn0mcCa6scWoNcbZ6dAtoo2618u9UUzxgmsCOreJpqDDuv61LvwofW7hLcBA==", - "dev": true + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" + }, + "term-size": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", + "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "dev": true, + "requires": { + "execa": "^0.7.0" + }, + "dependencies": { + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + } + } }, "terser": { - "version": "3.16.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-3.16.1.tgz", - "integrity": "sha512-JDJjgleBROeek2iBcSNzOHLKsB/MdDf+E/BOAJ0Tk9r7p9/fVobfv7LMJ/g/k3v9SXdmjZnIlFd5nfn/Rt0Xow==", + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-3.17.0.tgz", + "integrity": "sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ==", "requires": { - "commander": "~2.17.1", + "commander": "^2.19.0", "source-map": "~0.6.1", - "source-map-support": "~0.5.9" + "source-map-support": "~0.5.10" } }, "terser-webpack-plugin": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.2.2.tgz", - "integrity": "sha512-1DMkTk286BzmfylAvLXwpJrI7dWa5BnFmscV/2dCr8+c56egFcbaeFAl7+sujAjdmpLam21XRdhA4oifLyiWWg==", - "dev": true, + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.2.3.tgz", + "integrity": "sha512-GOK7q85oAb/5kE12fMuLdn2btOS9OBZn4VsecpHDywoUC/jLhSAKOiYo0ezx7ss2EXPMzyEWFoE0s1WLE+4+oA==", "requires": { "cacache": "^11.0.2", "find-cache-dir": "^2.0.0", @@ -6326,21 +11005,42 @@ "terser": "^3.16.1", "webpack-sources": "^1.1.0", "worker-farm": "^1.5.2" + } + }, + "test-exclude": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.2.tgz", + "integrity": "sha512-N2pvaLpT8guUpb5Fe1GJlmvmzH3x+DAKmmyEQmFP792QcLYoGE1syxztSvPD1V8yPe6VrcCt6YGQVjSRjCASsA==", + "dev": true, + "requires": { + "glob": "^7.1.3", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^2.0.0" }, "dependencies": { - "terser": { - "version": "3.16.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-3.16.1.tgz", - "integrity": "sha512-JDJjgleBROeek2iBcSNzOHLKsB/MdDf+E/BOAJ0Tk9r7p9/fVobfv7LMJ/g/k3v9SXdmjZnIlFd5nfn/Rt0Xow==", + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "dev": true, "requires": { - "commander": "~2.17.1", - "source-map": "~0.6.1", - "source-map-support": "~0.5.9" + "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" } } } }, + "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 + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -6350,21 +11050,34 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, "requires": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" } }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "dev": true + }, "timers-browserify": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==", - "dev": true, "requires": { "setimmediate": "^1.0.4" } }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, "to-array": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", @@ -6373,14 +11086,18 @@ "to-arraybuffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=" + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true }, "to-object-path": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, "requires": { "kind-of": "^3.0.2" }, @@ -6389,7 +11106,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -6400,7 +11116,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, "requires": { "define-property": "^2.0.2", "extend-shallow": "^3.0.2", @@ -6409,38 +11124,30 @@ } }, "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", "dev": true, "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "nopt": "~1.0.10" }, "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "abbrev": "1" } - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true } } }, @@ -6466,6 +11173,12 @@ "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=" }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, "tryer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", @@ -6473,16 +11186,14 @@ "dev": true }, "tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", - "dev": true + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" }, "tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=" }, "tunnel-agent": { "version": "0.6.0", @@ -6517,15 +11228,14 @@ "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "uglify-js": { - "version": "3.4.9", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz", - "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==", + "version": "3.5.6", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.5.6.tgz", + "integrity": "sha512-YDKRX8F0Y+Jr7LhoVk0n4G7ltR3Y7qFAj+DtVBthlOgCcIj1hyMigCfousVfn9HKmvJ+qiFlLDwaHx44/e5ZKw==", "requires": { - "commander": "~2.17.1", + "commander": "~2.20.0", "source-map": "~0.6.1" } }, @@ -6534,46 +11244,30 @@ "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" }, - "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "undefsafe": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz", + "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=", "dev": true, + "requires": { + "debug": "^2.2.0" + } + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } + "set-value": "^2.0.1" } }, "unique-filename": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, "requires": { "unique-slug": "^2.0.0" } @@ -6582,11 +11276,19 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.1.tgz", "integrity": "sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg==", - "dev": true, "requires": { "imurmurhash": "^0.1.4" } }, + "unique-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "dev": true, + "requires": { + "crypto-random-string": "^1.0.0" + } + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -6596,7 +11298,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, "requires": { "has-value": "^0.3.1", "isobject": "^3.0.0" @@ -6606,7 +11307,6 @@ "version": "0.3.1", "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, "requires": { "get-value": "^2.0.3", "has-values": "^0.1.4", @@ -6617,7 +11317,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, "requires": { "isarray": "1.0.0" } @@ -6627,23 +11326,75 @@ "has-values": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" } } }, - "upath": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", - "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", + "unzip-response": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", + "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", "dev": true }, + "upath": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", + "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==" + }, + "update-notifier": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", + "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", + "dev": true, + "requires": { + "boxen": "^1.2.1", + "chalk": "^2.0.1", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", + "is-installed-globally": "^0.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" + }, + "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" + } + } + } + }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", @@ -6655,14 +11406,12 @@ "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" }, "url": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, "requires": { "punycode": "1.3.2", "querystring": "0.2.0" @@ -6671,22 +11420,28 @@ "punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" } } }, + "url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "dev": true, + "requires": { + "prepend-http": "^1.0.1" + } + }, "use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" }, "util": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, "requires": { "inherits": "2.0.3" } @@ -6694,8 +11449,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "utils-merge": { "version": "1.0.1", @@ -6708,10 +11462,19 @@ "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" }, "v8-compile-cache": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.2.tgz", - "integrity": "sha512-1wFuMUIM16MDJRCrpbpuEPTUGmM5QMUg0cr3KFwra2XgOgFcPGDQHDh3CszSCD2Zewc/dh/pamNEW8CbfDebUw==", - "dev": true + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz", + "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==" + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } }, "vary": { "version": "1.1.2", @@ -6729,13 +11492,9 @@ } }, "vm-browserify": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", - "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", - "dev": true, - "requires": { - "indexof": "0.0.1" - } + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", + "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==" }, "w3c-hr-time": { "version": "1.0.1", @@ -6749,7 +11508,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", - "dev": true, "requires": { "chokidar": "^2.0.2", "graceful-fs": "^4.1.2", @@ -6762,17 +11520,15 @@ "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" }, "webpack": { - "version": "4.29.3", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.29.3.tgz", - "integrity": "sha512-xPJvFeB+8tUflXFq+OgdpiSnsCD5EANyv56co5q8q8+YtEasn5Sj3kzY44mta+csCIEB0vneSxnuaHkOL2h94A==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "^6.0.5", - "acorn-dynamic-import": "^4.0.0", + "version": "4.35.3", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.35.3.tgz", + "integrity": "sha512-xggQPwr9ILlXzz61lHzjvgoqGU08v5+Wnut19Uv3GaTtzN4xBTcwnobodrXE142EL1tOiS5WVEButooGzcQzTA==", + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-module-context": "1.8.5", + "@webassemblyjs/wasm-edit": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5", + "acorn": "^6.2.0", "ajv": "^6.1.0", "ajv-keywords": "^3.1.0", "chrome-trace-event": "^1.0.0", @@ -6794,20 +11550,20 @@ }, "dependencies": { "acorn": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.7.tgz", - "integrity": "sha512-HNJNgE60C9eOTgn974Tlp3dpLZdUr+SoxxDwPaY9J/kDNOLQTkaDgwBUXAF4SSsrAwD9RpdxuHK/EbuF+W9Ahw==", - "dev": true + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.0.tgz", + "integrity": "sha512-8oe72N3WPMjA+2zVG71Ia0nXZ8DpQH+QyyHO+p06jT8eg8FGG3FbcUIi8KziHlAfheJQZeoqbvq1mQSQHXKYLw==" } } }, "webpack-bundle-analyzer": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.0.3.tgz", - "integrity": "sha512-naLWiRfmtH4UJgtUktRTLw6FdoZJ2RvCR9ePbwM9aRMsS/KjFerkPZG9epEvXRAw5d5oPdrs9+3p+afNjxW8Xw==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.3.2.tgz", + "integrity": "sha512-7qvJLPKB4rRWZGjVp5U1KEjwutbDHSKboAl0IfafnrdXMrgC0tOtZbQD6Rw0u4cmpgRN4O02Fc0t8eAT+FgGzA==", "dev": true, "requires": { - "acorn": "^5.7.3", + "acorn": "^6.0.7", + "acorn-walk": "^6.1.1", "bfj": "^6.1.1", "chalk": "^2.4.1", "commander": "^2.18.0", @@ -6821,6 +11577,12 @@ "ws": "^6.0.0" }, "dependencies": { + "acorn": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", + "dev": true + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -6841,12 +11603,6 @@ "supports-color": "^5.3.0" } }, - "commander": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", - "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", - "dev": true - }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -6857,9 +11613,9 @@ } }, "ws": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.3.tgz", - "integrity": "sha512-tbSxiT+qJI223AP4iLfQbkbxkwdFcneYinM2+x46Gx2wgvbaOMO36czfdfVUBRTHvzAMRhDd98sA5d/BuWbQdg==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", "dev": true, "requires": { "async-limiter": "~1.0.0" @@ -6868,29 +11624,32 @@ } }, "webpack-cli": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.2.3.tgz", - "integrity": "sha512-Ik3SjV6uJtWIAN5jp5ZuBMWEAaP5E4V78XJ2nI+paFPh8v4HPSwo/myN0r29Xc/6ZKnd2IdrAlpSgNOu2CDQ6Q==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "cross-spawn": "^6.0.5", - "enhanced-resolve": "^4.1.0", - "findup-sync": "^2.0.0", - "global-modules": "^1.0.0", - "import-local": "^2.0.0", - "interpret": "^1.1.0", - "loader-utils": "^1.1.0", - "supports-color": "^5.5.0", - "v8-compile-cache": "^2.0.2", - "yargs": "^12.0.4" + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.6.tgz", + "integrity": "sha512-0vEa83M7kJtxK/jUhlpZ27WHIOndz5mghWL2O53kiDoA9DIxSKnfqB92LoqEn77cT4f3H2cZm1BMEat/6AZz3A==", + "requires": { + "chalk": "2.4.2", + "cross-spawn": "6.0.5", + "enhanced-resolve": "4.1.0", + "findup-sync": "3.0.0", + "global-modules": "2.0.0", + "import-local": "2.0.0", + "interpret": "1.2.0", + "loader-utils": "1.2.3", + "supports-color": "6.1.0", + "v8-compile-cache": "2.0.3", + "yargs": "13.2.4" }, "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==" + }, "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" } @@ -6899,29 +11658,138 @@ "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==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.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, + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "requires": { "has-flag": "^3.0.0" } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "yargs": { + "version": "13.2.4", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", + "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.0" + } + }, + "yargs-parser": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "webpack-dev-middleware": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.0.tgz", + "integrity": "sha512-qvDesR1QZRIAZHOE3iQ4CXLZZSQ1lAUsSpnQmlB1PBfoN/xdRjmge3Dok0W4IdaVLJOGJy3sGI4sZHwjRU0PCA==", + "dev": true, + "requires": { + "memory-fs": "^0.4.1", + "mime": "^2.4.2", + "range-parser": "^1.2.1", + "webpack-log": "^2.0.0" + }, + "dependencies": { + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true } } }, + "webpack-hot-middleware": { + "version": "2.25.0", + "resolved": "https://registry.npmjs.org/webpack-hot-middleware/-/webpack-hot-middleware-2.25.0.tgz", + "integrity": "sha512-xs5dPOrGPCzuRXNi8F6rwhawWvQQkeli5Ro48PRuQh8pYPCPmNnltP9itiUPT4xI8oW+y0m59lyyeQk54s5VgA==", + "dev": true, + "requires": { + "ansi-html": "0.0.7", + "html-entities": "^1.2.0", + "querystring": "^0.2.0", + "strip-ansi": "^3.0.0" + } + }, + "webpack-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", + "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", + "dev": true, + "requires": { + "ansi-colors": "^3.0.0", + "uuid": "^3.3.2" + } + }, "webpack-sources": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.3.0.tgz", "integrity": "sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA==", - "dev": true, "requires": { "source-list-map": "^2.0.0", "source-map": "~0.6.1" @@ -6964,7 +11832,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, "requires": { "isexe": "^2.0.0" } @@ -6972,8 +11839,43 @@ "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "widest-line": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", + "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", + "dev": true, + "requires": { + "string-width": "^2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } }, "wordwrap": { "version": "1.0.0", @@ -6984,7 +11886,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz", "integrity": "sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ==", - "dev": true, "requires": { "errno": "~0.1.7" } @@ -7024,8 +11925,27 @@ "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" + } + }, + "write-file-atomic": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.2.tgz", + "integrity": "sha512-s0b6vB3xIVRLWywa6X9TOMA7k9zio0TMOsl9ZnDkliA/cfJlpHXAscj0gbHVJiTdIuAYpIyqS5GW91fqm6gG5g==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } }, "ws": { "version": "4.1.0", @@ -7041,6 +11961,12 @@ "resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.1.0.tgz", "integrity": "sha512-rx3GzJlgEeZ08MIcDsU2vY2B1QEriUKJTSiNHHUIem6eg9pzVOr2TL3Y4Pd6TMAM5D5azGjcxqI62piITBDHVg==" }, + "xdg-basedir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", + "dev": true + }, "xml-name-validator": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", @@ -7054,45 +11980,50 @@ "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" }, "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" }, "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true }, "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.2.tgz", + "integrity": "sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA==", "dev": true, "requires": { "cliui": "^4.0.0", - "decamelize": "^1.2.0", "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", + "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", - "string-width": "^2.0.0", + "string-width": "^3.0.0", "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" + "y18n": "^4.0.0", + "yargs-parser": "^13.0.0" + }, + "dependencies": { + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + } } }, "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.0.0.tgz", + "integrity": "sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw==", "dev": true, "requires": { "camelcase": "^5.0.0", diff --git a/package.json b/package.json index c72a2d15341..5adf81960af 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nightscout", - "version": "0.11.1", + "version": "0.12.3", "description": "Nightscout acts as a web-based CGM (Continuous Glucose Montinor) to allow multiple caregivers to remotely view a patients glucose data in realtime.", "license": "AGPL-3.0", "author": "Nightscout Team", @@ -16,22 +16,27 @@ "type": "git", "url": "https://github.com/nightscout/cgm-remote-monitor.git" }, - "contributors": { - "name": "Nightscout Team", - "url": "https://github.com/nightscout/cgm-remote-monitor/graphs/contributors" - }, + "contributors": [ + { + "name": "Nightscout Team", + "url": "https://github.com/nightscout/cgm-remote-monitor/graphs/contributors" + } + ], "bugs": { "url": "https://github.com/nightscout/cgm-remote-monitor/issues" }, "scripts": { "start": "node server.js", - "test": "make test", + "test": "env-cmd ./test.env mocha --exit tests/*.test.js", "env": "env", "postinstall": "webpack --mode production --config webpack.config.js && npm run-script update-buster", "bundle": "webpack --mode production --config webpack.config.js && npm run-script update-buster", "bundle-dev": "webpack --mode development --config webpack.config.js && npm run-script update-buster", "bundle-analyzer": "webpack --mode development --config webpack.config.js --profile --json > stats.json && webpack-bundle-analyzer stats.json", - "update-buster": "node bin/generateCacheBuster.js >tmp/cacheBusterToken" + "update-buster": "node bin/generateCacheBuster.js >tmp/cacheBusterToken", + "coverage": "env-cmd ./test.env nyc mocha --exit tests/*.test.js", + "dev": "env-cmd ./my.env nodemon server.js 0.0.0.0", + "prod": "env-cmd ./my.prod.env node server.js 0.0.0.0" }, "config": { "blanket": { @@ -48,66 +53,77 @@ } }, "engines": { - "node": "^10.14.1 || ^8.15.0", - "npm": "6.x" + "node": "^10.15.2 || ^8.15.1", + "npm": "^6.4.1" }, "dependencies": { "async": "^0.9.2", "body-parser": "^1.18.3", "bootevent": "0.0.1", - "compression": "^1.7.3", + "braces": "^3.0.2", + "compression": "^1.7.4", "css-loader": "^1.0.1", "cssmin": "^0.4.3", "d3": "^3.5.17", "ejs": "^2.6.1", "errorhandler": "^1.5.0", "event-stream": "3.3.4", - "expand-braces": "^0.1.2", + "expose-loader": "^0.7.5", "express": "^4.16.4", "express-minify": "^1.0.0", - "flot": "^0.8.0-alpha", - "helmet": "^3.15.0", + "file-loader": "^3.0.1", + "flot": "^0.8.3", + "heapdump": "^0.3.14", + "helmet": "^3.16.0", "jquery": "^3.3.1", "jquery-ui-bundle": "^1.12.1-migrate", "jquery.tooltips": "^1.0.0", "js-storage": "^1.0.4", "jsdom": "~11.11.0", - "jsonwebtoken": "^8.4.0", - "lodash": "^4.17.11", + "jsonwebtoken": "^8.5.1", + "lodash": "^4.17.15", + "memory-cache": "^0.2.0", "mime": "^2.4.0", - "minimed-connect-to-nightscout": "^1.1.1", + "minimed-connect-to-nightscout": "^1.2.2", "moment": "^2.24.0", + "moment-locales-webpack-plugin": "^1.0.7", "moment-timezone": "^0.5.23", - "mongodb": "^3.1.13", + "moment-timezone-data-webpack-plugin": "^1.1.0", + "mongodb": "^3.2.2", "mongomock": "^0.1.2", "node-cache": "^4.2.0", "parse-duration": "^0.1.1", - "prettyjson": "^1.2.1", "pushover-notifications": "^1.2.0", "random-token": "0.0.8", "request": "^2.88.0", - "semver": "^5.6.0", - "share2nightscout-bridge": "^0.2.0", + "semver": "^6.0.0", + "share2nightscout-bridge": "^0.2.1", "shiro-trie": "^0.4.8", "simple-statistics": "^0.7.0", "socket.io": "~2.1.1", - "swagger-ui-dist": "^3.20.6", - "terser": "^3.16.1", - "traverse": "^0.6.6" + "style-loader": "^0.23.1", + "swagger-ui-dist": "^3.22.0", + "swagger-ui-express": "^4.0.7", + "terser": "^3.17.0", + "traverse": "^0.6.6", + "webpack": "^4.29.6", + "webpack-cli": "^3.3.0" }, "devDependencies": { + "nodemon": "^1.19.0", + "babel-eslint": "^10.0.2", "benv": "^3.3.0", - "expose-loader": "^0.7.5", - "file-loader": "^3.0.1", + "env-cmd": "^8.0.2", + "eslint": "^6.0.1", + "eslint-loader": "^2.1.2", "istanbul": "^0.4.5", "mocha": "^5.2.0", - "moment-locales-webpack-plugin": "^1.0.7", + "nyc": "^14.0.0", "should": "^13.2.3", - "style-loader": "^0.23.1", "supertest": "^3.4.2", - "terser-webpack-plugin": "^1.2.2", - "webpack": "^4.29.3", - "webpack-bundle-analyzer": "^3.0.3", - "webpack-cli": "^3.2.3" + "terser-webpack-plugin": "^1.2.3", + "webpack-bundle-analyzer": "^3.3.2", + "webpack-dev-middleware": "^3.7.0", + "webpack-hot-middleware": "^2.25.0" } } diff --git a/static/css/drawer.css b/static/css/drawer.css index 41afd6fd400..f9e6147fe2d 100644 --- a/static/css/drawer.css +++ b/static/css/drawer.css @@ -227,6 +227,7 @@ h1, legend, overflow: hidden; } #buttonbar { + margin-right: 50px; padding-right: 15px; height: 44px; opacity: 0.75; diff --git a/static/css/main.css b/static/css/main.css index 2d45c2d081e..78cf7ae4c97 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -119,12 +119,13 @@ a, a:visited, a:link { font-family: 'Ubuntu', Verdana, Helvetica, Arial, sans-serif; vertical-align: middle; clear: both; + white-space: nowrap; } .bgStatus { float: right; text-align: center; - white-space: nowrap; + white-space: normal; padding-right: 20px; } @@ -140,6 +141,10 @@ a, a:visited, a:link { color: #4cff00; } +.bgStatus .bgSpan { + white-space: nowrap; +} + .bgStatus .currentBG { font-size: 120px; line-height: 100px; @@ -240,14 +245,16 @@ a, a:visited, a:link { .status { color: #808080; font-size: 100px; + white-space: normal; } .statusBox { text-align: center; - width: 250px; + width: 40%; } .statusPills { font-size: 20px; line-height: 23px; + margin-left: 5px; } .loading .statusPills { @@ -397,7 +404,7 @@ a, a:visited, a:link { margin: 4px; padding: 0; color: #808080; - width: 250px; + width: 40%; text-align: center; } @@ -474,6 +481,7 @@ a, a:visited, a:link { .focus-range { margin: 0; + width: 50%; } .focus-range li { @@ -491,7 +499,7 @@ a, a:visited, a:link { @media (max-width: 750px) { .bgStatus { - width: 240px; + width: 50%; padding: 0 0 20px 0; } @@ -503,6 +511,10 @@ a, a:visited, a:link { font-size: 12px; } + .statusBox { + width: auto; + } + .bgStatus .currentBG { font-size: 70px; line-height: 60px; @@ -741,10 +753,6 @@ a, a:visited, a:link { display: block; } - .statusBox { - width: 220px; - } - .statusPills { display: inline; margin-left: auto; diff --git a/static/css/report.css b/static/css/report.css index 9ec304cb1a7..afe046f00d9 100644 --- a/static/css/report.css +++ b/static/css/report.css @@ -25,7 +25,7 @@ body { #tabnav { text-align: left; margin: 1em 0 1em 0; - font: bold 11px verdana, arial, sans-serif; + font: bold 11pt verdana, arial, sans-serif; border-bottom: 1px solid #6c6; list-style-type: none; padding: 3px 10px 3px 10px; @@ -59,7 +59,7 @@ body { text-align: left; padding: 4px; font-size: 14px; - line-height: 15px; + line-height: 15pt; background: white; border: 2px solid black; border-radius: 8px; diff --git a/static/images/TripleDown.svg b/static/images/TripleDown.svg new file mode 100644 index 00000000000..2fb7ec80baf --- /dev/null +++ b/static/images/TripleDown.svg @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/static/images/TripleUp.svg b/static/images/TripleUp.svg new file mode 100644 index 00000000000..a773f61fd7e --- /dev/null +++ b/static/images/TripleUp.svg @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/static/report/js/report.js b/static/report/js/report.js index 5240cc94961..f7b02ec44af 100644 --- a/static/report/js/report.js +++ b/static/report/js/report.js @@ -634,8 +634,9 @@ data.sgv.sort(function(a, b) { return a.mills - b.mills; }); var lastDate = 0; data.sgv = data.sgv.filter(function(d) { - var ok = (lastDate + ONE_MIN_IN_MS) < d.mills; + var ok = (lastDate + ONE_MIN_IN_MS) <= d.mills; lastDate = d.mills; + if (!ok) { console.log("itm",JSON.stringify(d)); } return ok; }); data.mbg = mbgData.slice(); @@ -752,6 +753,9 @@ } // treatments data.dailyCarbs = 0; + data.dailyProtein = 0; + data.dailyFat = 0; + data.treatments.forEach(function (d) { if (parseFloat(d.insulin) > maxInsulinValue) { maxInsulinValue = parseFloat(d.insulin); @@ -760,7 +764,13 @@ maxCarbsValue = parseFloat(d.carbs); } if (d.carbs) { - data.dailyCarbs += d.carbs; + data.dailyCarbs += Number(d.carbs); + } + if (d.protein) { + data.dailyProtein += Number(d.protein); + } + if (d.fat) { + data.dailyFat += Number(d.fat); } }); if (data.dailyCarbs > maxDailyCarbsValue) { diff --git a/swagger.json b/swagger.json index 4e5fbe80a57..1daf2c45a38 100755 --- a/swagger.json +++ b/swagger.json @@ -8,7 +8,7 @@ "info": { "title": "Nightscout API", "description": "Own your DData with the Nightscout API", - "version": "0.11.1", + "version": "0.12.3", "license": { "name": "AGPL 3", "url": "https://www.gnu.org/licenses/agpl.txt" @@ -907,7 +907,7 @@ }, "dateString": { "type": "string", - "description": "dateString, prefer ISO `8601`" + "description": "dateString, MUST be ISO `8601` format date parseable by Javascript Date()" }, "date": { "type": "number", @@ -1174,7 +1174,15 @@ }, "carbs": { "type": "number", - "description": "Number of carbs." + "description": " Amount of carbs consumed in grams." + }, + "protein": { + "type": "number", + "description": " Amount of protein consumed in grams." + }, + "fat": { + "type": "number", + "description": " Amount of fat consumed in grams." }, "insulin": { "type": "number", diff --git a/swagger.yaml b/swagger.yaml index 44d98be8001..4591239d8d8 100755 --- a/swagger.yaml +++ b/swagger.yaml @@ -4,7 +4,7 @@ servers: info: title: Nightscout API description: Own your DData with the Nightscout API - version: 0.11.1 + version: 0.12.3 license: name: AGPL 3 url: 'https://www.gnu.org/licenses/agpl.txt' @@ -679,7 +679,7 @@ components: description: 'sgv, mbg, cal, etc' dateString: type: string - description: 'dateString, prefer ISO `8601`' + description: 'dateString, MUST be ISO `8601` format date parseable by Javascript Date()' date: type: number description: Epoch @@ -723,7 +723,7 @@ components: description: 'Device type and hostname for example openaps://hostname' created_at: type: string - description: 'dateString, prefer ISO `8601`' + description: 'dateString, MUST be ISO `8601` format date parseable by Javascript Date()' openaps: type: string description: 'OpenAPS devicestatus record - TODO: Fill Out Details' @@ -744,7 +744,7 @@ components: properties: clock: type: string - description: 'dateString, prefer ISO `8601`' + description: 'dateString, MUST be ISO `8601` format date parseable by Javascript Date()' battery: $ref: '#/components/schemas/pumpbattery' reservoir: @@ -773,7 +773,7 @@ components: description: Is Pump Suspended timestamp: type: string - description: 'dateString, prefer ISO `8601`' + description: 'dateString, MUST be ISO `8601` format date parseable by Javascript Date()' uploader: properties: batteryVoltage: @@ -878,7 +878,13 @@ components: description: 'Method used to obtain glucose, Finger or Sensor.' carbs: type: number - description: Number of carbs. + description: Amount of carbs consumed in grams. + protein: + type: number + description: Amount of protein consumed in grams. + fat: + type: number + description: Amount of fat consumed in grams. insulin: type: number description: 'Amount of insulin, if any.' diff --git a/tests/admintools.test.js b/tests/admintools.test.js index 2c2924c4a8c..bbede54156a 100644 --- a/tests/admintools.test.js +++ b/tests/admintools.test.js @@ -70,7 +70,7 @@ describe('admintools', function ( ) { before(function (done) { benv.setup(function() { - benv.require(__dirname + '/../tmp/js/bundle.js'); + benv.require(__dirname + '/../tmp/js/bundle.report.js'); self.$ = $; diff --git a/tests/api.devicestatus.test.js b/tests/api.devicestatus.test.js index 341fa16b311..a618db49056 100644 --- a/tests/api.devicestatus.test.js +++ b/tests/api.devicestatus.test.js @@ -60,6 +60,7 @@ describe('Devicestatus API', function ( ) { .expect(200) .expect(function (response) { response.body[0].xdripjs.state.should.equal(6); + response.body[0].utcOffset.should.equal(0); }) .end(function (err) { if (err) { diff --git a/tests/api.entries.test.js b/tests/api.entries.test.js index 4ccae695fff..098b5c45663 100644 --- a/tests/api.entries.test.js +++ b/tests/api.entries.test.js @@ -19,7 +19,7 @@ describe('Entries REST api', function ( ) { self.app = require('express')( ); self.app.enable('api'); bootevent(self.env, language).boot(function booted (ctx) { - self.app.use('/', entries(self.app, self.wares, ctx)); + self.app.use('/', entries(self.app, self.wares, ctx, self.env)); self.archive = require('../lib/server/entries')(self.env, ctx); var creating = load('json'); @@ -271,7 +271,9 @@ describe('Entries REST api', function ( ) { .set('api-secret', self.env.api_secret || '') .expect(200) .expect(function (response) { - response.body[0].sgv.should.equal('199'); + var entry = response.body[0]; + entry.sgv.should.equal('199'); + entry.utcOffset.should.equal(-420); }) .end(function (err) { if (err) { diff --git a/tests/api.treatments.test.js b/tests/api.treatments.test.js index 7b13770d35f..4ba3739f4c0 100644 --- a/tests/api.treatments.test.js +++ b/tests/api.treatments.test.js @@ -4,6 +4,7 @@ var _ = require('lodash'); var request = require('supertest'); var should = require('should'); var language = require('../lib/language')(); +var _moment = require('moment'); describe('Treatment API', function ( ) { this.timeout(10000); @@ -60,6 +61,44 @@ describe('Treatment API', function ( ) { }); }); + + it('post single treatments in zoned time format', function (done) { + + var current_time = Date.now(); + console.log('Testing date with local format: ', _moment(current_time).format("YYYY-MM-DDTHH:mm:ss.SSSZZ")); + + self.ctx.treatments().remove({ }, function ( ) { + request(self.app) + .post('/api/treatments/') + .set('api-secret', self.env.api_secret || '') + .send({eventType: 'Meal Bolus', created_at: _moment(current_time).format("YYYY-MM-DDTHH:mm:ss.SSSZZ"), carbs: '30', insulin: '2.00', glucose: 100, glucoseType: 'Finger', units: 'mg/dl'}) + .expect(200) + .end(function (err) { + if (err) { + done(err); + } else { + self.ctx.treatments.list({}, function (err, list) { + var sorted = _.sortBy(list, function (treatment) { + return treatment.created_at; + }); + console.log(sorted); + sorted.length.should.equal(1); + sorted[0].glucose.should.equal(100); + should.not.exist(sorted[0].eventTime); + sorted[0].insulin.should.equal(2); + sorted[0].carbs.should.equal(30); + var zonedTime = _moment(current_time).utc().format("YYYY-MM-DDTHH:mm:ss.SSS") + "Z"; + sorted[0].created_at.should.equal(zonedTime); + sorted[0].utcOffset.should.equal(-1* new Date().getTimezoneOffset()); + done(); + }); + } + }); + + }); + }); + + it('post a treatment array', function (done) { self.ctx.treatments().remove({ }, function ( ) { request(self.app) @@ -101,7 +140,7 @@ describe('Treatment API', function ( ) { , {eventType: 'BG Check', glucose: 100, units: 'mg/dl', created_at: now} , {eventType: 'BG Check', glucose: 100, units: 'mg/dl', created_at: now} , {eventType: 'BG Check', glucose: 100, units: 'mg/dl', created_at: now} - , {eventType: 'Meal Bolus', carbs: '30', insulin: '2.00', preBolus: '15', glucose: 100, glucoseType: 'Finger', units: 'mg/dl'} + , {eventType: 'Meal Bolus', created_at: now, carbs: '30', insulin: '2.00', preBolus: '15', glucose: 100, glucoseType: 'Finger', units: 'mg/dl'} ]) .expect(200) .end(function (err) { @@ -125,6 +164,7 @@ describe('Treatment API', function ( ) { }); }); }); + it('post a treatment, query, delete, verify gone', function (done) { // insert a treatment - needs to be unique from example data console.log('Inserting treatment entry'); diff --git a/tests/api.unauthorized.test.js b/tests/api.unauthorized.test.js index 8c804c4244f..5785069f77e 100644 --- a/tests/api.unauthorized.test.js +++ b/tests/api.unauthorized.test.js @@ -21,7 +21,7 @@ describe('authed REST api', function ( ) { var self = this; self.known_key = known; require('../lib/server/bootevent')(env, language).boot(function booted (ctx) { - self.app.use('/', entries(self.app, self.wares, ctx)); + self.app.use('/', entries(self.app, self.wares, ctx, env)); self.archive = require('../lib/server/entries')(env, ctx); var creating = load('json'); diff --git a/tests/fixtures/headless.js b/tests/fixtures/headless.js index 8b59b7b5dba..7706d5a8b0b 100644 --- a/tests/fixtures/headless.js +++ b/tests/fixtures/headless.js @@ -15,7 +15,7 @@ function headless (benv, binding) { var someData = opts.mockAjax || { }; benv.setup(function() { - benv.require(__dirname + '/../../tmp/js/bundle.js'); + benv.require(__dirname + '/../../tmp/js/bundle.report.js'); self.$ = $; diff --git a/tests/loop.test.js b/tests/loop.test.js index 805f49040ab..9c65ff9bdd1 100644 --- a/tests/loop.test.js +++ b/tests/loop.test.js @@ -119,7 +119,7 @@ describe('loop', function ( ) { , pluginBase: { updatePillText: function mockedUpdatePillText (plugin, options) { options.label.should.equal('Loop ⌁'); - options.value.should.equal('1m ago'); + options.value.should.equal('1m ago ↝ 147'); var first = _.first(options.info); first.label.should.equal('1m ago'); first.value.should.equal('Temp Basal Started 0.88U/hour for 30m, IOB: 0.17U, Predicted Min-Max BG: 147-149, Eventual BG: 147'); diff --git a/tests/query.test.js b/tests/query.test.js new file mode 100644 index 00000000000..92a8a80673a --- /dev/null +++ b/tests/query.test.js @@ -0,0 +1,38 @@ +'use strict'; + +require('should'); + +var moment = require('moment'); + +describe('query', function ( ) { + var query = require('../lib/server/query'); + + it('should provide default options', function ( ) { + var opts = query(); + + var low = moment().utc().subtract(4, 'days').subtract(1, 'minutes').format(); + var high = moment().utc().subtract(4, 'days').add(1, 'minutes').format(); + + opts.date['$gte'].should.be.greaterThan(low); + opts.date['$gte'].should.be.lessThan(high); + }); + + it('should not override non default options', function ( ) { + var opts = query({}, { + deltaAgo: 2 * 24 * 60 * 60000, + dateField: 'created_at' + }); + + var low = moment().utc().subtract(2, 'days').subtract(1, 'minutes').format(); + var high = moment().utc().subtract(2, 'days').add(1, 'minutes').format(); + + opts.created_at['$gte'].should.greaterThan(low); + opts.created_at['$gte'].should.lessThan(high); + }); + + it('should not enforce date filter if query includes id', function ( ) { + var opts = query({ find: { _id: 1234 } }); + + (typeof opts.date).should.equal('undefined') + }); +}); diff --git a/tests/timeago.test.js b/tests/timeago.test.js index e47e9873d00..7b4a718ccd0 100644 --- a/tests/timeago.test.js +++ b/tests/timeago.test.js @@ -2,7 +2,7 @@ var should = require('should'); var levels = require('../lib/levels'); var times = require('../lib/times'); -describe('timeago', function ( ) { +describe('timeago', function() { var ctx = {}; ctx.ddata = require('../lib/data/ddata')(); ctx.notifications = require('../lib/notifications')(env, ctx); @@ -12,16 +12,16 @@ describe('timeago', function ( ) { var env = require('../env')(); - function freshSBX() { + function freshSBX () { //set extendedSettings right before calling withExtendedSettings, there's some strange test interference here - env.extendedSettings = {timeago: {enableAlerts: true}}; + env.extendedSettings = { timeago: { enableAlerts: true } }; var sbx = require('../lib/sandbox')().serverInit(env, ctx).withExtendedSettings(timeago); return sbx; } - it('Not trigger an alarm when data is current', function (done) { + it('Not trigger an alarm when data is current', function(done) { ctx.notifications.initRequests(); - ctx.ddata.sgvs = [{mills: Date.now(), mgdl: 100, type: 'sgv'}]; + ctx.ddata.sgvs = [{ mills: Date.now(), mgdl: 100, type: 'sgv' }]; var sbx = freshSBX(); timeago.checkNotifications(sbx); @@ -30,9 +30,9 @@ describe('timeago', function ( ) { done(); }); - it('Not trigger an alarm with future data', function (done) { + it('Not trigger an alarm with future data', function(done) { ctx.notifications.initRequests(); - ctx.ddata.sgvs = [{mills: Date.now() + times.mins(15).msecs, mgdl: 100, type: 'sgv'}]; + ctx.ddata.sgvs = [{ mills: Date.now() + times.mins(15).msecs, mgdl: 100, type: 'sgv' }]; var sbx = freshSBX(); timeago.checkNotifications(sbx); @@ -41,21 +41,27 @@ describe('timeago', function ( ) { done(); }); - it('should trigger a warning when data older than 15m', function (done) { + it('should trigger a warning when data older than 15m', function(done) { ctx.notifications.initRequests(); - ctx.ddata.sgvs = [{mills: Date.now() - times.mins(16).msecs, mgdl: 100, type: 'sgv'}]; + ctx.ddata.sgvs = [{ mills: Date.now() - times.mins(16).msecs, mgdl: 100, type: 'sgv' }]; var sbx = freshSBX(); timeago.checkNotifications(sbx); + + var currentTime = new Date().getTime(); + + // eslint-disable-next-line no-empty + while (currentTime + 500 >= new Date().getTime()) {} + var highest = ctx.notifications.findHighestAlarm('Time Ago'); highest.level.should.equal(levels.WARN); highest.message.should.equal('Last received: 16 mins ago\nBG Now: 100 mg/dl'); done(); }); - it('should trigger an urgent alarm when data older than 30m', function (done) { + it('should trigger an urgent alarm when data older than 30m', function(done) { ctx.notifications.initRequests(); - ctx.ddata.sgvs = [{mills: Date.now() - times.mins(31).msecs, mgdl: 100, type: 'sgv'}]; + ctx.ddata.sgvs = [{ mills: Date.now() - times.mins(31).msecs, mgdl: 100, type: 'sgv' }]; var sbx = freshSBX(); timeago.checkNotifications(sbx); @@ -70,55 +76,55 @@ describe('timeago', function ( ) { should.deepEqual( timeago.calcDisplay({ mills: now + times.mins(15).msecs }, now) - , {label: 'in the future', shortLabel: 'future'} + , { label: 'in the future', shortLabel: 'future' } ); //TODO: current behavior, we can do better //just a little in the future, pretend it's ok should.deepEqual( timeago.calcDisplay({ mills: now + times.mins(4).msecs }, now) - , {value: 1, label: 'min ago', shortLabel: 'm'} + , { value: 1, label: 'min ago', shortLabel: 'm' } ); should.deepEqual( timeago.calcDisplay(null, now) - , {label: 'time ago', shortLabel: 'ago'} + , { label: 'time ago', shortLabel: 'ago' } ); should.deepEqual( timeago.calcDisplay({ mills: now }, now) - , {value: 1, label: 'min ago', shortLabel: 'm'} + , { value: 1, label: 'min ago', shortLabel: 'm' } ); should.deepEqual( timeago.calcDisplay({ mills: now - 1 }, now) - , {value: 1, label: 'min ago', shortLabel: 'm'} + , { value: 1, label: 'min ago', shortLabel: 'm' } ); should.deepEqual( timeago.calcDisplay({ mills: now - times.sec(30).msecs }, now) - , {value: 1, label: 'min ago', shortLabel: 'm'} + , { value: 1, label: 'min ago', shortLabel: 'm' } ); should.deepEqual( timeago.calcDisplay({ mills: now - times.mins(30).msecs }, now) - , {value: 30, label: 'mins ago', shortLabel: 'm'} + , { value: 30, label: 'mins ago', shortLabel: 'm' } ); should.deepEqual( timeago.calcDisplay({ mills: now - times.hours(5).msecs }, now) - , {value: 5, label: 'hours ago', shortLabel: 'h'} + , { value: 5, label: 'hours ago', shortLabel: 'h' } ); should.deepEqual( timeago.calcDisplay({ mills: now - times.days(5).msecs }, now) - , {value: 5, label: 'days ago', shortLabel: 'd'} + , { value: 5, label: 'days ago', shortLabel: 'd' } ); should.deepEqual( timeago.calcDisplay({ mills: now - times.days(10).msecs }, now) - , {label: 'long ago', shortLabel: 'ago'} + , { label: 'long ago', shortLabel: 'ago' } ); }); -}); \ No newline at end of file +}); diff --git a/tests/utils.test.js b/tests/utils.test.js index be0b298290d..53cccf07507 100644 --- a/tests/utils.test.js +++ b/tests/utils.test.js @@ -15,6 +15,22 @@ describe('utils', function ( ) { utils.toFixed(5.499999999).should.equal('5.50'); }); + it('format numbers short', function () { + var undef; + utils.toFixedMin(3.345, 2).should.equal('3.35'); + utils.toFixedMin(5.499999999, 0).should.equal('5'); + utils.toFixedMin(5.499999999, 1).should.equal('5.5'); + utils.toFixedMin(5.499999999, 3).should.equal('5.5'); + utils.toFixedMin(123.45, -2).should.equal('100'); + utils.toFixedMin(-0.001, 2).should.equal('0'); + utils.toFixedMin(-2.47, 1).should.equal('-2.5'); + utils.toFixedMin(-2.44, 1).should.equal('-2.4'); + + utils.toFixedMin(undef, 2).should.equal('0'); + utils.toFixedMin(null, 2).should.equal('0'); + utils.toFixedMin('text', 2).should.equal('0'); + }); + it('merge date and time', function () { var result = utils.mergeInputTime('22:35', '2015-07-14'); result.hours().should.equal(22); diff --git a/views/adminindex.html b/views/adminindex.html index 8a0f97b2196..6108d1b3978 100644 --- a/views/adminindex.html +++ b/views/adminindex.html @@ -25,12 +25,17 @@ - - - - + + + + + + <% include preloadCSS %> + +
X
+

Nightscout

@@ -45,7 +50,7 @@

Admin Tools

Authentication status: - + diff --git a/views/bgclock.html b/views/bgclock.html deleted file mode 100644 index fdb90807ffe..00000000000 --- a/views/bgclock.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - - Nightscout - - - - - - - - - - - - - - - - - -
-
-
-
-
-
-
-
-
- - - - - - - diff --git a/views/clock-color.html b/views/clock-color.html deleted file mode 100644 index 06c0fb9ba82..00000000000 --- a/views/clock-color.html +++ /dev/null @@ -1,182 +0,0 @@ - - - - - - - Nightscout - - - - - - - - - - - - - - - - - -
-
-
-
-
-
-
-
-
- - - - - - - diff --git a/views/clock.html b/views/clock.html deleted file mode 100644 index c0ac35d64be..00000000000 --- a/views/clock.html +++ /dev/null @@ -1,132 +0,0 @@ - - - - - - - Nightscout - - - - - - - - - - - - - - - - - -
-
-
-
-
-
-
-
- - - - - - - - diff --git a/views/clockviews/bgclock.css b/views/clockviews/bgclock.css new file mode 100644 index 00000000000..6f97406a883 --- /dev/null +++ b/views/clockviews/bgclock.css @@ -0,0 +1,74 @@ +body { + text-align: center; + margin: 0 0; + padding: 0; + overflow: hidden; + font-family: 'Open Sans'; + color: grey; + background-color: black; +} + +main { + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; + height: 100vh; +} + +#close { + position: absolute; + top: 10px; + right: 10px; + color: #333; + border-radius: 5px; + border: 2px solid #333; + padding: 5px; + width: 20px; + height: 20px; +} + +.inner { + width: 100%; + -webkit-transform: translateY(-2%); +} + +#trend { + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; + justify-content: center; + -webkit-flex-direction: row; + flex-direction: row; +} + +#bgnow, #arrowDiv { + display: flex; + flex-grow: 0; + font-weight: 700; + font-size: 30vmin; + padding: 0 20px; + margin: 0; +} + +img#arrow { + height: 18vmin; + filter: brightness(50%); + -webkit-transform: translateY(5%); +} + +#clock { + font-weight: 700; + font-size: 25vmin; +} + +.stale { + text-decoration: line-through; +} \ No newline at end of file diff --git a/views/clockviews/clock-color.css b/views/clockviews/clock-color.css new file mode 100644 index 00000000000..3777a86a119 --- /dev/null +++ b/views/clockviews/clock-color.css @@ -0,0 +1,75 @@ +body { + text-align: center; + margin: 0 0; + padding: 0; + overflow: hidden; + font-family: 'Open Sans'; + color: white; + background-color: white; +} + +main { + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; + height: 100vh; +} + +#close { + position: absolute; + top: 10px; + right: 10px; + color: grey; + border-radius: 5px; + border: 2px solid grey; + padding: 5px; + width: 20px; + height: 20px; +} + +.inner { + width: 100%; + -webkit-transform: translateY(-5%); +} + +#bgnow { + font-weight: 700; + font-size: 40vmin; +} + +#trend { + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -ms-flex-align: center; + -webkit-align-items: center; + -webkit-transform: translateX(1%); + align-items: center; + justify-content: center; + -webkit-flex-direction: column; + flex-direction: column; +} + +#arrowDiv { + flex-grow: 1; + text-align: center; +} + +img#arrow { + height: 30vmin; +} + +#staleTime { + flex-grow: 1; + font-size: 6vmin; + display: none; +} + +#clock { + display: none; +} \ No newline at end of file diff --git a/views/clockviews/clock.css b/views/clockviews/clock.css new file mode 100644 index 00000000000..75b1b0cbafa --- /dev/null +++ b/views/clockviews/clock.css @@ -0,0 +1,66 @@ +body { + text-align: center; + margin: 0 0; + padding: 0; + overflow: hidden; + font-family: 'Open Sans'; + color: grey; + background-color: black; +} + +main { + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; + height: 100vh; +} + +#close { + position: absolute; + top: 10px; + right: 10px; + color: #333; + border-radius: 5px; + border: 2px solid #333; + padding: 5px; + width: 20px; + height: 20px; +} + +.inner { + width: 100%; + -webkit-transform: translateY(-5%); +} + +#bgnow { + font-weight: 700; + font-size: 40vmin; +} + +#trend { + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -ms-flex-align: center; + -webkit-align-items: center; + -webkit-transform: translateX(1%); + align-items: center; + justify-content: center; + -webkit-flex-direction: column; + flex-direction: column; +} + +#staleTime { + flex-grow: 1; + font-size: 6vmin; + display: none; +} + +#clock { + display: none; +} diff --git a/views/clockviews/shared.html b/views/clockviews/shared.html new file mode 100644 index 00000000000..f7d5f78cd25 --- /dev/null +++ b/views/clockviews/shared.html @@ -0,0 +1,47 @@ + + + + + + + Nightscout + + + + + + + + + + + + + + + + +
X
+
+
+
+
+
+
+
+
+
+ + + + + + + diff --git a/views/foodindex.html b/views/foodindex.html index ea0d153958f..d42eb16a50b 100644 --- a/views/foodindex.html +++ b/views/foodindex.html @@ -24,13 +24,19 @@ - - - - - + + + + + + <% include preloadCSS %> + + +
X
+ +
Status: Not loaded @@ -119,7 +125,7 @@

Food Editor

- + diff --git a/views/index.html b/views/index.html index 832437a05f2..cf13cdb91a7 100644 --- a/views/index.html +++ b/views/index.html @@ -27,9 +27,9 @@ - - - + + + - +<% include preloadCSS %>
@@ -116,7 +116,7 @@
-