From c5db286cdc59d32b61af9664d3c916b9bc486df9 Mon Sep 17 00:00:00 2001 From: Simon Laux Date: Sun, 2 Feb 2020 22:41:02 +0100 Subject: [PATCH 1/6] remove build folder from git --- .gitignore | 3 +++ build/custom-launcher.zip | Bin 264994 -> 0 bytes custom-launcher.min.json | 1 - metadata.json | 2 ++ 4 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 .gitignore delete mode 100755 build/custom-launcher.zip delete mode 100644 custom-launcher.min.json create mode 100644 metadata.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e13c8ee --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +node_modules +build +dist \ No newline at end of file diff --git a/build/custom-launcher.zip b/build/custom-launcher.zip deleted file mode 100755 index 5b4e0f9d82a8d17804a3e8e173884388f065fc65..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 264994 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 diff --git a/custom-launcher.min.json b/custom-launcher.min.json deleted file mode 100644 index c7fda89..0000000 --- a/custom-launcher.min.json +++ /dev/null @@ -1 +0,0 @@ -[{"app_name":"Telegram"},{"app_name":"Audio"},{"app_name":"Gallery"},{"app_name":"rss-reader"},{"app_name":"osm-map","dir":"outdoor"},{"app_name":"knots","dir":"outdoor"},{"app_name":"shellCMD","dir":"tools"},{"app_name":"Note","dir":"tools"},{"app_name":"Calendar"},{"sleep_mode":{"startTime":"23:30","duration_h":"8","duration_m":"0"}},{"weather":{"owm_api_key":"6d385b079ea964532d681348","location":{"biel":{"position_lat":"47.0","position_long":"7.0"},"prag":{"position_lat":"50.073658","position_long":"14.418540"}}}}] \ No newline at end of file diff --git a/metadata.json b/metadata.json new file mode 100644 index 0000000..357097d --- /dev/null +++ b/metadata.json @@ -0,0 +1,2 @@ +{"version": 1.0, "manifestURL": "app://custom.launcher.org/manifest.webapp"} + From c70cca308f9e8faffff1fe687995c1417f20842b Mon Sep 17 00:00:00 2001 From: Simon Laux Date: Mon, 3 Feb 2020 04:21:07 +0100 Subject: [PATCH 2/6] parcel --- .gitignore | 4 +- README.md | 9 +- package-lock.json | 8814 +++++++++++++++++ package.json | 25 + package_app.sh | 21 + {application => src}/assets/css/grid.css | 1 - {application => src}/assets/css/grid.min.css | 0 {application => src}/assets/css/main.css | 0 {application => src}/assets/css/main.min.css | 0 .../assets/js/Chart.bundle.js | 0 .../assets/js/applait.finder.min.js | 0 {application => src}/assets/js/client.min.js | 0 .../assets/js/jQuery-3.1.0.js | 0 {application => src}/assets/js/moments.min.js | 0 {application => src}/assets/js/script.js | 0 {application => src}/assets/js/script.min.js | 0 {application => src}/index.html | 2 +- .../icons/icon-112-112.png | Bin .../icons/icon-112-112.svg | 0 {application => static}/icons/icon-56-56.png | Bin {application => static}/icons/icon-56-56.svg | 0 {application => static}/manifest.webapp | 0 22 files changed, 8872 insertions(+), 4 deletions(-) create mode 100644 package-lock.json create mode 100644 package.json create mode 100755 package_app.sh rename {application => src}/assets/css/grid.css (99%) rename {application => src}/assets/css/grid.min.css (100%) rename {application => src}/assets/css/main.css (100%) rename {application => src}/assets/css/main.min.css (100%) rename {application => src}/assets/js/Chart.bundle.js (100%) rename {application => src}/assets/js/applait.finder.min.js (100%) rename {application => src}/assets/js/client.min.js (100%) rename {application => src}/assets/js/jQuery-3.1.0.js (100%) rename {application => src}/assets/js/moments.min.js (100%) rename {application => src}/assets/js/script.js (100%) rename {application => src}/assets/js/script.min.js (100%) rename {application => src}/index.html (97%) rename {application => static}/icons/icon-112-112.png (100%) rename {application => static}/icons/icon-112-112.svg (100%) rename {application => static}/icons/icon-56-56.png (100%) rename {application => static}/icons/icon-56-56.svg (100%) rename {application => static}/manifest.webapp (100%) diff --git a/.gitignore b/.gitignore index e13c8ee..12cdacf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ node_modules build -dist \ No newline at end of file +dist +.todo-ideas +.cache \ No newline at end of file diff --git a/README.md b/README.md index 1e20ff9..98b1cb7 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ custom-launcher ## Installation -1. download [/build/custom-launcher.zip](/build/custom-launcher.zip) +1. download [custom-launcher.zip](#) from the releases Page 2. copy in sdcard/downloads/ on your phone 3. installl the app with the GerdaOs Installer App. 4. Put on your sd card a file with the name custom-launcher.json with the following structure: @@ -100,3 +100,10 @@ You like the app and you have enough money [![](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=Q8QLA8CNMWAWG) +### Development + +Install dependencies: `npm i` (you need to have nodejs installed, we recommend using nvm (Node Version Manager)) + +- Build application, installable with webide: `npm run build` +- Test application in system browser (experimental): `npm run watch` +- Package application for releasing or installation with OmniSD \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..134a1f2 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,8814 @@ +{ + "name": "kaios-custom-launcher", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/compat-data": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.8.5.tgz", + "integrity": "sha512-jWYUqQX/ObOhG1UiEkbH5SANsE/8oKXiQWjj7p7xgj9Zmnt//aUvyz4dBkK0HNsS8/cbyC5NmmH87VekW+mXFg==", + "dev": true, + "requires": { + "browserslist": "^4.8.5", + "invariant": "^2.2.4", + "semver": "^5.5.0" + } + }, + "@babel/core": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.4.tgz", + "integrity": "sha512-0LiLrB2PwrVI+a2/IEskBopDYSd8BCb3rOvH7D5tzoWd696TBEduBvuLVm4Nx6rltrLZqvI3MCalB2K2aVzQjA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.4", + "@babel/helpers": "^7.8.4", + "@babel/parser": "^7.8.4", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.4", + "@babel/types": "^7.8.3", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.0", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "json5": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", + "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz", + "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz", + "integrity": "sha512-6o+mJrZBxOoEX77Ezv9zwW7WV8DdluouRKNY/IR5u/YTMuKHgugHOzYWlYvYLpLA9nPsQCAAASpCIbjI9Mv+Uw==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.8.3.tgz", + "integrity": "sha512-5eFOm2SyFPK4Rh3XMMRDjN7lBH0orh3ss0g3rTYZnBQ+r6YPj7lgDyCvPphynHvUrobJmeMignBr6Acw9mAPlw==", + "dev": true, + "requires": { + "@babel/helper-explode-assignable-expression": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-builder-react-jsx": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.8.3.tgz", + "integrity": "sha512-JT8mfnpTkKNCboTqZsQTdGo3l3Ik3l7QIt9hh0O9DYiwVel37VoJpILKM4YFbP2euF32nkQSb+F9cUk9b7DDXQ==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3", + "esutils": "^2.0.0" + } + }, + "@babel/helper-call-delegate": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.8.3.tgz", + "integrity": "sha512-6Q05px0Eb+N4/GTyKPPvnkig7Lylw+QzihMpws9iiZQv7ZImf84ZsZpQH7QoWN4n4tm81SnSzPgHw2qtO0Zf3A==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.4.tgz", + "integrity": "sha512-3k3BsKMvPp5bjxgMdrFyq0UaEO48HciVrOVF0+lon8pp95cyJ2ujAh0TrBHNMnJGT2rr0iKOJPFFbSqjDyf/Pg==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.8.4", + "browserslist": "^4.8.5", + "invariant": "^2.2.4", + "levenary": "^1.1.1", + "semver": "^5.5.0" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.3.tgz", + "integrity": "sha512-Gcsm1OHCUr9o9TcJln57xhWHtdXbA2pgQ58S0Lxlks0WMGNXuki4+GLfX0p+L2ZkINUGZvfkz8rzoqJQSthI+Q==", + "dev": true, + "requires": { + "@babel/helper-regex": "^7.8.3", + "regexpu-core": "^4.6.0" + } + }, + "@babel/helper-define-map": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.8.3.tgz", + "integrity": "sha512-PoeBYtxoZGtct3md6xZOCWPcKuMuk3IHhgxsRRNtnNShebf4C8YonTSblsK4tvDbm+eJAw2HAPOfCr+Q/YRG/g==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.8.3", + "@babel/types": "^7.8.3", + "lodash": "^4.17.13" + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.8.3.tgz", + "integrity": "sha512-N+8eW86/Kj147bO9G2uclsg5pwfs/fqqY5rwgIL7eTBklgXjcOJ3btzS5iM6AitJcftnY7pm2lGsrJVYLGjzIw==", + "dev": true, + "requires": { + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.8.3.tgz", + "integrity": "sha512-ky1JLOjcDUtSc+xkt0xhYff7Z6ILTAHKmZLHPxAhOP0Nd77O+3nCsd6uSVYur6nJnCI029CrNbYlc0LoPfAPQg==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz", + "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-module-imports": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz", + "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-module-transforms": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.8.3.tgz", + "integrity": "sha512-C7NG6B7vfBa/pwCOshpMbOYUmrYQDfCpVL/JCRu0ek8B5p8kue1+BCXpg2vOYs7w5ACB9GTOBYQ5U6NwrMg+3Q==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-simple-access": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3", + "lodash": "^4.17.13" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", + "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + }, + "@babel/helper-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.8.3.tgz", + "integrity": "sha512-BWt0QtYv/cg/NecOAZMdcn/waj/5P26DR4mVLXfFtDokSR6fyuG0Pj+e2FqtSME+MqED1khnSMulkmGl8qWiUQ==", + "dev": true, + "requires": { + "lodash": "^4.17.13" + } + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.8.3.tgz", + "integrity": "sha512-kgwDmw4fCg7AVgS4DukQR/roGp+jP+XluJE5hsRZwxCYGg+Rv9wSGErDWhlI90FODdYfd4xG4AQRiMDjjN0GzA==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-wrap-function": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-replace-supers": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.8.3.tgz", + "integrity": "sha512-xOUssL6ho41U81etpLoT2RTdvdus4VfHamCuAm4AHxGr+0it5fnwoVdwUJ7GFEqCsQYzJUhcbsN9wB9apcYKFA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-simple-access": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", + "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", + "dev": true, + "requires": { + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-wrap-function": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz", + "integrity": "sha512-LACJrbUET9cQDzb6kG7EeD7+7doC3JNvUgTEQOx2qaO1fKlzE/Bf05qs9w1oXQMmXlPO65lC3Tq9S6gZpTErEQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helpers": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.4.tgz", + "integrity": "sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==", + "dev": true, + "requires": { + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.4", + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", + "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", + "dev": true + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.8.3.tgz", + "integrity": "sha512-NZ9zLv848JsV3hs8ryEh7Uaz/0KsmPLqv0+PdkDJL1cJy0K4kOCFa8zc1E3mp+RHPQcpdfb/6GovEsW4VDrOMw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-remap-async-to-generator": "^7.8.3", + "@babel/plugin-syntax-async-generators": "^7.8.0" + } + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.8.3.tgz", + "integrity": "sha512-NyaBbyLFXFLT9FP+zk0kYlUlA8XtCUbehs67F0nnEg7KICgMc2mNkIeu9TYhKzyXMkrapZFwAhXLdnt4IYHy1w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-dynamic-import": "^7.8.0" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.8.3.tgz", + "integrity": "sha512-KGhQNZ3TVCQG/MjRbAUwuH+14y9q0tpxs1nWWs3pbSleRdDro9SAMMDyye8HhY1gqZ7/NqIc8SKhya0wRDgP1Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.0" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-8qvuPwU/xxUCt78HocNlv0mXXo0wdh9VT1R04WU8HGOfaOob26pF+9P5/lYjN/q7DHOX1bvX60hnhOvuQUJdbA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-0gkX7J7E+AtAw9fcwlVQj8peP61qhdg/89D5swOkjYbkboA2CVckn3kiyum1DE0wskGb7KJJxBdyEBApDLLVdw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.8.3.tgz", + "integrity": "sha512-QIoIR9abkVn+seDE3OjA08jWcs3eZ9+wJCKSRgo3WdEU2csFYgdScb+8qHB3+WXsGJD55u+5hWCISI7ejXS+kg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.0" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.3.tgz", + "integrity": "sha512-1/1/rEZv2XGweRwwSkLpY+s60za9OZ1hJs4YDqFHCw0kYWYwL5IFljVY1MYBL+weT1l9pokDO2uhSTLVxzoHkQ==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-flow": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.8.3.tgz", + "integrity": "sha512-innAx3bUbA0KSYj2E2MNFSn9hiCeowOFLxlsuhXzw8hMQnzkDomUr9QCD7E9VF60NmnG1sNTuuv6Qf4f8INYsg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.8.3.tgz", + "integrity": "sha512-WxdW9xyLgBdefoo0Ynn3MRSkhe5tFVxxKNVdnZSh318WrG2e2jH+E9wd/++JsqcLJZPfz87njQJ8j2Upjm0M0A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.8.3.tgz", + "integrity": "sha512-kwj1j9lL/6Wd0hROD3b/OZZ7MSrZLqqn9RAZ5+cYYsflQ9HZBIKCUkr3+uL1MEJ1NePiUbf98jjiMQSv0NMR9g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz", + "integrity": "sha512-0MRF+KC8EqH4dbuITCWwPSzsyO3HIWWlm30v8BbbpOrS1B++isGxPnnuq/IZvOX5J2D/p7DQalQm+/2PnlKGxg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.8.3.tgz", + "integrity": "sha512-imt9tFLD9ogt56Dd5CI/6XgpukMwd/fLGSrix2httihVe7LOGVPhyhMh1BU5kDM7iHD08i8uUtmV2sWaBFlHVQ==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-remap-async-to-generator": "^7.8.3" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.8.3.tgz", + "integrity": "sha512-vo4F2OewqjbB1+yaJ7k2EJFHlTP3jR634Z9Cj9itpqNjuLXvhlVxgnjsHsdRgASR8xYDrx6onw4vW5H6We0Jmg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.8.3.tgz", + "integrity": "sha512-pGnYfm7RNRgYRi7bids5bHluENHqJhrV4bCZRwc5GamaWIIs07N4rZECcmJL6ZClwjDz1GbdMZFtPs27hTB06w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "lodash": "^4.17.13" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.8.3.tgz", + "integrity": "sha512-SjT0cwFJ+7Rbr1vQsvphAHwUHvSUPmMjMU/0P59G8U2HLFqSa082JO7zkbDNWs9kH/IUqpHI6xWNesGf8haF1w==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-define-map": "^7.8.3", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.8.3.tgz", + "integrity": "sha512-O5hiIpSyOGdrQZRQ2ccwtTVkgUDBBiCuK//4RJ6UfePllUTCENOzKxfh6ulckXKc0DixTFLCfb2HVkNA7aDpzA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.8.3.tgz", + "integrity": "sha512-H4X646nCkiEcHZUZaRkhE2XVsoz0J/1x3VVujnn96pSoGCtKPA99ZZA+va+gK+92Zycd6OBKCD8tDb/731bhgQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.8.3.tgz", + "integrity": "sha512-kLs1j9Nn4MQoBYdRXH6AeaXMbEJFaFu/v1nQkvib6QzTj8MZI5OQzqmD83/2jEM1z0DLilra5aWO5YpyC0ALIw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.8.3.tgz", + "integrity": "sha512-s8dHiBUbcbSgipS4SMFuWGqCvyge5V2ZeAWzR6INTVC3Ltjig/Vw1G2Gztv0vU/hRG9X8IvKvYdoksnUfgXOEQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.8.3.tgz", + "integrity": "sha512-zwIpuIymb3ACcInbksHaNcR12S++0MDLKkiqXHl3AzpgdKlFNhog+z/K0+TGW+b0w5pgTq4H6IwV/WhxbGYSjQ==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-flow-strip-types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.8.3.tgz", + "integrity": "sha512-g/6WTWG/xbdd2exBBzMfygjX/zw4eyNC4X8pRaq7aRHRoDUCzAIu3kGYIXviOv8BjCuWm8vDBwjHcjiRNgXrPA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-flow": "^7.8.3" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.8.4.tgz", + "integrity": "sha512-iAXNlOWvcYUYoV8YIxwS7TxGRJcxyl8eQCfT+A5j8sKUzRFvJdcyjp97jL2IghWSRDaL2PU2O2tX8Cu9dTBq5A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.8.3.tgz", + "integrity": "sha512-rO/OnDS78Eifbjn5Py9v8y0aR+aSYhDhqAwVfsTl0ERuMZyr05L1aFSCJnbv2mmsLkit/4ReeQ9N2BgLnOcPCQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.8.3.tgz", + "integrity": "sha512-3Tqf8JJ/qB7TeldGl+TT55+uQei9JfYaregDcEAyBZ7akutriFrt6C/wLYIer6OYhleVQvH/ntEhjE/xMmy10A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.8.3.tgz", + "integrity": "sha512-3Wk2EXhnw+rP+IDkK6BdtPKsUE5IeZ6QOGrPYvw52NwBStw9V1ZVzxgK6fSKSxqUvH9eQPR3tm3cOq79HlsKYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.8.3.tgz", + "integrity": "sha512-MadJiU3rLKclzT5kBH4yxdry96odTUwuqrZM+GllFI/VhxfPz+k9MshJM+MwhfkCdxxclSbSBbUGciBngR+kEQ==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "babel-plugin-dynamic-import-node": "^2.3.0" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.8.3.tgz", + "integrity": "sha512-JpdMEfA15HZ/1gNuB9XEDlZM1h/gF/YOH7zaZzQu2xCFRfwc01NXBMHHSTT6hRjlXJJs5x/bfODM3LiCk94Sxg==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-simple-access": "^7.8.3", + "babel-plugin-dynamic-import-node": "^2.3.0" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.8.3.tgz", + "integrity": "sha512-8cESMCJjmArMYqa9AO5YuMEkE4ds28tMpZcGZB/jl3n0ZzlsxOAi3mC+SKypTfT8gjMupCnd3YiXCkMjj2jfOg==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.8.3", + "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "babel-plugin-dynamic-import-node": "^2.3.0" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.8.3.tgz", + "integrity": "sha512-evhTyWhbwbI3/U6dZAnx/ePoV7H6OUG+OjiJFHmhr9FPn0VShjwC2kdxqIuQ/+1P50TMrneGzMeyMTFOjKSnAw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz", + "integrity": "sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.8.3.tgz", + "integrity": "sha512-QuSGysibQpyxexRyui2vca+Cmbljo8bcRckgzYV4kRIsHpVeyeC3JDO63pY+xFZ6bWOBn7pfKZTqV4o/ix9sFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.8.3.tgz", + "integrity": "sha512-57FXk+gItG/GejofIyLIgBKTas4+pEU47IXKDBWFTxdPd7F80H8zybyAY7UoblVfBhBGs2EKM+bJUu2+iUYPDQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.3" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.8.4.tgz", + "integrity": "sha512-IsS3oTxeTsZlE5KqzTbcC2sV0P9pXdec53SU+Yxv7o/6dvGM5AkTotQKhoSffhNgZ/dftsSiOoxy7evCYJXzVA==", + "dev": true, + "requires": { + "@babel/helper-call-delegate": "^7.8.3", + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.8.3.tgz", + "integrity": "sha512-uGiiXAZMqEoQhRWMK17VospMZh5sXWg+dlh2soffpkAl96KAm+WZuJfa6lcELotSRmooLqg0MWdH6UUq85nmmg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-react-jsx": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.8.3.tgz", + "integrity": "sha512-r0h+mUiyL595ikykci+fbwm9YzmuOrUBi0b+FDIKmi3fPQyFokWVEMJnRWHJPPQEjyFJyna9WZC6Viv6UHSv1g==", + "dev": true, + "requires": { + "@babel/helper-builder-react-jsx": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-jsx": "^7.8.3" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.3.tgz", + "integrity": "sha512-qt/kcur/FxrQrzFR432FGZznkVAjiyFtCOANjkAKwCbt465L6ZCiUQh2oMYGU3Wo8LRFJxNDFwWn106S5wVUNA==", + "dev": true, + "requires": { + "regenerator-transform": "^0.14.0" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.8.3.tgz", + "integrity": "sha512-mwMxcycN3omKFDjDQUl+8zyMsBfjRFr0Zn/64I41pmjv4NJuqcYlEtezwYtw9TFd9WR1vN5kiM+O0gMZzO6L0A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.8.3.tgz", + "integrity": "sha512-I9DI6Odg0JJwxCHzbzW08ggMdCezoWcuQRz3ptdudgwaHxTjxw5HgdFJmZIkIMlRymL6YiZcped4TTCB0JcC8w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.8.3.tgz", + "integrity": "sha512-CkuTU9mbmAoFOI1tklFWYYbzX5qCIZVXPVy0jpXgGwkplCndQAa58s2jr66fTeQnA64bDox0HL4U56CFYoyC7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.8.3.tgz", + "integrity": "sha512-9Spq0vGCD5Bb4Z/ZXXSK5wbbLFMG085qd2vhL1JYu1WcQ5bXqZBAYRzU1d+p79GcHs2szYv5pVQCX13QgldaWw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-regex": "^7.8.3" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.8.3.tgz", + "integrity": "sha512-820QBtykIQOLFT8NZOcTRJ1UNuztIELe4p9DCgvj4NK+PwluSJ49we7s9FB1HIGNIYT7wFUJ0ar2QpCDj0escQ==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.8.4.tgz", + "integrity": "sha512-2QKyfjGdvuNfHsb7qnBBlKclbD4CfshH2KvDabiijLMGXPHJXGxtDzwIF7bQP+T0ysw8fYTtxPafgfs/c1Lrqg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.8.3.tgz", + "integrity": "sha512-+ufgJjYdmWfSQ+6NS9VGUR2ns8cjJjYbrbi11mZBTaWm+Fui/ncTLFF28Ei1okavY+xkojGr1eJxNsWYeA5aZw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/preset-env": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.8.4.tgz", + "integrity": "sha512-HihCgpr45AnSOHRbS5cWNTINs0TwaR8BS8xIIH+QwiW8cKL0llV91njQMpeMReEPVs+1Ao0x3RLEBLtt1hOq4w==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.8.4", + "@babel/helper-compilation-targets": "^7.8.4", + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-proposal-async-generator-functions": "^7.8.3", + "@babel/plugin-proposal-dynamic-import": "^7.8.3", + "@babel/plugin-proposal-json-strings": "^7.8.3", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-proposal-object-rest-spread": "^7.8.3", + "@babel/plugin-proposal-optional-catch-binding": "^7.8.3", + "@babel/plugin-proposal-optional-chaining": "^7.8.3", + "@babel/plugin-proposal-unicode-property-regex": "^7.8.3", + "@babel/plugin-syntax-async-generators": "^7.8.0", + "@babel/plugin-syntax-dynamic-import": "^7.8.0", + "@babel/plugin-syntax-json-strings": "^7.8.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.0", + "@babel/plugin-syntax-top-level-await": "^7.8.3", + "@babel/plugin-transform-arrow-functions": "^7.8.3", + "@babel/plugin-transform-async-to-generator": "^7.8.3", + "@babel/plugin-transform-block-scoped-functions": "^7.8.3", + "@babel/plugin-transform-block-scoping": "^7.8.3", + "@babel/plugin-transform-classes": "^7.8.3", + "@babel/plugin-transform-computed-properties": "^7.8.3", + "@babel/plugin-transform-destructuring": "^7.8.3", + "@babel/plugin-transform-dotall-regex": "^7.8.3", + "@babel/plugin-transform-duplicate-keys": "^7.8.3", + "@babel/plugin-transform-exponentiation-operator": "^7.8.3", + "@babel/plugin-transform-for-of": "^7.8.4", + "@babel/plugin-transform-function-name": "^7.8.3", + "@babel/plugin-transform-literals": "^7.8.3", + "@babel/plugin-transform-member-expression-literals": "^7.8.3", + "@babel/plugin-transform-modules-amd": "^7.8.3", + "@babel/plugin-transform-modules-commonjs": "^7.8.3", + "@babel/plugin-transform-modules-systemjs": "^7.8.3", + "@babel/plugin-transform-modules-umd": "^7.8.3", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3", + "@babel/plugin-transform-new-target": "^7.8.3", + "@babel/plugin-transform-object-super": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.8.4", + "@babel/plugin-transform-property-literals": "^7.8.3", + "@babel/plugin-transform-regenerator": "^7.8.3", + "@babel/plugin-transform-reserved-words": "^7.8.3", + "@babel/plugin-transform-shorthand-properties": "^7.8.3", + "@babel/plugin-transform-spread": "^7.8.3", + "@babel/plugin-transform-sticky-regex": "^7.8.3", + "@babel/plugin-transform-template-literals": "^7.8.3", + "@babel/plugin-transform-typeof-symbol": "^7.8.4", + "@babel/plugin-transform-unicode-regex": "^7.8.3", + "@babel/types": "^7.8.3", + "browserslist": "^4.8.5", + "core-js-compat": "^3.6.2", + "invariant": "^2.2.2", + "levenary": "^1.1.1", + "semver": "^5.5.0" + } + }, + "@babel/runtime": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.4.tgz", + "integrity": "sha512-neAp3zt80trRVBI1x0azq6c57aNBqYZH8KhMm3TaB7wEI5Q4A2SHfBHE8w9gOhI/lrqxtEbXZgQIrHP+wvSGwQ==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.2" + } + }, + "@babel/template": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", + "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/traverse": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz", + "integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.4", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.8.4", + "@babel/types": "^7.8.3", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "@iarna/toml": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.3.tgz", + "integrity": "sha512-FmuxfCuolpLl0AnQ2NHSzoUKWEJDFl63qXjzdoWBVyFCXzMGm1spBzk7LeHNoVCiWCF7mRVms9e6jEV9+MoPbg==", + "dev": true + }, + "@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "dev": true, + "requires": { + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" + } + }, + "@nodelib/fs.stat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "dev": true + }, + "@parcel/fs": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@parcel/fs/-/fs-1.11.0.tgz", + "integrity": "sha512-86RyEqULbbVoeo8OLcv+LQ1Vq2PKBAvWTU9fCgALxuCTbbs5Ppcvll4Vr+Ko1AnmMzja/k++SzNAwJfeQXVlpA==", + "dev": true, + "requires": { + "@parcel/utils": "^1.11.0", + "mkdirp": "^0.5.1", + "rimraf": "^2.6.2" + } + }, + "@parcel/logger": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@parcel/logger/-/logger-1.11.1.tgz", + "integrity": "sha512-9NF3M6UVeP2udOBDILuoEHd8VrF4vQqoWHEafymO1pfSoOMfxrSJZw1MfyAAIUN/IFp9qjcpDCUbDZB+ioVevA==", + "dev": true, + "requires": { + "@parcel/workers": "^1.11.0", + "chalk": "^2.1.0", + "grapheme-breaker": "^0.3.2", + "ora": "^2.1.0", + "strip-ansi": "^4.0.0" + } + }, + "@parcel/utils": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@parcel/utils/-/utils-1.11.0.tgz", + "integrity": "sha512-cA3p4jTlaMeOtAKR/6AadanOPvKeg8VwgnHhOyfi0yClD0TZS/hi9xu12w4EzA/8NtHu0g6o4RDfcNjqN8l1AQ==", + "dev": true + }, + "@parcel/watcher": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-1.12.1.tgz", + "integrity": "sha512-od+uCtCxC/KoNQAIE1vWx1YTyKYY+7CTrxBJPRh3cDWw/C0tCtlBMVlrbplscGoEpt6B27KhJDCv82PBxOERNA==", + "dev": true, + "requires": { + "@parcel/utils": "^1.11.0", + "chokidar": "^2.1.5" + } + }, + "@parcel/workers": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@parcel/workers/-/workers-1.11.0.tgz", + "integrity": "sha512-USSjRAAQYsZFlv43FUPdD+jEGML5/8oLF0rUzPQTtK4q9kvaXr49F5ZplyLz5lox78cLZ0TxN2bIDQ1xhOkulQ==", + "dev": true, + "requires": { + "@parcel/utils": "^1.11.0", + "physical-cpu-count": "^2.0.0" + } + }, + "@types/q": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz", + "integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==", + "dev": true + }, + "abab": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", + "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==", + "dev": true + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "acorn": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", + "dev": true + }, + "acorn-globals": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", + "dev": true, + "requires": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + }, + "dependencies": { + "acorn": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.0.tgz", + "integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==", + "dev": true + } + } + }, + "acorn-walk": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", + "dev": true + }, + "adm-zip": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.13.tgz", + "integrity": "sha512-fERNJX8sOXfel6qCBCMPvZLzENBEhZTzKqg6vrOW5pvoEaQuJhRU4ndTAh6lHOxn1I6jnz2NHra56ZODM751uw==", + "dev": true + }, + "ajv": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz", + "integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", + "dev": true + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "ansi-to-html": { + "version": "0.6.13", + "resolved": "https://registry.npmjs.org/ansi-to-html/-/ansi-to-html-0.6.13.tgz", + "integrity": "sha512-Ys2/umuaTlQvP9DLkaa7UzRKF2FLrfod/hNHXS9QhXCrw7seObG6ksOGmNz3UoK+adwM8L9vQfG7mvaxfJ3Jvw==", + "dev": true, + "requires": { + "entities": "^1.1.2" + } + }, + "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" + } + } + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "dev": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-differ": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", + "dev": true + }, + "array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "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", + "minimalistic-assert": "^1.0.0" + } + }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dev": true, + "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 + }, + "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" + } + } + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true + }, + "async-foreach": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", + "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=", + "dev": true + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "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 + }, + "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=", + "dev": true + }, + "aws4": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", + "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==", + "dev": true + }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", + "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", + "dev": true, + "requires": { + "object.assign": "^4.1.0" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + } + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + }, + "dependencies": { + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true + } + } + }, + "babylon-walk": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/babylon-walk/-/babylon-walk-1.0.2.tgz", + "integrity": "sha1-OxWl3btIKni0zpwByLoYFwLZ1s4=", + "dev": true, + "requires": { + "babel-runtime": "^6.11.6", + "babel-types": "^6.15.0", + "lodash.clone": "^4.5.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "dev": true, + "requires": { + "inherits": "~2.0.0" + } + }, + "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 + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "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" + } + } + } + }, + "brfs": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/brfs/-/brfs-1.6.1.tgz", + "integrity": "sha512-OfZpABRQQf+Xsmju8XE9bDjs+uU4vLREGolP7bDgcpsI17QREyZ4Bl+2KLxxx1kCgA0fAIhKQBaBYh+PEcCqYQ==", + "dev": true, + "requires": { + "quote-stream": "^1.0.1", + "resolve": "^1.1.5", + "static-module": "^2.2.0", + "through2": "^2.0.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==", + "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==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.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", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "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", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "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" + } + }, + "browserify-sign": { + "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", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" + } + }, + "browserify-zlib": { + "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" + }, + "dependencies": { + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + } + } + }, + "browserslist": { + "version": "4.8.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.6.tgz", + "integrity": "sha512-ZHao85gf0eZ0ESxLfCp73GG9O/VTytYDIkIiZDlURppLTI9wErSM/5yAKEq6rcUdxBLjMELmrYUJGg5sxGKMHg==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001023", + "electron-to-chromium": "^1.3.341", + "node-releases": "^1.1.47" + } + }, + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-equal": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", + "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "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 + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", + "dev": true + }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "dev": true, + "requires": { + "callsites": "^2.0.0" + } + }, + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "dev": true, + "requires": { + "caller-callsite": "^2.0.0" + } + }, + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + } + } + }, + "caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "caniuse-lite": { + "version": "1.0.30001023", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001023.tgz", + "integrity": "sha512-C5TDMiYG11EOhVOA62W1p3UsJ2z4DsHtMBQtjzp3ZsUglcQn62WOUgW0y795c7A5uZ+GCEIvzkMatLIlAsbNTA==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "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" + } + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "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" + } + }, + "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" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cli-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-spinners": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.3.1.tgz", + "integrity": "sha512-1QL4544moEsDVH9T/l6Cemov/37iv1RtoKf7NJ04A60+4MREXNfx/QvavbH6QoGdsD4N4Mwy49cmaINR/o2mdg==", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "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 + }, + "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" + } + } + } + }, + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true + }, + "coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "dev": true, + "requires": { + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + } + }, + "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=", + "dev": true + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz", + "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==", + "dev": true, + "requires": { + "color-convert": "^1.9.1", + "color-string": "^1.5.2" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "color-string": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", + "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "dev": true, + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "command-exists": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.8.tgz", + "integrity": "sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw==", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, + "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 + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", + "dev": true + }, + "core-js-compat": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.4.tgz", + "integrity": "sha512-zAa3IZPvsJ0slViBQ2z+vgyyTuhd3MFn1rBQjZSKVEgB0UMYhUkCj9jJUVPgGTGqWvsBVmfnruXgTcNyTlEiSA==", + "dev": true, + "requires": { + "browserslist": "^4.8.3", + "semver": "7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true + } + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + } + }, + "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", + "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", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "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", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "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", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", + "dev": true + }, + "css-declaration-sorter": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", + "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", + "dev": true, + "requires": { + "postcss": "^7.0.1", + "timsort": "^0.3.0" + } + }, + "css-modules-loader-core": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/css-modules-loader-core/-/css-modules-loader-core-1.1.0.tgz", + "integrity": "sha1-WQhmgpShvs0mGuCkziGwtVHyHRY=", + "dev": true, + "requires": { + "icss-replace-symbols": "1.1.0", + "postcss": "6.0.1", + "postcss-modules-extract-imports": "1.1.0", + "postcss-modules-local-by-default": "1.2.0", + "postcss-modules-scope": "1.1.0", + "postcss-modules-values": "1.3.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "dependencies": { + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "postcss": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.1.tgz", + "integrity": "sha1-AA29H47vIXqjaLmiEsX8QLKo8/I=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "source-map": "^0.5.6", + "supports-color": "^3.2.3" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "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" + } + } + } + }, + "css-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^3.2.1", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", + "dev": true + }, + "css-selector-tokenizer": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.1.tgz", + "integrity": "sha512-xYL0AMZJ4gFzJQsHUKa5jiWWi2vH77WVNg7JYRyewwj6oPh4yb/y6Y9ZCw9dsj/9UauMhtuxR+ogQd//EdEVNA==", + "dev": true, + "requires": { + "cssesc": "^0.1.0", + "fastparse": "^1.1.1", + "regexpu-core": "^1.0.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + }, + "regexpu-core": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", + "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", + "dev": true, + "requires": { + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + }, + "regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", + "dev": true + }, + "regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + } + } + } + }, + "css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "dev": true, + "requires": { + "mdn-data": "2.0.4", + "source-map": "^0.6.1" + } + }, + "css-unit-converter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.1.tgz", + "integrity": "sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY=", + "dev": true + }, + "css-what": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.2.1.tgz", + "integrity": "sha512-WwOrosiQTvyms+Ti5ZC5vGEK0Vod3FTt1ca+payZqvKuGJF+dq7bG63DstxtN0dpm6FxY27a/zS3Wten+gEtGw==", + "dev": true + }, + "cssesc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz", + "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=", + "dev": true + }, + "cssnano": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz", + "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==", + "dev": true, + "requires": { + "cosmiconfig": "^5.0.0", + "cssnano-preset-default": "^4.0.7", + "is-resolvable": "^1.0.0", + "postcss": "^7.0.0" + } + }, + "cssnano-preset-default": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz", + "integrity": "sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==", + "dev": true, + "requires": { + "css-declaration-sorter": "^4.0.1", + "cssnano-util-raw-cache": "^4.0.1", + "postcss": "^7.0.0", + "postcss-calc": "^7.0.1", + "postcss-colormin": "^4.0.3", + "postcss-convert-values": "^4.0.1", + "postcss-discard-comments": "^4.0.2", + "postcss-discard-duplicates": "^4.0.2", + "postcss-discard-empty": "^4.0.1", + "postcss-discard-overridden": "^4.0.1", + "postcss-merge-longhand": "^4.0.11", + "postcss-merge-rules": "^4.0.3", + "postcss-minify-font-values": "^4.0.2", + "postcss-minify-gradients": "^4.0.2", + "postcss-minify-params": "^4.0.2", + "postcss-minify-selectors": "^4.0.2", + "postcss-normalize-charset": "^4.0.1", + "postcss-normalize-display-values": "^4.0.2", + "postcss-normalize-positions": "^4.0.2", + "postcss-normalize-repeat-style": "^4.0.2", + "postcss-normalize-string": "^4.0.2", + "postcss-normalize-timing-functions": "^4.0.2", + "postcss-normalize-unicode": "^4.0.1", + "postcss-normalize-url": "^4.0.1", + "postcss-normalize-whitespace": "^4.0.2", + "postcss-ordered-values": "^4.1.2", + "postcss-reduce-initial": "^4.0.3", + "postcss-reduce-transforms": "^4.0.2", + "postcss-svgo": "^4.0.2", + "postcss-unique-selectors": "^4.0.1" + } + }, + "cssnano-util-get-arguments": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", + "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=", + "dev": true + }, + "cssnano-util-get-match": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", + "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=", + "dev": true + }, + "cssnano-util-raw-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", + "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "cssnano-util-same-parent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", + "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==", + "dev": true + }, + "csso": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.2.tgz", + "integrity": "sha512-kS7/oeNVXkHWxby5tHVxlhjizRCSv8QdU7hB2FpdAibDU8FjTAolhNjKNTiLzXtUrKT6HwClE81yXwEk1309wg==", + "dev": true, + "requires": { + "css-tree": "1.0.0-alpha.37" + } + }, + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "cssstyle": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", + "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", + "dev": true, + "requires": { + "cssom": "0.3.x" + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + } + }, + "deasync": { + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/deasync/-/deasync-0.1.19.tgz", + "integrity": "sha512-oh3MRktfnPlLysCPpBpKZZzb4cUC/p0aA3SyRGp15lN30juJBTo/CiD0d4fR+f1kBtUQoJj1NE9RPNWQ7BQ9Mg==", + "dev": true, + "requires": { + "bindings": "^1.5.0", + "node-addon-api": "^1.7.1" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "requires": { + "clone": "^1.0.2" + }, + "dependencies": { + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + } + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "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==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "requires": { + "globby": "^5.0.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "rimraf": "^2.2.8" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "diffie-hellman": { + "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", + "randombytes": "^2.0.0" + } + }, + "dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + }, + "dependencies": { + "domelementtype": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", + "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==", + "dev": true + }, + "entities": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", + "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==", + "dev": true + } + } + }, + "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 + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "dev": true, + "requires": { + "webidl-conversions": "^4.0.2" + } + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "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" + } + }, + "dotenv": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-5.0.1.tgz", + "integrity": "sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow==", + "dev": true + }, + "dotenv-expand": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", + "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", + "dev": true + }, + "duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", + "dev": true + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "electron-to-chromium": { + "version": "1.3.344", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.344.tgz", + "integrity": "sha512-tvbx2Wl8WBR+ym3u492D0L6/jH+8NoQXqe46+QhbWH3voVPauGuZYeb1QAXYoOAWuiP2dbSvlBx0kQ1F3hu/Mw==", + "dev": true + }, + "elliptic": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", + "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==", + "dev": true, + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "emitter-mixin": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/emitter-mixin/-/emitter-mixin-0.0.3.tgz", + "integrity": "sha1-WUjLKG8uSO3DslGnz8H3iDOW1lw=", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, + "envinfo": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.5.0.tgz", + "integrity": "sha512-jDgnJaF/Btomk+m3PZDTTCb5XIIIX3zYItnCRfF73zVgvinLoRomuhi75Y4su0PtQxWz4v66XnLLckyvyJTOIQ==", + "dev": true + }, + "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" + } + }, + "es-abstract": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", + "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + }, + "dependencies": { + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + } + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "escodegen": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.1.tgz", + "integrity": "sha512-6hTjO1NAWkHnDk3OqQ4YrCuwwmGHL9S3nPlzBOUG/R44rda3wLNrfvQ5fkSGjyhHFKM7ALPKcKGrwvCLe0lC7Q==", + "dev": true, + "requires": { + "esprima": "^3.1.3", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "dev": true + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, + "events": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", + "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", + "dev": true + }, + "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" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "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" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "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-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "falafel": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/falafel/-/falafel-2.1.0.tgz", + "integrity": "sha1-lrsXdh2rqU9G0AFzizzt86Z/4Gw=", + "dev": true, + "requires": { + "acorn": "^5.0.0", + "foreach": "^2.0.5", + "isarray": "0.0.1", + "object-keys": "^1.0.6" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + } + } + }, + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "dev": true + }, + "fast-glob": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "dev": true, + "requires": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fastparse": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", + "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", + "dev": true + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true + }, + "filesize": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz", + "integrity": "sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==", + "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, + "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" + } + } + } + }, + "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" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "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==", + "dev": true, + "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=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.11.tgz", + "integrity": "sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw==", + "dev": true, + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1", + "node-pre-gyp": "*" + }, + "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.3", + "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": "3.2.6", + "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.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "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.6", + "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.3", + "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.4", + "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.9.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.14.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.4.2" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.7", + "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.1", + "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.7.1", + "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.1", + "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.13", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "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.1.1", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": 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" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "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=", + "dev": true, + "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=", + "dev": true, + "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=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "gaze": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", + "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", + "dev": true, + "requires": { + "globule": "^1.0.0" + } + }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "dev": true + }, + "get-caller-file": { + "version": "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 + }, + "get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=", + "dev": true + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "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=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "glob-to-regexp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", + "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", + "dev": true + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "globule": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.0.tgz", + "integrity": "sha512-YlD4kdMqRCQHrhVdonet4TdRtv1/sZKepvoxNT4Nrhrp5HI8XFfc8kFlGlBn2myBo80aGp8Eft259mbcUJhgSg==", + "dev": true, + "requires": { + "glob": "~7.1.1", + "lodash": "~4.17.10", + "minimatch": "~3.0.2" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "dev": true + }, + "grapheme-breaker": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/grapheme-breaker/-/grapheme-breaker-0.3.2.tgz", + "integrity": "sha1-W55reMODJFLSuiuxy4MPlidkEKw=", + "dev": true, + "requires": { + "brfs": "^1.2.0", + "unicode-trie": "^0.3.1" + } + }, + "gzip-size": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-4.1.0.tgz", + "integrity": "sha1-iuCWJX6r59acRb4rZ8RIEk/7UXw=", + "dev": true, + "requires": { + "duplexer": "^0.1.1", + "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 + } + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "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==", + "dev": true, + "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==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + } + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "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" + } + }, + "hex-color-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", + "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "hosted-git-info": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", + "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", + "dev": true + }, + "hsl-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", + "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=", + "dev": true + }, + "hsla-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", + "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=", + "dev": true + }, + "html-comment-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", + "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==", + "dev": true + }, + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "dev": true, + "requires": { + "whatwg-encoding": "^1.0.1" + } + }, + "html-tags": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-1.2.0.tgz", + "integrity": "sha1-x43mW1Zjqll5id0rerSSANfk25g=", + "dev": true + }, + "htmlnano": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/htmlnano/-/htmlnano-0.2.5.tgz", + "integrity": "sha512-X1iPSwXG/iF9bVs+/obt2n6F64uH0ETkA8zp7qFDmLW9/+A6ueHGeb/+qD67T21qUY22owZPMdawljN50ajkqA==", + "dev": true, + "requires": { + "cssnano": "^4.1.10", + "normalize-html-whitespace": "^1.0.0", + "posthtml": "^0.12.0", + "posthtml-render": "^1.1.5", + "purgecss": "^1.4.0", + "svgo": "^1.3.2", + "terser": "^4.3.9", + "uncss": "^0.17.2" + }, + "dependencies": { + "posthtml": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.12.0.tgz", + "integrity": "sha512-aNUEP/SfKUXAt+ghG51LC5MmafChBZeslVe/SSdfKIgLGUVRE68mrMF4V8XbH07ZifM91tCSuxY3eHIFLlecQw==", + "dev": true, + "requires": { + "posthtml-parser": "^0.4.1", + "posthtml-render": "^1.1.5" + } + }, + "terser": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.3.tgz", + "integrity": "sha512-Lw+ieAXmY69d09IIc/yqeBqXpEQIpDGZqT34ui1QWXIUpR2RjbqEkT8X7Lgex19hslSqcWM5iMN2kM11eMsESQ==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + } + } + } + }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dev": true, + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.5.0.tgz", + "integrity": "sha512-gSz026xs2LfxBPudDuI41V1lka8cxg64E66SGe78zJlsUofOg/yqwezdIcdfwik6B4h8LFmWPA9ef9X3FiNFLA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "http-errors": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "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=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "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.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" + } + }, + "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=", + "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==", + "dev": true + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "in-publish": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz", + "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=", + "dev": true + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "is-absolute-url": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", + "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "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-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-color-stop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", + "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", + "dev": true, + "requires": { + "css-color-names": "^0.0.4", + "hex-color-regex": "^1.1.0", + "hsl-regex": "^1.0.0", + "hsla-regex": "^1.0.0", + "rgb-regex": "^1.0.1", + "rgba-regex": "^1.0.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "dev": true + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-html": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-html/-/is-html-1.1.0.tgz", + "integrity": "sha1-4E8cGNOUhRETlvmgJz6rUa8hhGQ=", + "dev": true, + "requires": { + "html-tags": "^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" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "dev": true, + "requires": { + "is-path-inside": "^1.0.0" + } + }, + "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": { + "path-is-inside": "^1.0.1" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-svg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", + "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==", + "dev": true, + "requires": { + "html-comment-regex": "^1.1.0" + } + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "js-base64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.1.tgz", + "integrity": "sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "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=", + "dev": true + }, + "jsdom": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-14.1.0.tgz", + "integrity": "sha512-O901mfJSuTdwU2w3Sn+74T+RnDVP+FuV5fH8tcPWyqrseRAb0s5xOtPgCFiPOtLcyK7CLIJwPyD83ZqQWvA5ng==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "acorn": "^6.0.4", + "acorn-globals": "^4.3.0", + "array-equal": "^1.0.0", + "cssom": "^0.3.4", + "cssstyle": "^1.1.1", + "data-urls": "^1.1.0", + "domexception": "^1.0.1", + "escodegen": "^1.11.0", + "html-encoding-sniffer": "^1.0.2", + "nwsapi": "^2.1.3", + "parse5": "5.1.0", + "pn": "^1.1.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.5", + "saxes": "^3.1.9", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.5.0", + "w3c-hr-time": "^1.0.1", + "w3c-xmlserializer": "^1.1.2", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^7.0.0", + "ws": "^6.1.2", + "xml-name-validator": "^3.0.0" + }, + "dependencies": { + "acorn": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.0.tgz", + "integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==", + "dev": true + }, + "escodegen": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.13.0.tgz", + "integrity": "sha512-eYk2dCkxR07DsHA/X2hRBj0CFAZeri/LyDMc0C8JT1Hqi6JnVpMhJ7XFITbb0+yZS3lVkaPL2oCkZ3AVmeVbMw==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "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 + }, + "ws": { + "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" + } + } + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "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==", + "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=", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "junk": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/junk/-/junk-1.0.3.tgz", + "integrity": "sha1-h75jSIZJy9ym9Tqzm+yczSNH9ZI=", + "dev": true + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "^1.0.0" + } + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, + "levenary": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", + "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==", + "dev": true, + "requires": { + "leven": "^3.1.0" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "dependencies": { + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + } + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "lodash.clone": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", + "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=", + "dev": true + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", + "dev": true + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + } + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "magic-string": { + "version": "0.22.5", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz", + "integrity": "sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==", + "dev": true, + "requires": { + "vlq": "^0.2.2" + } + }, + "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==", + "dev": true, + "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=", + "dev": true + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "maximatch": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/maximatch/-/maximatch-0.1.0.tgz", + "integrity": "sha1-hs2NawTJ8wfAWmuUGZBtA2D7E6I=", + "dev": true, + "requires": { + "array-differ": "^1.0.0", + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "minimatch": "^3.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==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", + "dev": true + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + }, + "dependencies": { + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + } + } + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "requires": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + } + }, + "merge-source-map": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.0.4.tgz", + "integrity": "sha1-pd5GU42uhNQRTMXqArR3KmNGcB8=", + "dev": true, + "requires": { + "source-map": "^0.5.6" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "merge2": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", + "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "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": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mime-db": { + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", + "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==", + "dev": true + }, + "mime-types": { + "version": "2.1.26", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", + "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", + "dev": true, + "requires": { + "mime-db": "1.43.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" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "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=", + "dev": true + } + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "dev": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-addon-api": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.1.tgz", + "integrity": "sha512-2+DuKodWvwRTrCfKOeR24KIc5unKjOh8mz17NCzVnHWfjAdDqbfbjqh7gUT+BkXBRQM52+xCHciKWonJ3CbJMQ==", + "dev": true + }, + "node-forge": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.6.tgz", + "integrity": "sha512-sol30LUpz1jQFBjOKwbjxijiE3b6pjd74YwfD0fJOKPjF+fONKb2Yg8rYgS6+bK6VDl+/wfr4IYpC7jDzLUIfw==", + "dev": true + }, + "node-gyp": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", + "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==", + "dev": true, + "requires": { + "fstream": "^1.0.0", + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": "^2.87.0", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^2.0.0", + "which": "1" + }, + "dependencies": { + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true + } + } + }, + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "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=", + "dev": true + } + } + }, + "node-releases": { + "version": "1.1.47", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.47.tgz", + "integrity": "sha512-k4xjVPx5FpwBUj0Gw7uvFOTF4Ep8Hok1I6qjwL3pLfwe7Y0REQSAqOwwv9TWBCUtMHxcXfY4PgRLRozcChvTcA==", + "dev": true, + "requires": { + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "node-sass": { + "version": "4.13.1", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.13.1.tgz", + "integrity": "sha512-TTWFx+ZhyDx1Biiez2nB0L3YrCZ/8oHagaDalbuBSlqXgUPsdkUSzJsVxeDO9LtPB49+Fh3WQl3slABo6AotNw==", + "dev": true, + "requires": { + "async-foreach": "^0.1.3", + "chalk": "^1.1.1", + "cross-spawn": "^3.0.0", + "gaze": "^1.0.0", + "get-stdin": "^4.0.1", + "glob": "^7.0.3", + "in-publish": "^2.0.0", + "lodash": "^4.17.15", + "meow": "^3.7.0", + "mkdirp": "^0.5.1", + "nan": "^2.13.2", + "node-gyp": "^3.8.0", + "npmlog": "^4.0.0", + "request": "^2.88.0", + "sass-graph": "^2.2.4", + "stdout-stream": "^1.4.0", + "true-case-path": "^1.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "cross-spawn": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", + "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-html-whitespace": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/normalize-html-whitespace/-/normalize-html-whitespace-1.0.0.tgz", + "integrity": "sha512-9ui7CGtOOlehQu0t/OhhlmDyc71mKVlv+4vF+me4iZLPrNtRL2xoquEdfZxasC/bdQi/Hr3iTrpyRKIG+ocabA==", + "dev": true + }, + "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" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-url": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", + "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", + "dev": true + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "requires": { + "boolbase": "~1.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "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==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-inspect": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.4.1.tgz", + "integrity": "sha512-wqdhLpfCUbEsoEwl3FXwGyv8ief1k/1aUdIPCqVnupM6e8l63BEJdiF/0swtn04/8p05tG/T0FrpTlfwvljOdw==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", + "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "object.values": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "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" + } + }, + "opn": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", + "dev": true, + "requires": { + "is-wsl": "^1.1.0" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "ora": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-2.1.0.tgz", + "integrity": "sha512-hNNlAd3gfv/iPmsNxYoAPLvxg7HuPozww7fFonMZvL84tP6Ox5igfk5j/+a9rtJJwqMgKK+JgWsAQik5o0HTLA==", + "dev": true, + "requires": { + "chalk": "^2.3.1", + "cli-cursor": "^2.1.0", + "cli-spinners": "^1.1.0", + "log-symbols": "^2.2.0", + "strip-ansi": "^4.0.0", + "wcwidth": "^1.0.1" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "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": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "requires": { + "lcid": "^1.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 + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "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 + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", + "dev": true + }, + "p-limit": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", + "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", + "dev": true + }, + "parcel": { + "version": "1.12.4", + "resolved": "https://registry.npmjs.org/parcel/-/parcel-1.12.4.tgz", + "integrity": "sha512-qfc74e2/R4pCoU6L/ZZnK9k3iDS6ir4uHea0e9th9w52eehcAGf2ido/iABq9PBXdsIOe4NSY3oUm7Khe7+S3w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/core": "^7.4.4", + "@babel/generator": "^7.4.4", + "@babel/parser": "^7.4.4", + "@babel/plugin-transform-flow-strip-types": "^7.4.4", + "@babel/plugin-transform-modules-commonjs": "^7.4.4", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/preset-env": "^7.4.4", + "@babel/runtime": "^7.4.4", + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.4.4", + "@babel/types": "^7.4.4", + "@iarna/toml": "^2.2.0", + "@parcel/fs": "^1.11.0", + "@parcel/logger": "^1.11.1", + "@parcel/utils": "^1.11.0", + "@parcel/watcher": "^1.12.1", + "@parcel/workers": "^1.11.0", + "ansi-to-html": "^0.6.4", + "babylon-walk": "^1.0.2", + "browserslist": "^4.1.0", + "chalk": "^2.1.0", + "clone": "^2.1.1", + "command-exists": "^1.2.6", + "commander": "^2.11.0", + "core-js": "^2.6.5", + "cross-spawn": "^6.0.4", + "css-modules-loader-core": "^1.1.0", + "cssnano": "^4.0.0", + "deasync": "^0.1.14", + "dotenv": "^5.0.0", + "dotenv-expand": "^5.1.0", + "envinfo": "^7.3.1", + "fast-glob": "^2.2.2", + "filesize": "^3.6.0", + "get-port": "^3.2.0", + "htmlnano": "^0.2.2", + "is-glob": "^4.0.0", + "is-url": "^1.2.2", + "js-yaml": "^3.10.0", + "json5": "^1.0.1", + "micromatch": "^3.0.4", + "mkdirp": "^0.5.1", + "node-forge": "^0.7.1", + "node-libs-browser": "^2.0.0", + "opn": "^5.1.0", + "postcss": "^7.0.11", + "postcss-value-parser": "^3.3.1", + "posthtml": "^0.11.2", + "posthtml-parser": "^0.4.0", + "posthtml-render": "^1.1.3", + "resolve": "^1.4.0", + "semver": "^5.4.1", + "serialize-to-js": "^3.0.0", + "serve-static": "^1.12.4", + "source-map": "0.6.1", + "terser": "^3.7.3", + "v8-compile-cache": "^2.0.0", + "ws": "^5.1.1" + } + }, + "parcel-plugin-bundle-visualiser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parcel-plugin-bundle-visualiser/-/parcel-plugin-bundle-visualiser-1.2.0.tgz", + "integrity": "sha512-/O+26nsOwXbl1q6A/X9lEJWAPwZt5VauTV32omC3a/09bfUgHTogkAIYB/BqrGQm6OyuoG5FATToT3AGGk9RTA==", + "dev": true, + "requires": { + "filesize": "^3.6.0", + "gzip-size": "^4.1.0", + "yargs": "^11.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "get-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 + }, + "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==", + "dev": true + }, + "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" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "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" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "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 + }, + "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" + } + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "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=", + "dev": true, + "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=", + "dev": true, + "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=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yargs": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.1.tgz", + "integrity": "sha512-PRU7gJrJaXv3q3yQZ/+/X6KBswZiaQ+zOmdprZcouPYtQgvNU35i+68M4b1ZHLZtYFT5QObFLV+ZkmJYcwKdiw==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.1.1", + "find-up": "^2.1.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.1.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^9.0.2" + } + }, + "yargs-parser": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", + "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", + "dev": true, + "requires": { + "camelcase": "^4.1.0" + } + } + } + }, + "parcel-plugin-copy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parcel-plugin-copy/-/parcel-plugin-copy-1.0.2.tgz", + "integrity": "sha512-2mgf8Ezj0KOf/QYNadQpBbRSaa6Ay5hIpBdVVMSc5ZYyD1Mo2AJlPzFsj55XL6Mm71aaISCGC8EH4dw/SW2PMQ==", + "dev": true, + "requires": { + "recursive-copy": "^2.0.9" + } + }, + "parse-asn1": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", + "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", + "dev": true, + "requires": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "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" + } + }, + "parse5": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", + "dev": true + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pbkdf2": { + "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", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "physical-cpu-count": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/physical-cpu-count/-/physical-cpu-count-2.0.0.tgz", + "integrity": "sha1-GN4vl+S/epVRrXURlCtUlverpmA=", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "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" + } + }, + "pn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", + "dev": true + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "postcss": { + "version": "7.0.26", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.26.tgz", + "integrity": "sha512-IY4oRjpXWYshuTDFxMVkJDtWIk2LhsTlu8bZnbEJA4+bYT16Lvpo8Qv6EvDumhYRgzjZl489pmsY3qVgJQ08nA==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-calc": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.1.tgz", + "integrity": "sha512-oXqx0m6tb4N3JGdmeMSc/i91KppbYsFZKdH0xMOqK8V1rJlzrKlTdokz8ozUXLVejydRN6u2IddxpcijRj2FqQ==", + "dev": true, + "requires": { + "css-unit-converter": "^1.1.1", + "postcss": "^7.0.5", + "postcss-selector-parser": "^5.0.0-rc.4", + "postcss-value-parser": "^3.3.1" + } + }, + "postcss-colormin": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", + "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "color": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-convert-values": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", + "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", + "dev": true, + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-discard-comments": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", + "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-duplicates": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", + "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-empty": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", + "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-overridden": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", + "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-merge-longhand": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", + "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", + "dev": true, + "requires": { + "css-color-names": "0.0.4", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "stylehacks": "^4.0.0" + } + }, + "postcss-merge-rules": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", + "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "cssnano-util-same-parent": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0", + "vendors": "^1.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", + "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", + "dev": true, + "requires": { + "dot-prop": "^4.1.1", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "postcss-minify-font-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", + "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", + "dev": true, + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-minify-gradients": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", + "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "is-color-stop": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-minify-params": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", + "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.0", + "browserslist": "^4.0.0", + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "uniqs": "^2.0.0" + } + }, + "postcss-minify-selectors": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", + "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", + "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", + "dev": true, + "requires": { + "dot-prop": "^4.1.1", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "postcss-modules-extract-imports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz", + "integrity": "sha1-thTJcgvmgW6u41+zpfqh26agXds=", + "dev": true, + "requires": { + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + } + } + }, + "postcss-modules-local-by-default": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz", + "integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=", + "dev": true, + "requires": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + } + } + }, + "postcss-modules-scope": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz", + "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=", + "dev": true, + "requires": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + } + } + }, + "postcss-modules-values": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz", + "integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=", + "dev": true, + "requires": { + "icss-replace-symbols": "^1.1.0", + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + } + } + }, + "postcss-normalize-charset": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", + "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-normalize-display-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", + "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", + "dev": true, + "requires": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-positions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", + "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-repeat-style": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", + "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-string": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", + "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", + "dev": true, + "requires": { + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-timing-functions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", + "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", + "dev": true, + "requires": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-unicode": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", + "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-url": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", + "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", + "dev": true, + "requires": { + "is-absolute-url": "^2.0.0", + "normalize-url": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-whitespace": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", + "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", + "dev": true, + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-ordered-values": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", + "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-reduce-initial": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", + "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0" + } + }, + "postcss-reduce-transforms": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", + "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", + "dev": true, + "requires": { + "cssnano-util-get-match": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-selector-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", + "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", + "dev": true, + "requires": { + "cssesc": "^2.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "dependencies": { + "cssesc": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", + "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", + "dev": true + } + } + }, + "postcss-svgo": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz", + "integrity": "sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==", + "dev": true, + "requires": { + "is-svg": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "svgo": "^1.0.0" + } + }, + "postcss-unique-selectors": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", + "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.0", + "postcss": "^7.0.0", + "uniqs": "^2.0.0" + } + }, + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "posthtml": { + "version": "0.11.6", + "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.11.6.tgz", + "integrity": "sha512-C2hrAPzmRdpuL3iH0TDdQ6XCc9M7Dcc3zEW5BLerY65G4tWWszwv6nG/ksi6ul5i2mx22ubdljgktXCtNkydkw==", + "dev": true, + "requires": { + "posthtml-parser": "^0.4.1", + "posthtml-render": "^1.1.5" + } + }, + "posthtml-parser": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.4.2.tgz", + "integrity": "sha512-BUIorsYJTvS9UhXxPTzupIztOMVNPa/HtAm9KHni9z6qEfiJ1bpOBL5DfUOL9XAc3XkLIEzBzpph+Zbm4AdRAg==", + "dev": true, + "requires": { + "htmlparser2": "^3.9.2" + } + }, + "posthtml-render": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-1.1.5.tgz", + "integrity": "sha512-yvt54j0zCBHQVEFAuR+yHld8CZrCa/E1Z/OcFNCV1IEWTLVxT8O7nYnM4IIw1CD4r8kaRd3lc42+0lgCKgm87w==", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "dev": true, + "requires": { + "asap": "~2.0.3" + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "psl": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", + "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==", + "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", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "purgecss": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/purgecss/-/purgecss-1.4.2.tgz", + "integrity": "sha512-hkOreFTgiyMHMmC2BxzdIw5DuC6kxAbP/gGOGd3MEsF3+5m69rIvUEPaxrnoUtfODTFKe9hcXjGwC6jcjoyhOw==", + "dev": true, + "requires": { + "glob": "^7.1.3", + "postcss": "^7.0.14", + "postcss-selector-parser": "^6.0.0", + "yargs": "^14.0.0" + }, + "dependencies": { + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true + }, + "postcss-selector-parser": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", + "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "quote-stream": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/quote-stream/-/quote-stream-1.0.2.tgz", + "integrity": "sha1-hJY/jJwmuULhU/7rU6rnRlK34LI=", + "dev": true, + "requires": { + "buffer-equal": "0.0.1", + "minimist": "^1.1.3", + "through2": "^2.0.0" + } + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "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 + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "dependencies": { + "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" + } + } + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "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" + } + }, + "recursive-copy": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/recursive-copy/-/recursive-copy-2.0.10.tgz", + "integrity": "sha512-S9J9XJUnfZ2NUS3lK6lx6HWLl2nWui+f7AKuu+qoFs4ikEPYgZ3qKk1T6tmBnr7PzhtKnawE+6TREy9XQKmxCA==", + "dev": true, + "requires": { + "del": "^2.2.0", + "emitter-mixin": "0.0.3", + "errno": "^0.1.2", + "graceful-fs": "^4.1.4", + "junk": "^1.0.1", + "maximatch": "^0.1.0", + "mkdirp": "^0.5.1", + "pify": "^2.3.0", + "promise": "^7.0.1", + "slash": "^1.0.0" + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + } + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz", + "integrity": "sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==", + "dev": true, + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-runtime": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", + "dev": true + }, + "regenerator-transform": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.1.tgz", + "integrity": "sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ==", + "dev": true, + "requires": { + "private": "^0.1.6" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexpu-core": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.6.0.tgz", + "integrity": "sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.1.0", + "regjsgen": "^0.5.0", + "regjsparser": "^0.6.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.1.0" + } + }, + "regjsgen": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz", + "integrity": "sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg==", + "dev": true + }, + "regjsparser": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.2.tgz", + "integrity": "sha512-E9ghzUtoLwDekPT0DYCp+c4h+bvuUpe6rRHCTYn6eGoqj1LgKXxT6I0Il4WbjhQkOghzi/V+y03bPKvbllL93Q==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + } + } + }, + "request-promise-core": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", + "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", + "dev": true, + "requires": { + "lodash": "^4.17.15" + } + }, + "request-promise-native": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz", + "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==", + "dev": true, + "requires": { + "request-promise-core": "1.1.3", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "resolve": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.0.tgz", + "integrity": "sha512-+hTmAldEGE80U2wJJDC1lebb5jWqvTYAfm3YZ1ckk1gBr0MnCqUKlwK1e+anaFljIl+F5tR5IoZcm4ZDA1zMQw==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "rgb-regex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", + "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=", + "dev": true + }, + "rgba-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", + "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "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" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sass-graph": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz", + "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=", + "dev": true, + "requires": { + "glob": "^7.0.0", + "lodash": "^4.0.0", + "scss-tokenizer": "^0.2.3", + "yargs": "^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "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=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "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 + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "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=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + } + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yargs": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", + "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", + "dev": true, + "requires": { + "camelcase": "^3.0.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.2", + "which-module": "^1.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^5.0.0" + } + }, + "yargs-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", + "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "dev": true, + "requires": { + "camelcase": "^3.0.0" + } + } + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "saxes": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", + "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", + "dev": true, + "requires": { + "xmlchars": "^2.1.1" + } + }, + "scss-tokenizer": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", + "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", + "dev": true, + "requires": { + "js-base64": "^2.1.8", + "source-map": "^0.4.2" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "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 + } + } + }, + "serialize-to-js": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/serialize-to-js/-/serialize-to-js-3.1.1.tgz", + "integrity": "sha512-F+NGU0UHMBO4Q965tjw7rvieNVjlH6Lqi2emq/Lc9LUURYJbiCzmpi4Cy1OOjjVPtxu0c+NE85LU6968Wko5ZA==", + "dev": true + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "sha.js": { + "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" + } + }, + "shallow-copy": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/shallow-copy/-/shallow-copy-0.0.1.tgz", + "integrity": "sha1-QV9CcC1z2BAzApLMXuhurhoRoXA=", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "dev": true, + "requires": { + "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "dev": true + } + } + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "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" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", + "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "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.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "dev": true + }, + "static-eval": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.3.tgz", + "integrity": "sha512-zsxDGucfAh8T339sSKgpFbvg15Fms2IVaJGC+jqp0bVsxhcpM+iMeAI8weNo8dmf4OblgifTBUoyk1vGVtYw2w==", + "dev": true, + "requires": { + "escodegen": "^1.11.1" + }, + "dependencies": { + "escodegen": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.13.0.tgz", + "integrity": "sha512-eYk2dCkxR07DsHA/X2hRBj0CFAZeri/LyDMc0C8JT1Hqi6JnVpMhJ7XFITbb0+yZS3lVkaPL2oCkZ3AVmeVbMw==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "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 + } + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "static-module": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/static-module/-/static-module-2.2.5.tgz", + "integrity": "sha512-D8vv82E/Kpmz3TXHKG8PPsCPg+RAX6cbCOyvjM6x04qZtQ47EtJFVwRsdov3n5d6/6ynrOY9XB4JkaZwB2xoRQ==", + "dev": true, + "requires": { + "concat-stream": "~1.6.0", + "convert-source-map": "^1.5.1", + "duplexer2": "~0.1.4", + "escodegen": "~1.9.0", + "falafel": "^2.1.0", + "has": "^1.0.1", + "magic-string": "^0.22.4", + "merge-source-map": "1.0.4", + "object-inspect": "~1.4.0", + "quote-stream": "~1.0.2", + "readable-stream": "~2.3.3", + "shallow-copy": "~0.0.1", + "static-eval": "^2.0.0", + "through2": "~2.0.3" + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, + "stdout-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz", + "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==", + "dev": true, + "requires": { + "readable-stream": "^2.0.1" + } + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, + "stream-browserify": { + "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" + } + }, + "stream-http": { + "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", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "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 + }, + "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" + } + } + } + }, + "string.prototype.trimleft": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", + "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimright": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", + "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "^4.0.1" + } + }, + "stylehacks": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", + "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", + "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", + "dev": true, + "requires": { + "dot-prop": "^4.1.1", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "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" + } + }, + "svgo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + } + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "tar": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", + "dev": true, + "requires": { + "block-stream": "*", + "fstream": "^1.0.12", + "inherits": "2" + } + }, + "terser": { + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-3.17.0.tgz", + "integrity": "sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ==", + "dev": true, + "requires": { + "commander": "^2.19.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.10" + } + }, + "through2": { + "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" + } + }, + "timers-browserify": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", + "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", + "dev": true + }, + "tiny-inflate": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", + "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==", + "dev": true + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + }, + "true-case-path": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz", + "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==", + "dev": true, + "requires": { + "glob": "^7.1.2" + } + }, + "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 + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "uncss": { + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/uncss/-/uncss-0.17.2.tgz", + "integrity": "sha512-hu2HquwDItuGDem4YsJROdAD8SknmWtM24zwhQax6J1se8tPjV1cnwPKhtjodzBaUhaL8Zb3hlGdZ2WAUpbAOg==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "glob": "^7.1.4", + "is-absolute-url": "^3.0.1", + "is-html": "^1.1.0", + "jsdom": "^14.1.0", + "lodash": "^4.17.15", + "postcss": "^7.0.17", + "postcss-selector-parser": "6.0.2", + "request": "^2.88.0" + }, + "dependencies": { + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true + }, + "is-absolute-url": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", + "dev": true + }, + "postcss-selector-parser": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", + "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz", + "integrity": "sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz", + "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==", + "dev": true + }, + "unicode-trie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-0.3.1.tgz", + "integrity": "sha1-1nHd3YkQGgi6w3tqUWEBBgIFIIU=", + "dev": true, + "requires": { + "pako": "^0.2.5", + "tiny-inflate": "^1.0.0" + } + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", + "dev": true + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util": { + "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" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "util.promisify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", + "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.2", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.0" + } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + }, + "v8-compile-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "dev": true + }, + "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" + } + }, + "vendors": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", + "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vlq": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", + "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", + "dev": true + }, + "vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "w3c-hr-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", + "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", + "dev": true, + "requires": { + "browser-process-hrtime": "^0.1.2" + } + }, + "w3c-xmlserializer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", + "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", + "dev": true, + "requires": { + "domexception": "^1.0.1", + "webidl-conversions": "^4.0.2", + "xml-name-validator": "^3.0.0" + } + }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "requires": { + "iconv-lite": "0.4.24" + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + }, + "dependencies": { + "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" + } + } + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "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 + }, + "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" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "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 + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "14.2.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.2.tgz", + "integrity": "sha512-/4ld+4VV5RnrynMhPZJ/ZpOCGSCeghMykZ3BhdFBDa9Wy/RH6uEGNWDJog+aUlq+9OM1CFTgtYRW5Is1Po9NOA==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^15.0.0" + } + }, + "yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-xLTUnCMc4JhxrPEPUYD5IBR1mWCK/aT6+RJ/K29JY2y1vD+FhtgKK0AXRWvI262q3QSffAQuTouFIKUuHX89wQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..72e3f39 --- /dev/null +++ b/package.json @@ -0,0 +1,25 @@ +{ + "name": "kaios-custom-launcher", + "version": "1.0.0", + "description": "a custom launcher for kaiOS", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "build": "parcel build src/index.html", + "watch": "parcel src/index.html", + "package": "npm run build && ./package_app.sh" + }, + "author": "strukturart", + "license": "MIT", + "devDependencies": { + "parcel": "^1.12.4", + "adm-zip": "^0.4.13", + "fs-extra": "^8.1.0", + "node-sass": "^4.13.0", + "parcel-plugin-bundle-visualiser": "^1.2.0", + "parcel-plugin-copy": "^1.0.2" + }, + "staticPath": { + "source": "/static", + "target": "/dist" + } +} diff --git a/package_app.sh b/package_app.sh new file mode 100755 index 0000000..27d19a6 --- /dev/null +++ b/package_app.sh @@ -0,0 +1,21 @@ +#!/bin/bash +set -e #fail on error + +mkdir -p ./build/tmp + +# remove old artifacts +rm ./build/tmp/application.zip || true +rm ./build/custom-kaiOS-launcher.zip || true + +# copy stuff +cp ./metadata.json ./build/tmp/metadata.json + +cd build/tmp + +zip -jqr application.zip ../../dist + +cd .. + +zip -jqr custom-kaiOS-launcher.zip tmp + +echo "Created custom-kaiOS-launcher.zip" \ No newline at end of file diff --git a/application/assets/css/grid.css b/src/assets/css/grid.css similarity index 99% rename from application/assets/css/grid.css rename to src/assets/css/grid.css index 1fc83d9..86af6a4 100644 --- a/application/assets/css/grid.css +++ b/src/assets/css/grid.css @@ -681,7 +681,6 @@ .flex-shrink-1 { - //flex: 1 1 min-width:50%; max-width:50%; outline:2px solid red; diff --git a/application/assets/css/grid.min.css b/src/assets/css/grid.min.css similarity index 100% rename from application/assets/css/grid.min.css rename to src/assets/css/grid.min.css diff --git a/application/assets/css/main.css b/src/assets/css/main.css similarity index 100% rename from application/assets/css/main.css rename to src/assets/css/main.css diff --git a/application/assets/css/main.min.css b/src/assets/css/main.min.css similarity index 100% rename from application/assets/css/main.min.css rename to src/assets/css/main.min.css diff --git a/application/assets/js/Chart.bundle.js b/src/assets/js/Chart.bundle.js similarity index 100% rename from application/assets/js/Chart.bundle.js rename to src/assets/js/Chart.bundle.js diff --git a/application/assets/js/applait.finder.min.js b/src/assets/js/applait.finder.min.js similarity index 100% rename from application/assets/js/applait.finder.min.js rename to src/assets/js/applait.finder.min.js diff --git a/application/assets/js/client.min.js b/src/assets/js/client.min.js similarity index 100% rename from application/assets/js/client.min.js rename to src/assets/js/client.min.js diff --git a/application/assets/js/jQuery-3.1.0.js b/src/assets/js/jQuery-3.1.0.js similarity index 100% rename from application/assets/js/jQuery-3.1.0.js rename to src/assets/js/jQuery-3.1.0.js diff --git a/application/assets/js/moments.min.js b/src/assets/js/moments.min.js similarity index 100% rename from application/assets/js/moments.min.js rename to src/assets/js/moments.min.js diff --git a/application/assets/js/script.js b/src/assets/js/script.js similarity index 100% rename from application/assets/js/script.js rename to src/assets/js/script.js diff --git a/application/assets/js/script.min.js b/src/assets/js/script.min.js similarity index 100% rename from application/assets/js/script.min.js rename to src/assets/js/script.min.js diff --git a/application/index.html b/src/index.html similarity index 97% rename from application/index.html rename to src/index.html index 6af5a18..e48965c 100644 --- a/application/index.html +++ b/src/index.html @@ -11,7 +11,7 @@ - + diff --git a/application/icons/icon-112-112.png b/static/icons/icon-112-112.png similarity index 100% rename from application/icons/icon-112-112.png rename to static/icons/icon-112-112.png diff --git a/application/icons/icon-112-112.svg b/static/icons/icon-112-112.svg similarity index 100% rename from application/icons/icon-112-112.svg rename to static/icons/icon-112-112.svg diff --git a/application/icons/icon-56-56.png b/static/icons/icon-56-56.png similarity index 100% rename from application/icons/icon-56-56.png rename to static/icons/icon-56-56.png diff --git a/application/icons/icon-56-56.svg b/static/icons/icon-56-56.svg similarity index 100% rename from application/icons/icon-56-56.svg rename to static/icons/icon-56-56.svg diff --git a/application/manifest.webapp b/static/manifest.webapp similarity index 100% rename from application/manifest.webapp rename to static/manifest.webapp From 14ff04d85d32532fd5a7c61070f048be721108f4 Mon Sep 17 00:00:00 2001 From: Simon Laux Date: Mon, 3 Feb 2020 04:33:52 +0100 Subject: [PATCH 3/6] move stuff and format code --- package-lock.json | 6 + package.json | 12 +- src/assets/css/grid.css | 820 ------- src/assets/css/grid.min.css | 1 - src/assets/css/main.css | 382 --- src/assets/css/main.min.css | 1 - src/assets/js/script.js | 2070 ----------------- src/assets/js/script.min.js | 1 - src/css/grid.css | 603 +++++ src/css/main.css | 292 +++ src/index.html | 240 +- src/script.js | 1554 +++++++++++++ {src/assets/js => thirdparty}/Chart.bundle.js | 0 .../js => thirdparty}/applait.finder.min.js | 0 {src/assets/js => thirdparty}/client.min.js | 0 {src/assets/js => thirdparty}/jQuery-3.1.0.js | 0 {src/assets/js => thirdparty}/moments.min.js | 0 17 files changed, 2579 insertions(+), 3403 deletions(-) delete mode 100644 src/assets/css/grid.css delete mode 100644 src/assets/css/grid.min.css delete mode 100644 src/assets/css/main.css delete mode 100644 src/assets/css/main.min.css delete mode 100644 src/assets/js/script.js delete mode 100644 src/assets/js/script.min.js create mode 100644 src/css/grid.css create mode 100644 src/css/main.css create mode 100644 src/script.js rename {src/assets/js => thirdparty}/Chart.bundle.js (100%) rename {src/assets/js => thirdparty}/applait.finder.min.js (100%) rename {src/assets/js => thirdparty}/client.min.js (100%) rename {src/assets/js => thirdparty}/jQuery-3.1.0.js (100%) rename {src/assets/js => thirdparty}/moments.min.js (100%) diff --git a/package-lock.json b/package-lock.json index 134a1f2..3a20218 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6765,6 +6765,12 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, + "prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "dev": true + }, "private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", diff --git a/package.json b/package.json index 72e3f39..c09e602 100644 --- a/package.json +++ b/package.json @@ -6,20 +6,24 @@ "test": "echo \"Error: no test specified\" && exit 1", "build": "parcel build src/index.html", "watch": "parcel src/index.html", - "package": "npm run build && ./package_app.sh" + "package": "npm run build && ./package_app.sh", + "test-format": "prettier --check \"src/**/*.{js,html,css,scss}\"", + "format": "prettier --write \"src/**/*.{js,html,css,scss}\"" }, "author": "strukturart", "license": "MIT", "devDependencies": { - "parcel": "^1.12.4", "adm-zip": "^0.4.13", "fs-extra": "^8.1.0", "node-sass": "^4.13.0", + "parcel": "^1.12.4", "parcel-plugin-bundle-visualiser": "^1.2.0", - "parcel-plugin-copy": "^1.0.2" + "parcel-plugin-copy": "^1.0.2", + "prettier": "^1.19.1" }, "staticPath": { "source": "/static", "target": "/dist" - } + }, + "dependencies": {} } diff --git a/src/assets/css/grid.css b/src/assets/css/grid.css deleted file mode 100644 index 86af6a4..0000000 --- a/src/assets/css/grid.css +++ /dev/null @@ -1,820 +0,0 @@ -/* G R I D */ -.grid-col-1 -{ - min-width:10px; - max-width:10px; -} - - -.grid-col-2 -{ - min-width:20px; - max-width:20px; -} - -.grid-col-3 -{ - min-width:30px; - max-width:30px; -} - -.grid-col-4 -{ - min-width:40px; - max-width:40px; -} - -.grid-col-5 -{ - min-width:50px; - max-width:50px; -} - -.grid-col-6 -{ - min-width:60px; - max-width:60px; -} - - -.grid-col-7 -{ - min-width:70px; - max-width:70px; -} - -.grid-col-8 -{ - min-width:80px; - max-width:80px; -} - -.grid-col-9 -{ - min-width:90px; - max-width:90px; -} - -.grid-col-10 -{ - min-width:100px; - max-width:100px; -} - -.grid-col-11 -{ - min-width:110px; - max-width:110px; -} - -.grid-col-12 -{ - min-width:120px; - max-width:120px; -} - -.grid-col-13 -{ - min-width:130px; - max-width:130px; -} - -.grid-col-14 -{ - min-width:140px; - max-width:140px; -} - - -.grid-col-15 -{ - min-width:150px; - max-width:150px; -} - - -.grid-col-16 -{ - min-width:160px; - max-width:160px; -} - - -.grid-col-17 -{ - min-width:170px; - max-width:170px; -} - - -.grid-col-18 -{ - min-width:180px; - max-width:180px; -} - -.grid-col-19 -{ - min-width:190px; - max-width:190px; -} - -.grid-col-20 -{ - min-width:200px; - max-width:200px; -} - -.grid-col-21 -{ - min-width:210px; - max-width:210px; -} - -.grid-col-22 -{ - min-width:220px; - max-width:220px; -} - -.grid-col-23 -{ - min-width:230px; - max-width:230px; -} - -.grid-col-24 -{ - min-width:240px; - max-width:240px; -} - - -.grid-col-25 -{ - min-width:250px; - max-width:250px; -} - - -.grid-col-26 -{ - min-width:260px; - max-width:260px; -} - -.grid-col-27 -{ - min-width:270px; - max-width:270px; -} - - -.grid-col-28 -{ - min-width:280px; - max-width:280px; -} - - -.grid-col-29 -{ - min-width:290px; - max-width:290px; -} - -.grid-col-30 -{ - min-width:300px; - max-width:300px; -} - - -.grid-col-31 -{ - min-width:310px; - max-width:310px; -} - -.grid-col-32 -{ - min-width:320px; - max-width:320px; -} - -.grid-col-33 -{ - min-width:330px; - max-width:330px; -} - -.grid-col-34 -{ - min-width:340px; - max-width:340px; -} - -.grid-col-35 -{ - min-width:350px; - max-width:350px; -} - -.grid-col-36 -{ - min-width:360px; - max-width:360px; -} - -.grid-col-37 -{ - min-width:370px; - max-width:370px; -} - - -.grid-col-38 -{ - min-width:380px; - max-width:380px; -} - - -.grid-col-39 -{ - min-width:390px; - max-width:390px; -} - -.grid-col-40 -{ - min-width:400px; - max-width:400px; -} - -.grid-col-41 -{ - min-width:410px; - max-width:410px; -} - -.grid-col-42 -{ - min-width:420px; - max-width:420px; -} - -.grid-col-43 -{ - min-width:430px; - max-width:430px; -} - -.grid-col-44 -{ - min-width:440px; - max-width:440px; -} - - -.grid-col-45 -{ - min-width:450px; - max-width:450px; -} - - -.grid-col-46 -{ - min-width:460px; - max-width:460px; -} - - -.grid-col-47 -{ - min-width:470px; - max-width:470px; -} - - -.grid-col-48 -{ - min-width:480px; - max-width:480px; -} - - -.grid-col-49 -{ - min-width:490px; - max-width:490px; -} - - -.grid-col-50 -{ - min-width:500px; - max-width:500px; -} - - -.grid-col-51 -{ - min-width:510px; - max-width:510px; -} - -.grid-col-52 -{ - min-width:520px; - max-width:520px; -} - - -.grid-col-53 -{ - min-width:530px; - max-width:530px; -} - - -.grid-col-54 -{ - min-width:540px; - max-width:540px; -} - - -.grid-col-55 -{ - min-width:550px; - max-width:550px; -} - - -.grid-col-56 -{ - min-width:560px; - max-width:560px; -} - - -.grid-col-57 -{ - min-width:570px; - max-width:570px; -} - - -.grid-col-58 -{ - min-width:580px; - max-width:580px; -} - - -.grid-col-59 -{ - min-width:590px; - max-width:590px; -} - - -.grid-col-60 -{ - min-width:600px; - max-width:600px; -} - - -.grid-col-61 -{ - min-width:610px; - max-width:610px; -} - - -.grid-col-62 -{ - min-width:620px; - max-width:620px; -} - - -.grid-col-63 -{ - min-width:630px; - max-width:630px; -} - - -.grid-col-64 -{ - min-width:640px; - max-width:640px; -} - -.grid-col-65 -{ - min-width:650px; - max-width:650px; -} - -.grid-col-66 -{ - min-width:660px; - max-width:660px; -} - -.grid-col-67 -{ - min-width:670px; - max-width:670px; -} - - -.grid-col-68 -{ - min-width:680px; - max-width:680px; -} - -.grid-col-69 -{ - min-width:690px; - max-width:690px; -} - -.grid-col-70 -{ - min-width:700px; - max-width:700px; -} - - -.grid-col-71 -{ - min-width:710px; - max-width:710px; -} - - -.grid-col-72 -{ - min-width:720px; - max-width:720px; -} - -.grid-col-73 -{ - min-width:730px; - max-width:730px; -} - - -.grid-col-74 -{ - min-width:740px; - max-width:740px; -} - - - -.grid-col-75 -{ - min-width:750px; - max-width:750px; -} - - -.grid-col-76 -{ - min-width:760px; - max-width:760px; -} - - -.grid-col-77 -{ - min-width:770px; - max-width:770px; -} - - - -.grid-col-78 -{ - min-width:780px; - max-width:780px; -} - - - -.grid-col-79 -{ - min-width:790px; - max-width:790px; -} - - -.grid-col-80 -{ - min-width:800px; - max-width:800px; -} - - -.grid-col-81 -{ - min-width:810px; - max-width:810px; -} - - -.grid-col-82 -{ - min-width:820px; - max-width:820px; -} - - - -.grid-col-83 -{ - min-width:830px; - max-width:830px; -} - - -.grid-col-84 -{ - min-width:840px; - max-width:840px; -} - -.grid-col-85 -{ - min-width:850px; - max-width:850px; -} - - -.grid-col-86 -{ - min-width:860px; - max-width:860px; -} - - - -.grid-col-87 -{ - min-width:870px; - max-width:870px; -} - - - -.grid-col-88 -{ - min-width:880px; - max-width:880px; -} - - - -.grid-col-88 -{ - min-width:880px; - max-width:880px; -} - - - -.grid-col-89 -{ - min-width:890px; - max-width:890px; -} - - - -.grid-col-90 -{ - min-width:900px; - max-width:900px; -} - - - -.grid-col-91 -{ - min-width:910px; - max-width:910px; -} - - -.grid-col-92 -{ - min-width:920px; - max-width:920px; -} - - -.grid-col-93 -{ - min-width:930px; - max-width:930px; -} - - - - -.grid-col-94 -{ - min-width:940px; - max-width:940px; -} - - - -.grid-col-95 -{ - min-width:950px; - max-width:950px; -} - - - -.grid-col-96 -{ - min-width:960px; - max-width:960px; -} - - -.text-center -{ - text-align:center; -} - - - -.flex -{ - display:-webkit-flex; - display:flex; - -webkit-flex-direction: row; - flex-direction: row; - -webkit-flex-wrap: wrap; - flex-wrap: wrap; - -} - -.flex-column -{ - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; -} - -.flex-shrink-1 -{ - min-width:50%; - max-width:50%; - outline:2px solid red; -} - -.justify-content-start -{ - -webkit-align-items: flex-start; - align-items: flex-start; - -} - -.justify-content-end -{ - -webkit-justify-content: flex-end; - justify-content: flex-end; - -} - -.algin-item-start -{ - -webkit-align-items: flex-start; - align-items: flex-start; - -} - -.algin-item-end -{ - -webkit-align-items: flex-end; - align-items: flex-end; - -} - -.align-item-center -{ - - -webkit-align-items: center; - -ms-flex-align: center; - align-items: center; - -} - -.justify-content-spacebetween -{ - -webkit-justify-content: space-between; - justify-content: space-between; -} - -.justify-content-spacearound -{ - - - -webkit-justify-content: space-around; - -ms-flex-pack: distribute; - justify-content: space-around; - -webkit-align-content: space-around; - -ms-flex-line-pack: distribute; - align-content: space-around; - -} - -.justify-content-center -{ - - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; -} - -.width-100 -{ - min-width:98vw; -} - -.height-100 -{ - min-height:100vh; -} - - -.width-50 -{ - min-width:50%; -} - -.width-30 -{ - min-width:30%; - max-width:30%; -} - -.center -{ - - - transform: translate(50%, -0%); -} - - - - -.col-3 -{ - -webkit-column-count: 3; - -moz-column-count: 3; - column-count: 3; - - - -webkit-column-count: 3; - -webkit-column-gap: 30px; - -moz-column-count: 3; - -moz-column-gap: 30px; - column-count: 3; - column-gap: 30px; - - -} - -.col-dont-break-inside -{ - -webkit-column-break-inside: avoid; /* Chrome, Safari, Opera */ - page-break-inside: avoid; /* Firefox */ - break-inside: avoid; /* IE 10+ */ - -} - -.block -{ - display:block; -} - -[class*='grid-'] -{ - - -} - diff --git a/src/assets/css/grid.min.css b/src/assets/css/grid.min.css deleted file mode 100644 index 0942c2d..0000000 --- a/src/assets/css/grid.min.css +++ /dev/null @@ -1 +0,0 @@ -.grid-col-1{min-width:10px;max-width:10px}.grid-col-2{min-width:20px;max-width:20px}.grid-col-3{min-width:30px;max-width:30px}.grid-col-4{min-width:40px;max-width:40px}.grid-col-5{min-width:50px;max-width:50px}.grid-col-6{min-width:60px;max-width:60px}.grid-col-7{min-width:70px;max-width:70px}.grid-col-8{min-width:80px;max-width:80px}.grid-col-9{min-width:90px;max-width:90px}.grid-col-10{min-width:100px;max-width:100px}.grid-col-11{min-width:110px;max-width:110px}.grid-col-12{min-width:120px;max-width:120px}.grid-col-13{min-width:130px;max-width:130px}.grid-col-14{min-width:140px;max-width:140px}.grid-col-15{min-width:150px;max-width:150px}.grid-col-16{min-width:160px;max-width:160px}.grid-col-17{min-width:170px;max-width:170px}.grid-col-18{min-width:180px;max-width:180px}.grid-col-19{min-width:190px;max-width:190px}.grid-col-20{min-width:200px;max-width:200px}.grid-col-21{min-width:210px;max-width:210px}.grid-col-22{min-width:220px;max-width:220px}.grid-col-23{min-width:230px;max-width:230px}.grid-col-24{min-width:240px;max-width:240px}.grid-col-25{min-width:250px;max-width:250px}.grid-col-26{min-width:260px;max-width:260px}.grid-col-27{min-width:270px;max-width:270px}.grid-col-28{min-width:280px;max-width:280px}.grid-col-29{min-width:290px;max-width:290px}.grid-col-30{min-width:300px;max-width:300px}.grid-col-31{min-width:310px;max-width:310px}.grid-col-32{min-width:320px;max-width:320px}.grid-col-33{min-width:330px;max-width:330px}.grid-col-34{min-width:340px;max-width:340px}.grid-col-35{min-width:350px;max-width:350px}.grid-col-36{min-width:360px;max-width:360px}.grid-col-37{min-width:370px;max-width:370px}.grid-col-38{min-width:380px;max-width:380px}.grid-col-39{min-width:390px;max-width:390px}.grid-col-40{min-width:400px;max-width:400px}.grid-col-41{min-width:410px;max-width:410px}.grid-col-42{min-width:420px;max-width:420px}.grid-col-43{min-width:430px;max-width:430px}.grid-col-44{min-width:440px;max-width:440px}.grid-col-45{min-width:450px;max-width:450px}.grid-col-46{min-width:460px;max-width:460px}.grid-col-47{min-width:470px;max-width:470px}.grid-col-48{min-width:480px;max-width:480px}.grid-col-49{min-width:490px;max-width:490px}.grid-col-50{min-width:500px;max-width:500px}.grid-col-51{min-width:510px;max-width:510px}.grid-col-52{min-width:520px;max-width:520px}.grid-col-53{min-width:530px;max-width:530px}.grid-col-54{min-width:540px;max-width:540px}.grid-col-55{min-width:550px;max-width:550px}.grid-col-56{min-width:560px;max-width:560px}.grid-col-57{min-width:570px;max-width:570px}.grid-col-58{min-width:580px;max-width:580px}.grid-col-59{min-width:590px;max-width:590px}.grid-col-60{min-width:600px;max-width:600px}.grid-col-61{min-width:610px;max-width:610px}.grid-col-62{min-width:620px;max-width:620px}.grid-col-63{min-width:630px;max-width:630px}.grid-col-64{min-width:640px;max-width:640px}.grid-col-65{min-width:650px;max-width:650px}.grid-col-66{min-width:660px;max-width:660px}.grid-col-67{min-width:670px;max-width:670px}.grid-col-68{min-width:680px;max-width:680px}.grid-col-69{min-width:690px;max-width:690px}.grid-col-70{min-width:700px;max-width:700px}.grid-col-71{min-width:710px;max-width:710px}.grid-col-72{min-width:720px;max-width:720px}.grid-col-73{min-width:730px;max-width:730px}.grid-col-74{min-width:740px;max-width:740px}.grid-col-75{min-width:750px;max-width:750px}.grid-col-76{min-width:760px;max-width:760px}.grid-col-77{min-width:770px;max-width:770px}.grid-col-78{min-width:780px;max-width:780px}.grid-col-79{min-width:790px;max-width:790px}.grid-col-80{min-width:800px;max-width:800px}.grid-col-81{min-width:810px;max-width:810px}.grid-col-82{min-width:820px;max-width:820px}.grid-col-83{min-width:830px;max-width:830px}.grid-col-84{min-width:840px;max-width:840px}.grid-col-85{min-width:850px;max-width:850px}.grid-col-86{min-width:860px;max-width:860px}.grid-col-87{min-width:870px;max-width:870px}.grid-col-88{min-width:880px;max-width:880px}.grid-col-88{min-width:880px;max-width:880px}.grid-col-89{min-width:890px;max-width:890px}.grid-col-90{min-width:900px;max-width:900px}.grid-col-91{min-width:910px;max-width:910px}.grid-col-92{min-width:920px;max-width:920px}.grid-col-93{min-width:930px;max-width:930px}.grid-col-94{min-width:940px;max-width:940px}.grid-col-95{min-width:950px;max-width:950px}.grid-col-96{min-width:960px;max-width:960px}.flex{display:-webkit-flex;display:flex;-webkit-flex-direction:row;flex-direction:row;-webkit-flex-wrap:wrap;flex-wrap:wrap}.flex-column{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.flex-shrink-1{max-width:50%;outline:2px solid red}.justify-content-start{-webkit-align-items:flex-start;align-items:flex-start}.justify-content-end{-webkit-justify-content:flex-end;justify-content:flex-end}.algin-item-start{-webkit-align-items:flex-start;align-items:flex-start}.algin-item-end{-webkit-align-items:flex-end;align-items:flex-end}.align-item-center{-webkit-align-items:center;-ms-flex-align:center;align-items:center}.justify-content-spacebetween{-webkit-justify-content:space-between;justify-content:space-between}.justify-content-spacearound{-webkit-justify-content:space-around;-ms-flex-pack:distribute;justify-content:space-around;-webkit-align-content:space-around;-ms-flex-line-pack:distribute;align-content:space-around}.justify-content-center{-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center}.width-100{min-width:100%}.width-50{min-width:50%}.width-30{min-width:30%;max-width:30%}.center{transform:translate(50%,0)}.col-3{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-count:3;-webkit-column-gap:30px;-moz-column-count:3;-moz-column-gap:30px;column-count:3;column-gap:30px}.col-dont-break-inside{-webkit-column-break-inside:avoid;page-break-inside:avoid;break-inside:avoid}.block{display:block} \ No newline at end of file diff --git a/src/assets/css/main.css b/src/assets/css/main.css deleted file mode 100644 index 7cc6e27..0000000 --- a/src/assets/css/main.css +++ /dev/null @@ -1,382 +0,0 @@ - -/*GENERAL*/ - -:root { - --color-one: black; - --color-two: yellow; - --color-three:silver; - --color-four:rgb(99,99,99); - --color-five:rgb(38,38,38); - --color-six:rgb(78,206,144); - --color-seven:gainsboro; - -} -*, *:before, *:after -{ - - border:0px; - padding:0px; - margin:0px; - box-sizing: border-box; -} - -*::-webkit-scrollbar -{ - width: 0!important; - background-color:transparent!Important; - display:none!Important; -} - - -html,body -{ - - font-weight: 100; - width:100%; - position:relative; - margin:0px; - padding:0px; - font-size:1.0rem; - line-height:1.4rem; - -webkit-appearance: none; - height: 100%; - margin: 0; -} - - - -h1 -{ - margin:0 0 20px 0; - font-size:1.2rem; -} - - -h2 -{ - font-size:1.0rem; -} - - -.debug -{ - border:1px solid red; -} - - -/*/////////////////////////// -///HELPER////////////////*/ - - -div#window-status -{ - position:fixed; - top:10px; - left:5px; - background:black; - color:white; - z-index: 900; - display:none; - -} - - - -/*/////////////////////////// -///FINDER////////////////*/ - -div#finder -{ - position:relative; - background:black; - padding:5px; - color:white; - height:100vh; - width:100vw; -} - - -div#finder-error -{ - position:absolute; - z-index:2; - top:50%; - left:50%; - margin:-7px 0 0 -50px; - width:92px; - background:black; - color:white; - font-size:14px; - padding:3px; - display:none; -} - - -div#finder div#app-list -{ - background:black; - color:white; - margin:0 0 3px 0; - padding:3px; - max-height:90%; - min-width:95%; - overflow:hidden; -} - -div#finder div#app-list .child-of-dir -{ - display:none; -} - -div#finder div#app-list .dir -{ - border-left:4px solid silver; - padding:0 0 0 3px; -} - - - - -div#finder div#app-list .dir span.app-name -{ - display:none; -} - - -div#finder div#app-list div -{ - min-width:100%; - margin:0 0 5px 0; -} - - - -div#finder div:focus -{ - background:yellow; - color:black; -} - - -div#weather-wrapper -{ - display:none; - background:black; - -} - -div#quick-settings -{ - display:none; - position:relative; - background:black; - padding:5px; - color:white; - height:100vh; - width:100vw; - -} - - -div#quick-settings div:focus -{ - background:yellow; - color:black; -} - -div#quick-settings div.alarms -{ - margin:15px 0 0 0; -} - -div#quick-settings div.alarms div -{ - padding:0 10px 0 0; -} - -div#quick-settings div.alarms div:first:after -{ - content: "-"; -} - - - -/*/////////////////////////// -///LOCATION////////////////*/ - -div#chart -{ - position: relative; - margin: 25px 0 10px 0; - height: 240px; - width: 99vw; - max-width: 99vw; -} - -div#chart #myChart -{ - margin:0 0 0 -5px!Important; -} - -div#chart div.legend span -{ - margin:5px 5px 0 0; - - -} - -div#chart div.legend span:first-child -{ - color:red; -} - -div#chart div.legend span:nth-child(2) -{ - color:blue; -} - - - -div#location -{ - position:absolute; - z-index:1000; - left:0; - top:0; - background:black; - color:white; - font-size: 14px; - padding:5px 10px 50px 5px; - overflow: hidden; - display:none; -} - -div#weather-wrapper div#locations -{ - display:none; - position:fixed; - z-index:1001; - background:black; - top:0px; - left:0px; -} - -div#weather-wrapper div#locations:first-child -{ - outline:2px solid red; -} - - -div#weather-wrapper div#locations div -{ - display:block; - background:black; - color:white; - width:100%; - height:auto; - margin:0 0 5px 0; -} - -div#weather-wrapper div#locations div:focus -{ - background:yellow; - color:black; -} - - - -div#weather-wrapper div#message -{ - position:absolute; - z-index:5; - color:white; - top:40%; - text-align:center; -} - - -div#location div#weather -{ - margin:10px 0 0 0; -} - -div#location div#temp -{ - font-size:1.7rem; -} - - -div#location div#weather section -{ - border-top:2px dashed white; - margin: 0 0 0px 0; - padding:12px 5px 12px 0px; - background:black; - -} - -div#location div#weather div#weather-bar div#icon -{ - margin:8px 0 0 0; -} - - - -div#location div#weather div#wind-dir -{ - font-size:1.7rem; - max-height:1.7rem!Important; -} - -div#location div#weather div#wind-speed -{ - font-size:0.7rem; - max-height:1.7rem!Important; - margin:-10px 0 0 0; -} - - - -div#location div#weather div#wind-speed div#wind-speed-val -{ - max-height:0.7rem; - -} - -div#location div#weather div#wind-speed div#wind-speed-unit -{ - max-height:0.7rem; -} - - - -div#message-box -{ - display:none; - position:fixed; - bottom:5px; - left:0px; - padding:5px; - min-width:100vw; - height:auto; - background:pink; - color:black; - z-index:2000; -} - - - - - - - - -/* KaiOS portrait devices (240x320) */ -@media only screen and (orientation : portrait) { - /* styles */ -} - -/* KaiOS landscape devices (320x240) */ -@media screen and (orientation: landscape) { - /* styles */ -} \ No newline at end of file diff --git a/src/assets/css/main.min.css b/src/assets/css/main.min.css deleted file mode 100644 index 18f7965..0000000 --- a/src/assets/css/main.min.css +++ /dev/null @@ -1 +0,0 @@ -:root{--color-one:black;--color-two:yellow;--color-three:silver;--color-four:rgb(99,99,99);--color-five:rgb(38,38,38);--color-six:rgb(78,206,144);--color-seven:gainsboro}*,:after,:before{border:0;padding:0;margin:0;box-sizing:border-box}::-webkit-scrollbar{width:0!important}body,html{font-weight:100;width:100%;color:var(--color-four);position:relative;margin:0;padding:0;font-size:.95rem;line-height:1.4rem;-webkit-appearance:none;height:100%;margin:0}div#zoom-level{position:fixed;z-index:1000;top:10px;left:10px;background:#000;color:#fff;font-size:16px}div#man-page{display:none;position:fixed;z-index:3000;top:0;background:#000;color:#fff;font-size:12px;width:100%;height:100vh;padding:5px}div#man-page h1{text-align:center;font-weight:800;margin:0 0 10px 0;font-size:14px}div#man-page li div{padding:0 0 0 10px}div#location{position:absolute;z-index:3000;top:40px;left:10px;background:#000;color:#fff;font-size:14px;display:none}div#currentPosition{position:absolute;z-index:-3000;top:40px;background:#000;color:#fff;font-size:14px;width:100%;height:100vh;padding:5px}div#currentPosition>div{text-align:center}#map{height:100%;width:100vw}.gpx{border:2px #aaa solid;border-radius:5px;box-shadow:0 0 3px 3px #ccc;width:800px;margin:1em auto}.gpx header{padding:.5em}.gpx h3{margin:0;padding:0;font-weight:700}.gpx .start{font-size:smaller;color:#444}.gpx .map{border:1px #888 solid;border-left:none;border-right:none;width:800px;height:500px;margin:0}.gpx footer{background:#f0f0f0;padding:.5em}.gpx ul.info{list-style:none;margin:0;padding:0;font-size:smaller}.gpx ul.info li{color:#666;padding:2px;display:inline}.gpx ul.info li span{color:#000} \ No newline at end of file diff --git a/src/assets/js/script.js b/src/assets/js/script.js deleted file mode 100644 index 6eb13b4..0000000 --- a/src/assets/js/script.js +++ /dev/null @@ -1,2070 +0,0 @@ - -$(document).ready(function() - { - - - //Global Vars - var windowOpen = false; - var i = 0; - var z = -1; - var finderNav_tabindex = -1; - var app_list_filter_arr = []; - var app_shortcut_arr = []; - var list_all = false; - var debug = false; - var page = 0; - var pos_focus = 0 - var locations = []; - var dir_level = 0; - - - - var current_lng; - var current_lat; - var openweather_api =""; - - var items = ""; - - - var pages_arr = []; - - - var startTime; - var duration_h = 0; - var duration_m = 0; - - //TO-DO - //to know how the settings was before turn on or off - //save the data in a localStorage item - - - - var sleepModeState; - var bluetoothState - var wifiState - var mobileDataState - var tetheringState - var airplaneState = "true" - - - function getSettingState() - { - - bluetoothState = localStorage.getItem("bluetooth") - wifiState = localStorage.getItem("wifi") - mobileDataState = localStorage.getItem("mobileData") - tetheringState = localStorage.getItem("tethering") - } - - - -$("div#window-status").text(windowOpen); - - - - -//execute weather function once - var once_exec = (function() { - var executed = false; - return function() { - if (!executed) { - executed = true; - weather("geolocation") - } - }; - })(); - -//////////////////// -//NOTFICATION////// -////////////////// - - - -function notify(param_title,param_text,param_silent) { - - var options = { - body: param_text, - silent: param_silent - } - // Let's check if the browser supports notifications - if (!("Notification" in window)) { - alert("This browser does not support desktop notification"); - } - - // Let's check whether notification permissions have already been granted - else if (Notification.permission === "granted") { - // If it's okay let's create a notification - var notification = new Notification(param_title,options); - - } - - // Otherwise, we need to ask the user for permission - else if (Notification.permission !== "denied") { - Notification.requestPermission().then(function (permission) { - // If the user accepts, let's create a notification - if (permission === "granted") { - var notification = new Notification(param_title,options); - - - } - }); - } - -} - -///////////////// -////Sleep Mode/// -//////////////// -function sleep() -{ - //init local storage item - sleepModeState = localStorage.getItem("sleepMode") - if(sleepModeState == null) - { - localStorage.setItem("sleepMode","false") - sleepModeState = localStorage.getItem("sleepMode") - } - - - function remove_alarms() - { - var request = navigator.mozAlarms.getAll(); - - request.onsuccess = function () - { - - - this.result.forEach(function (alarm) { - - navigator.mozAlarms.remove(alarm.id); - $('div.alarms div.time').empty(); - - - }); - console.log('operation successful:' + this.result.length + 'alarms pending'); - }; - - request.onerror = function () - { - console.log("An error occurred: " + this.error.name); - }; - } - - - - - function getAlarms() - { - var request = navigator.mozAlarms.getAll(); - request.onsuccess = function () - { - //$('div.alarms div.time').append("

"+this.result.length+""+dateFormat+" moment()) - { - console.log("alarm: between start and end") - } - else - { - - //remove all alarms - remove_alarms(); - //check if user paused the alarms - sleepModeState = localStorage.getItem("sleepMode") - - - //set alarm - - setTimeout( - function() - { - - alarmInterval(m,n) - getAlarms() - - - }, 3000); - - } - - - } - - - - - - - - - - - - - ///////////////////////////// - //////FINDER//////////////// - /////////////////////////// - - - - function finder() - { - app_list_filter_arr.length = 0; - - var finder = new Applait.Finder({ type: "sdcard", debugMode: true }); - - - finder.on("empty", function (needle) - { - //alert("no sdcard found, no openweathermap api-key found"); - return; - }); - - finder.search("custom-launcher.json"); - - - - finder.on("fileFound", function (file, fileinfo, storageName) - { - - var reader = new FileReader() - - - reader.onerror = function(event) - { - alert('shit happens') - reader.abort(); - }; - - reader.onloadend = function (event) - { - - search_result = event.target.result - - //check if json valid - var printError = function(error, explicit) { - console.log("[${explicit ? 'EXPLICIT' : 'INEXPLICIT'}] ${error.name}: ${error.message}"); - } - - try { - - } catch (e) { - if (e instanceof SyntaxError) { - alert("Json file is not valid"); - return; - } else { - - } - - } - var app_list_filter = JSON.parse(search_result); - - - $.each(app_list_filter, function(i, item) { - if(item.dir == undefined) - { - app_list_filter_arr.push([item.app_name,"root"]); - } - else - { - app_list_filter_arr.push([item.app_name,item.dir]); - - } - - - - - if(item.weather) - { - openweather_api = item.weather.owm_api_key; - - if(openweather_api == "") - { - $("div#weather-wrapper").remove() - } - - - - $.each(item.weather.location, function(k, item_location) { - locations.push([k,item_location.position_lat,item_location.position_long]) - }) - } - - - if(item.sleep_mode) - { - startTime = item.sleep_mode.startTime; - duration_h = item.sleep_mode.duration_h; - duration_m = item.sleep_mode.duration_m; - - - sleep() - - } - - }); - - listApps() - - - - //get list of pages - $('.page').each(function() { - var currentElement = $(this); - var value = currentElement.attr('id'); - pages_arr.push(value) - - }); - - - }; - reader.readAsText(file) - }); - $('div#finder').find('div.items[tabindex=0]').focus(); - - } - - -finder() - - - - - -//////////////////////// -//NAVIGATION -///////////////////////// - - - - function nav (move) { - - - if(move == "+1") - { - pos_focus++ - - - - if(pos_focus <= items.length) - { - - $('div[tabindex='+pos_focus+']').focus() - } - - if( pos_focus == items.length) - { - pos_focus = 0; - $('div[tabindex=0]').focus() - - - } - - - } - - if(move == "-1") - { - pos_focus-- - if( pos_focus >= 0) - { - - $('div[tabindex='+pos_focus+']').focus() - - } - - if(pos_focus == -1) - { - pos_focus = items.length-1; - - $('div[tabindex='+pos_focus+']').focus() - - } - } - - - if(move == "slide_right") - { - pos_focus = 0; - if(page < pages_arr.length-1) - { - page++ - - $("div.page").css("display","none"); - $("div#"+pages_arr[page]).css("display","block"); - - - - if(pages_arr[page] == "weather-wrapper") - { - //execute weather() only once - once_exec() - //weather() - } - - - if(pages_arr[page] == "quick-settings") - { - items = document.querySelectorAll('div#quick-settings > div.items'); - $('div#quick-settings').find('div.items[tabindex=0]').focus(); - - } - - if(pages_arr[page] == "finder") - { - items = document.querySelectorAll('div#app-list > div.items'); - $('div#app-list').find('div.items[tabindex=0]').focus(); - - } - - if(pages_arr[page] == "weather-wrapper") - { - items = document.querySelectorAll('div#weather-wrapper div#weather-locations > div.items'); - - } - - - if(pages_arr[page] == "dev") - { - ble_test(); - - } - - } - } - - - if(move == "slide_left") - { - pos_focus = 0; - if(page > 0) - { - page-- - - $("div.page").css("display","none"); - $("div#"+pages_arr[page]).css("display","block"); - - if(pages_arr[page] == "quick-settings") - { - items = document.querySelectorAll('div#quick-settings > div.items'); - $('div#quick-settings').find('div.items[tabindex=0]').focus(); - } - - - if(pages_arr[page] == "finder") - { - items = document.querySelectorAll('div#app-list > div.items'); - $('div#app-list').find('div.items[tabindex=0]').focus(); - } - - if(pages_arr[page] == "weather-wrapper") - { - items = document.querySelectorAll('div#weather-wrapper div#weather-locations > div.items'); - - } - - - if(pages_arr[page] == "dev") - { - ble_test(); - - } - } - } - - - - - - - } - - -///////////////////////// -//LIST APPS -///////////////////////// - - - - - var last_dir; - var dirs = []; - function listApps(param) - { - z = -1 - $("div#app-list").empty(); - var request = window.navigator.mozApps.mgmt.getAll() - - - request.onsuccess = function() - { - if (request.result) - { - - var data = request.result; - - //list all apps - if (param == true) - { - $.each(data, function(i, item) { - z++ - - $("div#app-list").append('
'+item.manifest.name+'
'); - }) - - } - - else - { - for(var k = 0; k< app_list_filter_arr.length-1; k++) - { - - - $.each(data, function(i, item) - { - - - - if (item.manifest.name == app_list_filter_arr[k][0]) - { - - - if(app_list_filter_arr[k][1] == "root") - { - $("div#app-list").append('
'+item.manifest.name+'
'); - } - - if(app_list_filter_arr[k][1] != "root") - { - - if($.inArray(app_list_filter_arr[k][1], dirs) == -1) - { - dirs.push(app_list_filter_arr[k][1]) - $("div#app-list").append('
'+app_list_filter_arr[k][1]+''+item.manifest.name+'
'); - - } - - //first element of dir - else - { - $("div#app-list").append('
'+app_list_filter_arr[k][1]+''+item.manifest.name+'
'); - } - - } - - } - - }) - } - - } - - items = $('div#app-list > div.items:visible'); - pos_focus = 0; - //dir_view() - set_tabindex() - - - } - - - else - { - alert("No apps"); - } - }; - - - request.onerror = function() { - // Display error name from the DOMError object - alert("Error: " + request.error.name); - }; - - - } - - - -function set_tabindex() -{ - var items_list = $('div#finder div.items:visible'); - items = $('div#app-list > div.items:visible'); - - for(var i =-1; i < items.length; i++) - { - $(items[i]).attr('tabindex',i) - pos_focus = 0 - $('div#finder').find('div.items[tabindex=0]').focus(); - } -} - - - -function dir_view() -{ - - for (var i = 0; i < dirs.length; i++) { - var test = document.getElementsByClassName(dirs[i]) - $(test).addClass("child-of-dir") - $(test).first().removeClass("child-of-dir") - } -set_tabindex() -} - - - -function dir_nav() -{ - if(dir_level == 1) - { - $("div.items").css("display","block"); - $("div.items").children('.dir-name').css('display','block') - $("div.items").children('.app-name').css('display','none') - $("div.child-of-dir").css("display","none"); - - $('div#finder').find('div.items[tabindex=0]').focus(); - $('div#finder div#app-list .dir').css("border-left","4px solid silver") - pos_focus = 0 - dir_level = 0; - set_tabindex() - - } - - -} - - - - - -////////////////// -//LAUNCH APP -////////////////// - -function launchApp() -{ - if(page == 0) - { - - var selected_button = $(":focus")[0]; - var app_url = selected_button.getAttribute('data-url'); - //if element is a dir - if($(selected_button).hasClass('dir') && dir_level == 0) - { - - $("div.items").css("display","none"); - var same_class = $("*:focus").eq(0).attr('class') - var elems = document.getElementsByClassName(same_class); - $(elems).children('.dir-name').css('display','none') - $(elems).children('.app-name').css('display','block') - $(elems).css("display","block"); - pos_focus = 0 - $('div#finder').find('div.items[tabindex=0]').focus(); - dir_level = 1; - $('div#finder div#app-list .dir').css("border","0px solid silver") - set_tabindex() - - - return; - - } - //if element is not a dir start app - else - { - var request = window.navigator.mozApps.mgmt.getAll(); - request.onsuccess = function() - { - if (request.result) - { - request.result[app_url].launch() - return; - } - - } - } - - - - - } -} - - -////////////////// -//DELETE APP -////////////////// - -function delete_app() -{ - if(page == 0) - { - - var request = window.navigator.mozApps.mgmt.getAll() - request.onsuccess = function() { - if (request.result) { - - - var selected_button = $(":focus")[0]; - var app_url = selected_button.getAttribute('data-url'); - var app_name = selected_button.getAttribute('data-app_name'); - var delete_request= navigator.mozApps.mgmt.uninstall(request.result[app_url]) - - - delete_request.error = function(event) - { - alert("error: app not unistalled") - }; - - delete_request.onsuccess = function(event) - { - var text = app_name+" successfully uninstalled"; - notify("App",text) - finder(); - setTimeout(function(){ - items = document.querySelectorAll('div#app-list > div.items'); - $('div#app-list').find('div.items[tabindex=0]').focus(); - },3000); - }; - - } - } - } - - -} - - - - -////////////////// -//SHORTCUT -////////////////// - - -function focus_shortcut(shortcut_number) -{ - if(page == 0) - { - var items = document.querySelectorAll('.items'); - var targetElement = items[shortcut_number]; - targetElement.focus(); - launchApp(); - } -} - - - - - -////////////////// -//Quick-Settings -////////////////// - -var selected_button; -function quick_settings_toggle() -{ - if(pages_arr[page] == "quick-settings") - { - selected_button = $(":focus")[0]; - var quick_settings_item = selected_button.getAttribute('data-function'); - - switch (true) - { - case (quick_settings_item == "bluetooth"): - bluetooth_toggle("toggle"); - break; - - case (quick_settings_item == "wifi"): - wifi_toggle("toggle"); - break; - - case (quick_settings_item == "mobile_data"): - data_toggle("toggle"); - break; - - - case (quick_settings_item == "tethering"): - tethering_toggle("toggle"); - break; - - case (quick_settings_item == "airplane"): - airplane_toggle("toggle"); - break; - - ///alarm on/off - case (quick_settings_item == "sleep"): - sleepModeState = localStorage.getItem("sleepMode") - - - - if(sleepModeState == "true") - { - localStorage.setItem("sleepMode","false") - $('div.alarms div.time div').css("opacity","0.5") - $('div.alarms div.time div').css("font-style","italic") - return - - - } - - if(sleepModeState == "false") - { - localStorage.setItem("sleepMode","true") - $('div.alarms div.time div').css("opacity","1") - $('div.alarms div.time div').css("font-style","normal") - - } - - - - break; - } - - } -} - - - - -/////////////// -///BLUETOOTH/////// -///////////// -///toggle --- toggle setting -///get --- to know the current state -///on / off ---- enable / disable strict - - - -function bluetooth_toggle(param) -{ - - - var lock = navigator.mozSettings.createLock(); - var setting = lock.get('bluetooth.enabled'); - - - - setting.onsuccess = function () - { - //strict - if(param == "on") - { - var lock = navigator.mozSettings.createLock(); - var result = lock.set({ - 'bluetooth.enabled': true - }); - - result.onsuccess = function () - { - navigator.mozBluetooth.defaultAdapter.enable(); - $("div#quick-settings div.bluetooth").css("opacity","1") - $("div#quick-settings div.bluetooth").css("font-style","normal") - localStorage.setItem("bluetooth","true") - airplaneState = "false" - airplane_toggle("get"); - - - - } - - result.onerror = function () - { - alert("An error occure, the settings remain unchanged"); - } - - } - - if(param == "off") - { - var lock = navigator.mozSettings.createLock(); - var result = lock.set({ - 'bluetooth.enabled': false - }); - - - - result.onsuccess = function () - { - navigator.mozBluetooth.defaultAdapter.disable(); - $("div#quick-settings div.bluetooth").css("opacity","0.5") - $("div#quick-settings div.bluetooth").css("font-style","italic") - localStorage.setItem("bluetooth","false") - } - - result.onerror = function () - { - alert("An error occure, the settings remain unchanged"); - } - - - } - - - - //toogle - var callback = JSON.stringify(setting.result); - - - - if(callback == '{"bluetooth.enabled":true}') - { - - - if(param == "toggle") - { - bluetooth_toggle("off"); - - } - - - - if(param == "get") - { - $("div#quick-settings div.bluetooth").css("opacity","1") - $("div#quick-settings div.bluetooth").css("font-style","normal") - localStorage.setItem("bluetooth","true") - airplaneState = "false" - - - - } - - - - }; - - if(callback == '{"bluetooth.enabled":false}') - { - if(param == "toggle") - { - - bluetooth_toggle("on"); - - } - - if(param == "get") - { - $("div#quick-settings div.bluetooth").css("opacity","0.5") - $("div#quick-settings div.bluetooth").css("font-style","italic") - localStorage.setItem("bluetooth","false") - - } - - - }; - - } - - - setting.onerror = function () - { - console.warn('An error occured: ' + setting.error); - } - - -} - - - -/////////////// -///WIFI/////// -///////////// - - -function wifi_toggle(param) -{ - - - var lock = navigator.mozSettings.createLock(); - var setting = lock.get('wifi.enabled'); - - - - setting.onsuccess = function () - { - //strict - if(param == "on") - { - var lock = navigator.mozSettings.createLock(); - var result = lock.set({ - 'wifi.enabled': true - }); - - result.onsuccess = function () - { - $("div#quick-settings div.wifi").css("opacity","1") - $("div#quick-settings div.wifi").css("font-style","normal") - localStorage.setItem("wifi","true") - airplaneState = "false" - airplane_toggle("get"); - - } - - result.onerror = function () - { - alert("An error occure, the settings remain unchanged"); - } - - } - - if(param == "off") - { - var lock = navigator.mozSettings.createLock(); - var result = lock.set({ - 'wifi.enabled': false - }); - - - result.onsuccess = function () - { - $("div#quick-settings div.wifi").css("opacity","0.5") - $("div#quick-settings div.wifi").css("font-style","italic") - localStorage.setItem("wifi","false") - } - - result.onerror = function () - { - alert("An error occure, the settings remain unchanged"); - } - - - } - - - - //toogle - var callback = JSON.stringify(setting.result); - - - - if(callback == '{"wifi.enabled":true}') - { - - - if(param == "toggle") - { - wifi_toggle("off"); - - } - - - if(param == "get") - { - $("div#quick-settings div.wifi").css("opacity","1") - $("div#quick-settings div.wifi").css("font-style","normal") - localStorage.setItem("wifi","true") - airplaneState = "false" - - - } - - - - }; - - if(callback == '{"wifi.enabled":false}') - { - if(param == "toggle") - { - - wifi_toggle("on"); - - } - - if(param == "get") - { - $("div#quick-settings div.wifi").css("opacity","0.5") - $("div#quick-settings div.wifi").css("font-style","italic") - localStorage.setItem("wifi","false") - - } - - - }; - - } - - - setting.onerror = function () - { - console.warn('An error occured: ' + setting.error); - } - - -} - - - - - -///////////////////////// -///DATA CONNECTION/////// -//////////////////////// - - -function data_toggle(param) -{ - - - var lock = navigator.mozSettings.createLock(); - var setting = lock.get('ril.data.enabled'); - - - - setting.onsuccess = function () - { - //strict - if(param == "on") - { - var lock = navigator.mozSettings.createLock(); - var result = lock.set({ - 'ril.data.enabled': true, - 'ril.radio.disabled': false - }); - - result.onsuccess = function () - { - - - $("div#quick-settings div.mobile-data").css("opacity","1") - $("div#quick-settings div.mobile-data").css("font-style","normal") - localStorage.setItem("mobileData","true") - airplaneState = "false" - airplane_toggle("get"); - - } - - result.onerror = function () - { - alert("An error occure, the settings remain unchanged"); - } - - } - - if(param == "off") - { - var lock = navigator.mozSettings.createLock(); - var result = lock.set({ - 'ril.data.enabled': false, - 'ril.radio.disabled': true - }); - - - result.onsuccess = function () - { - $("div#quick-settings div.mobile-data").css("opacity","0.5") - $("div#quick-settings div.mobile-data").css("font-style","italic") - localStorage.setItem("mobileData","false") - } - - result.onerror = function () - { - alert("An error occure, the settings remain unchanged"); - } - - - } - - - - //toogle - var callback = JSON.stringify(setting.result); - - - - if(callback == '{"ril.data.enabled":true}') - { - - - if(param == "toggle") - { - data_toggle("off"); - - } - - - - if(param == "get") - { - $("div#quick-settings div.mobile-data").css("opacity","1") - $("div#quick-settings div.mobile-data").css("font-style","normal") - localStorage.setItem("mobileData","true") - airplaneState = "false" - - } - - - - }; - - if(callback == '{"ril.data.enabled":false}') - { - if(param == "toggle") - { - - data_toggle("on"); - - } - - if(param == "get") - { - $("div#quick-settings div.mobile-data").css("opacity","0.5") - $("div#quick-settings div.mobile-data").css("font-style","italic") - localStorage.setItem("mobileData","false") - - } - - - }; - - } - - - setting.onerror = function () - { - console.warn('An error occured: ' + setting.error); - } - - -} - - -/////////////////// -///TETHERING/////// -////////////////// - - -function tethering_toggle(param) -{ - - - var lock = navigator.mozSettings.createLock(); - var setting = lock.get('tethering.wifi.enabled'); - - - - setting.onsuccess = function () - { - //strict - if(param == "on") - { - var lock = navigator.mozSettings.createLock(); - var result = lock.set({ - 'tethering.wifi.enabled': true - }); - - result.onsuccess = function () - { - - - $("div#quick-settings div.tethering").css("opacity","1") - $("div#quick-settings div.tethering").css("font-style","normal") - localStorage.setItem("tethering","true") - - //get PWD - var getPWD = lock.get('tethering.wifi.security.password'); - getPWD.onsuccess = function () - { - - - var stringify_result = JSON.stringify(getPWD.result) - var callback = JSON.parse(stringify_result) - $("div#message-box").css("display","block") - $("div#message-box").text(callback['tethering.wifi.security.password']) - - - setTimeout(function() { - $("div#message-box").text(""); - $("div#message-box").css("display","none"); - }, 10000); - - } - - getPWD.onerror = function () - { - alert("Can't show password") - } - - - } - - result.onerror = function () - { - alert("An error occure, the settings remain unchanged"); - } - - } - - if(param == "off") - { - var lock = navigator.mozSettings.createLock(); - var result = lock.set({ - 'tethering.wifi.enabled': false - }); - - - result.onsuccess = function () - { - $("div#quick-settings div.tethering").css("opacity","0.5") - $("div#quick-settings div.tethering").css("font-style","italic") - localStorage.setItem("tethering","false") - } - - result.onerror = function () - { - alert("An error occure, the settings remain unchanged"); - } - - - } - - - - //toogle - var callback = JSON.stringify(setting.result); - - - - if(callback == '{"tethering.wifi.enabled":true}') - { - - - if(param == "toggle") - { - tethering_toggle("off"); - - } - - - - if(param == "get") - { - $("div#quick-settings div.tethering").css("opacity","1") - $("div#quick-settings div.tethering").css("font-style","normal") - localStorage.setItem("tethering","true") - - } - - - - }; - - if(callback == '{"tethering.wifi.enabled":false}') - { - if(param == "toggle") - { - - tethering_toggle("on"); - - } - - if(param == "get") - { - $("div#quick-settings div.tethering").css("opacity","0.5") - $("div#quick-settings div.tethering").css("font-style","italic") - localStorage.setItem("tethering","false") - - } - - - }; - - } - - - setting.onerror = function () - { - console.warn('An error occured: ' + setting.error); - } - - -} - - - -/////AIRPLANE - - - -function airplane_toggle(param) -{ - if(param == "toggle" && airplaneState == "true") - { - airplane_toggle("off") - airplaneState = "false" - return - } - - if(param == "toggle" && airplaneState == "false") - { - airplane_toggle("on") - airplaneState = "true" - - } - - - - - if(param == "off") - { - $("div#quick-settings div.airplane").css("opacity","0.5") - $("div#quick-settings div.airplane").css("font-style","italic") - // - bluetooth_toggle("on") - wifi_toggle("on") - data_toggle("on") - - } - - if(param == "on") - { - $("div#quick-settings div.airplane").css("opacity","1") - $("div#quick-settings div.airplane").css("font-style","normal") - //airplaneState = "true" - bluetooth_toggle("off") - wifi_toggle("off") - data_toggle("off") - - } - - if(param = "get") - { - - - if(airplaneState == "true") - { - $("div#quick-settings div.airplane").css("opacity","1") - $("div#quick-settings div.airplane").css("font-style","normal") - } - - if(airplaneState == "false") - { - $("div#quick-settings div.airplane").css("opacity","0.5") - $("div#quick-settings div.airplane").css("font-style","italic") - } - } - - - -} - - - -//get status on start -wifi_toggle("get"); -bluetooth_toggle("get"); -data_toggle("get"); -tethering_toggle("get"); - - - setTimeout( - function() - { - - airplane_toggle("get"); - - - }, 1000); - - - - - -//////////////////// -////GEOLOCATION///// -/////////////////// - -function select_location() -{ - pos_focus = 0 - $('div#weather-wrapper div#locations').find('div.items[tabindex=0]').focus(); - - k = -1; - $("div#weather-wrapper div#locations").empty(); - for(var i = 0; i < locations.length; i++) - { - k++; - $("div#weather-wrapper div#locations").append("
"+locations[i][0]+"
") - } - - if(pages_arr[page] == "weather-wrapper") - { - - $("div#weather-wrapper div#locations").css("display","block") - $("div#weather-wrapper div#location").css("display","none") - $("div#weather-wrapper div#locations div").first().focus(); - items = document.querySelectorAll('div#weather-wrapper div#locations > div.items'); - - } -} - - - - -function choice_location() -{ - - if(pages_arr[page] == "weather-wrapper") - { - - - var selected_button = $(":focus")[0]; - current_lng = selected_button.getAttribute('data-long'); - current_lat = selected_button.getAttribute('data-lat'); - location_name = $(selected_button).text(); - $("h1#location_name").text(location_name); - - - $("div#weather-wrapper div#locations").css("display","none"); - $("div#weather-wrapper div#location").css("display","block"); - weather("notgeolocation"); - - - } -} - - -function getCityName() -{ - - var request_url = "https://nominatim.openstreetmap.org/reverse?format=json&lat="+current_lat+"&lon="+current_lng+"&zoom=18&addressdetails=1"; - var jqxhr = $.getJSON(request_url, function(data) { - - }).done(function(data) { - $.each(data.address, function(key, val) { - if(key === "town") - { - $("h1#location_name").text(val); - } - - }); - }) - .fail(function() { - alert("error") - }) - .always(function() { - }); - -} - - - -var weather_data = []; - -function weather(param) -{ - - weather_data.length = 0; - - if(param == "geolocation") - { - var options = { - enableHighAccuracy: true, - timeout: 30000, - maximumAge: 0 - }; - - function success(pos) { - var crd = pos.coords; - - - - current_lng = crd.longitude; - current_lat = crd.latitude; - fetch_weather_data() - getCityName() - - } - - function error(err) { - alert("Position not found"+err.code+":"+err.message); - select_location(); - } - - navigator.geolocation.getCurrentPosition(success, error, options); - } - - else - { - fetch_weather_data(); - updateChart(); - - } - - - - - -function fetch_weather_data() -{ - -var request_url = "https://api.openweathermap.org/data/2.5/forecast?lat="+current_lat+"&lon="+current_lng+"&units=metric&APPID="+openweather_api; -var jqxhr = $.getJSON(request_url, function(data) { - -}) - .done(function(data) { - - var wind_dir = ""; - function direction(in_val) - { - var degree = data.list[in_val].wind.deg; - - switch (true) - { - case (degree>337.5): - wind_dir = 'N'; - break; - case (degree>292.5): - wind_dir = 'N'; - break; - case (degree>247.5): - wind_dir = 'W'; - break; - case (degree>202.5): - wind_dir = 'SW'; - break; - case (degree>157.5): - wind_dir = 'S'; - break; - case (degree>122.5): - wind_dir = 'SE'; - break; - case (degree>67.5): - wind_dir = 'E'; - break; - case (degree>22.5): - wind_dir = 'NE'; - } - - } - - - - - - //cloning elements - $('div#weather section').not(':first').remove(); - //$("div#weather section").first().css("display","block") - - - - var template = $("section#forecast-0") - var k = 0; - - for (var i = 0; i < 20; i++) - { - k++; - //create elements - template.clone() - .attr("id","forecast-"+k) - .appendTo('div#weather'); - - //add data - - - var date_format = moment.unix(data.list[i].dt).format("ddd DD MMM HH:mm"); - var date_format_hhmm = moment.unix(data.list[i].dt).format("HH:mm"); - var temp = Math.round(data.list[i].main.temp); - var rain_data = 0; - - - if(data.list[i].rain != undefined) - { - rain_data = data.list[i].rain["3h"]; - rain_data = Number(rain_data) - } - else - { - rain_data = 0; - } - - - - - - - direction(i) - - - $('div#location section#forecast-'+i+' div#temp').text(Math.round(data.list[i].main.temp)+"°"); - $('div#location section#forecast-'+i+' div#wind div#wind-speed div#wind-speed-val').text(data.list[i].wind.speed); - $('div#location section#forecast-'+i+' div#wind div#wind-dir').text(wind_dir); - $('div#location section#forecast-'+i+' div#pressure div#pressure-val').text(Math.round(data.list[i].main.pressure)); - $('div#location section#forecast-'+i+' div.title div.forecast-time').text(date_format); - $('div#location section#forecast-'+i+' div#icon img').attr("src","https://openweathermap.org/img/w/"+data.list[i].weather[0].icon+".png"); - - - weather_data.push([date_format_hhmm,temp,rain_data]) - } - - $("div#weather-wrapper div#message").css('display','none') - $("div#location").css('display','block') - //$("div#weather section").first().css("display","none") - - - - - //chart - addChart() - - - }) - .fail(function() { - //alert( "error" ); - }) - .always(function() { - //alert( "complete" ); - }); - - -} - -} - -var mixedChart; - - function addChart() - { - - var ctx = document.getElementById('myChart'); - var ctx = document.getElementById('myChart').getContext('2d'); - - mixedChart = new Chart(ctx, { - type: 'line', - data: { - - datasets: [{ - label: 'temp', - yAxisID: 'id1', - data: [weather_data[0][1], weather_data[1][1], weather_data[2][1], weather_data[3][1]], - borderColor:'rgba(255,0,0,1)' - }, { - label: 'rain', - yAxisID: 'id2', - data: [weather_data[0][2],weather_data[1][2],weather_data[2][2],weather_data[3][2]], - borderColor:'rgba(0,0,255,1)' - - }], - labels: [weather_data[0][0], weather_data[1][0], weather_data[2][0], weather_data[3][0]] - }, - options: { - legend: { - display: false, - labels: { - - position: 'bottom' - } - }, - - scales: { - yAxes: [{ - id: 'id1', - type: 'linear', - position: 'left', - }, { - id: 'id2', - type: 'linear', - position: 'right', - ticks: { - min: 0 - } - - }] - } - - - } - - }); - } - - - //update chart - function updateChart() - { - mixedChart.update(); - } - - - - - - - - - - -var key_time -var press_time = 0; -var longpress = false; -function func_interval() -{ - longpress = false; - press_time = 0; - key_time = setInterval(function() { - press_time++ - - if(press_time > 2) - { - longpress = true; - } - if(press_time < 2) - { - longpress = false; - } - - }, 1000); - - -} - - - ////////////////////////// - ////KEYPAD TRIGGER//////////// - ///////////////////////// -function handleKeyDown(evt) - -{ - - switch (evt.key) - { - case 'Enter': - func_interval(); - quick_settings_toggle(); - - - break; - - case 'Backspace': - evt.preventDefault(); - - if(dir_level == 0) - { - window.close(); - } - dir_nav(); - break; - - - - } -} - - - - function handleKeyUp(evt) { - clearInterval(key_time) - - switch (evt.key) { - - case 'Enter': - if(longpress == false) - { - launchApp(); - choice_location(); - - } - - if(longpress == true) - { - delete_app(); - } - break; - - case 'Backspace': - evt.preventDefault(); - break; - - case 'ArrowDown': - nav("+1") - break; - - case 'ArrowUp': - nav("-1") - break; - - case 'ArrowRight': - nav("slide_right") - break; - - case 'ArrowLeft': - nav("slide_left"); - - break; - - case 'SoftLeft': - select_location(); - break; - - - case '1': - //checkUpdate(); - focus_shortcut(0) - break; - - case '2': - focus_shortcut(1) - break; - - break; - - case '3': - focus_shortcut(2) - break; - - case '4': - focus_shortcut(3) - break; - - case '5': - focus_shortcut(4) - break; - - case '6': - focus_shortcut(5) - break; - - case '7': - focus_shortcut(6) - break; - - case '8': - focus_shortcut(7) - break; - - case '9': - focus_shortcut(8) - break; - - case '0': - listApps(true); - break; - - - } - - }; - - - - document.addEventListener('keydown', handleKeyDown); - document.addEventListener('keyup', handleKeyUp); - - - ////////////////////////// - ////BUG OUTPUT//////////// - ///////////////////////// - -if(debug == true) -{ - $(window).on("error", function(evt) { - - console.log("jQuery error event:", evt); - var e = evt.originalEvent; // get the javascript event - console.log("original event:", e); - if (e.message) { - alert("Error:\n\t" + e.message + "\nLine:\n\t" + e.lineno + "\nFile:\n\t" + e.filename); - } else { - alert("Error:\n\t" + e.type + "\nElement:\n\t" + (e.srcElement || e.target)); - } - }); - -} - - - - -}); - diff --git a/src/assets/js/script.min.js b/src/assets/js/script.min.js deleted file mode 100644 index 6daceee..0000000 --- a/src/assets/js/script.min.js +++ /dev/null @@ -1 +0,0 @@ -$(document).ready(function(){var t=.001,a=0,e=0,n=16,i=0,l="";$("div#location").text("ready");var c=L.map("map",{zoomControl:!1,dragging:!1,keyboard:!0}).fitWorld();L.tileLayer("https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw",{maxZoom:18,attribution:'Map data ©
OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',id:"mapbox.streets"}).addTo(c),c.on("locationfound",function(o){var t=o.accuracy/2;l=L.marker(o.latlng).addTo(c),L.circle(o.latlng,t).addTo(c),i=o.latlng,a=i.lng,e=i.lat,$("div#location div#lat").text(e),$("div#location div#lng").text(a)}),c.on("locationerror",function(o){alert(o.message)}),c.locate({setView:!0,maxZoom:16}),n=16,s();var o={url:"https://nominatim.openstreetmap.org/search?format=json&q={s}",jsonpParam:"json_callback",formatData:function(o){var t,a,e={},n=[];for(var i in o)t=(n=o[i].display_name.split(","))[0]+", "+n[1],a=L.latLng(o[i].lat,o[i].lon),e[t]=a;return e},textPlaceholder:"Search...",autoType:!0,tipAutoSubmit:!0,autoCollapse:!0,collapsed:!1,autoCollapseTime:1e4,delayType:800,marker:{icon:!0}},r=new L.Control.Search(o);function d(t){function o(o){l.setLatLng([o.coords.latitude,o.coords.longitude]).update(),c.flyTo(new L.LatLng(o.coords.latitude,o.coords.longitude),16),n=16,s(),a=o.coords.longitude,e=o.coords.latitude,$("div#location div#lat").text(e),$("div#location div#lng").text(a),1==t&&$("div#location").css("display","block")}navigator.geolocation?navigator.geolocation.getCurrentPosition(o):alert("New Position not found.")}function s(){return n<6&&(t=1,document.getElementById("zoom-level").innerHTML=n+t),6 - - - Custom-Launcher - - - - - - - - - - - - - - - -
- - -
- - - - -
-
-
- - - - - -
- -
wifi
-
bluetooth
-
mobile data
-
tethering
-
airplane
-
-

Sleep Mode

-
-
- -
- - - - - - - -
- -
- Please wait... -
- -
- -
-
-

- -
temprain
-
-
- -
- -
- -
- -
- -
-
-
-
- -
- -
-
-
-
-
m/sec
-
-
- -
-
-
hpa
-
-
- -
- -
- -
- - -
- - - + + + + + +
+
+ + + + +
+
+
+ + + + + +
+
wifi
+
+ bluetooth +
+
+ mobile data +
+
+ tethering +
+
+ airplane +
+
+

Sleep Mode

+
+
+
+ + + + + +
+
+ Please wait... +
+ +
+ +
+
+

+ +
temprain
+
+
+
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+
m/sec
+
+
+ +
+
+
hpa
+
+
+
+
+
+
+ + - - - -
- - +
+
+
+ - - - - - - - + + + + + + diff --git a/src/script.js b/src/script.js new file mode 100644 index 0000000..659d0ff --- /dev/null +++ b/src/script.js @@ -0,0 +1,1554 @@ +$(document).ready(function() { + //Global Vars + var windowOpen = false; + var i = 0; + var z = -1; + var finderNav_tabindex = -1; + var app_list_filter_arr = []; + var app_shortcut_arr = []; + var list_all = false; + var debug = false; + var page = 0; + var pos_focus = 0; + var locations = []; + var dir_level = 0; + + var current_lng; + var current_lat; + var openweather_api = ""; + + var items = ""; + + var pages_arr = []; + + var startTime; + var duration_h = 0; + var duration_m = 0; + + //TO-DO + //to know how the settings was before turn on or off + //save the data in a localStorage item + + var sleepModeState; + var bluetoothState; + var wifiState; + var mobileDataState; + var tetheringState; + var airplaneState = "true"; + + function getSettingState() { + bluetoothState = localStorage.getItem("bluetooth"); + wifiState = localStorage.getItem("wifi"); + mobileDataState = localStorage.getItem("mobileData"); + tetheringState = localStorage.getItem("tethering"); + } + + $("div#window-status").text(windowOpen); + + //execute weather function once + var once_exec = (function() { + var executed = false; + return function() { + if (!executed) { + executed = true; + weather("geolocation"); + } + }; + })(); + + //////////////////// + //NOTFICATION////// + ////////////////// + + function notify(param_title, param_text, param_silent) { + var options = { + body: param_text, + silent: param_silent + }; + // Let's check if the browser supports notifications + if (!("Notification" in window)) { + alert("This browser does not support desktop notification"); + } + + // Let's check whether notification permissions have already been granted + else if (Notification.permission === "granted") { + // If it's okay let's create a notification + var notification = new Notification(param_title, options); + } + + // Otherwise, we need to ask the user for permission + else if (Notification.permission !== "denied") { + Notification.requestPermission().then(function(permission) { + // If the user accepts, let's create a notification + if (permission === "granted") { + var notification = new Notification(param_title, options); + } + }); + } + } + + ///////////////// + ////Sleep Mode/// + //////////////// + function sleep() { + //init local storage item + sleepModeState = localStorage.getItem("sleepMode"); + if (sleepModeState == null) { + localStorage.setItem("sleepMode", "false"); + sleepModeState = localStorage.getItem("sleepMode"); + } + + function remove_alarms() { + var request = navigator.mozAlarms.getAll(); + + request.onsuccess = function() { + this.result.forEach(function(alarm) { + navigator.mozAlarms.remove(alarm.id); + $("div.alarms div.time").empty(); + }); + console.log( + "operation successful:" + this.result.length + "alarms pending" + ); + }; + + request.onerror = function() { + console.log("An error occurred: " + this.error.name); + }; + } + + function getAlarms() { + var request = navigator.mozAlarms.getAll(); + request.onsuccess = function() { + //$('div.alarms div.time').append("
"+this.result.length+"" + dateFormat + " moment()) { + console.log("alarm: between start and end"); + } else { + //remove all alarms + remove_alarms(); + //check if user paused the alarms + sleepModeState = localStorage.getItem("sleepMode"); + + //set alarm + + setTimeout(function() { + alarmInterval(m, n); + getAlarms(); + }, 3000); + } + } + + ///////////////////////////// + //////FINDER//////////////// + /////////////////////////// + + function finder() { + app_list_filter_arr.length = 0; + + var finder = new Applait.Finder({ type: "sdcard", debugMode: true }); + + finder.on("empty", function(needle) { + //alert("no sdcard found, no openweathermap api-key found"); + return; + }); + + finder.search("custom-launcher.json"); + + finder.on("fileFound", function(file, fileinfo, storageName) { + var reader = new FileReader(); + + reader.onerror = function(event) { + alert("shit happens"); + reader.abort(); + }; + + reader.onloadend = function(event) { + search_result = event.target.result; + + //check if json valid + var printError = function(error, explicit) { + console.log( + "[${explicit ? 'EXPLICIT' : 'INEXPLICIT'}] ${error.name}: ${error.message}" + ); + }; + + try { + } catch (e) { + if (e instanceof SyntaxError) { + alert("Json file is not valid"); + return; + } else { + } + } + var app_list_filter = JSON.parse(search_result); + + $.each(app_list_filter, function(i, item) { + if (item.dir == undefined) { + app_list_filter_arr.push([item.app_name, "root"]); + } else { + app_list_filter_arr.push([item.app_name, item.dir]); + } + + if (item.weather) { + openweather_api = item.weather.owm_api_key; + + if (openweather_api == "") { + $("div#weather-wrapper").remove(); + } + + $.each(item.weather.location, function(k, item_location) { + locations.push([ + k, + item_location.position_lat, + item_location.position_long + ]); + }); + } + + if (item.sleep_mode) { + startTime = item.sleep_mode.startTime; + duration_h = item.sleep_mode.duration_h; + duration_m = item.sleep_mode.duration_m; + + sleep(); + } + }); + + listApps(); + + //get list of pages + $(".page").each(function() { + var currentElement = $(this); + var value = currentElement.attr("id"); + pages_arr.push(value); + }); + }; + reader.readAsText(file); + }); + $("div#finder") + .find("div.items[tabindex=0]") + .focus(); + } + + finder(); + + //////////////////////// + //NAVIGATION + ///////////////////////// + + function nav(move) { + if (move == "+1") { + pos_focus++; + + if (pos_focus <= items.length) { + $("div[tabindex=" + pos_focus + "]").focus(); + } + + if (pos_focus == items.length) { + pos_focus = 0; + $("div[tabindex=0]").focus(); + } + } + + if (move == "-1") { + pos_focus--; + if (pos_focus >= 0) { + $("div[tabindex=" + pos_focus + "]").focus(); + } + + if (pos_focus == -1) { + pos_focus = items.length - 1; + + $("div[tabindex=" + pos_focus + "]").focus(); + } + } + + if (move == "slide_right") { + pos_focus = 0; + if (page < pages_arr.length - 1) { + page++; + + $("div.page").css("display", "none"); + $("div#" + pages_arr[page]).css("display", "block"); + + if (pages_arr[page] == "weather-wrapper") { + //execute weather() only once + once_exec(); + //weather() + } + + if (pages_arr[page] == "quick-settings") { + items = document.querySelectorAll("div#quick-settings > div.items"); + $("div#quick-settings") + .find("div.items[tabindex=0]") + .focus(); + } + + if (pages_arr[page] == "finder") { + items = document.querySelectorAll("div#app-list > div.items"); + $("div#app-list") + .find("div.items[tabindex=0]") + .focus(); + } + + if (pages_arr[page] == "weather-wrapper") { + items = document.querySelectorAll( + "div#weather-wrapper div#weather-locations > div.items" + ); + } + + if (pages_arr[page] == "dev") { + ble_test(); + } + } + } + + if (move == "slide_left") { + pos_focus = 0; + if (page > 0) { + page--; + + $("div.page").css("display", "none"); + $("div#" + pages_arr[page]).css("display", "block"); + + if (pages_arr[page] == "quick-settings") { + items = document.querySelectorAll("div#quick-settings > div.items"); + $("div#quick-settings") + .find("div.items[tabindex=0]") + .focus(); + } + + if (pages_arr[page] == "finder") { + items = document.querySelectorAll("div#app-list > div.items"); + $("div#app-list") + .find("div.items[tabindex=0]") + .focus(); + } + + if (pages_arr[page] == "weather-wrapper") { + items = document.querySelectorAll( + "div#weather-wrapper div#weather-locations > div.items" + ); + } + + if (pages_arr[page] == "dev") { + ble_test(); + } + } + } + } + + ///////////////////////// + //LIST APPS + ///////////////////////// + + var last_dir; + var dirs = []; + function listApps(param) { + z = -1; + $("div#app-list").empty(); + var request = window.navigator.mozApps.mgmt.getAll(); + + request.onsuccess = function() { + if (request.result) { + var data = request.result; + + //list all apps + if (param == true) { + $.each(data, function(i, item) { + z++; + + $("div#app-list").append( + '
' + + item.manifest.name + + "
" + ); + }); + } else { + for (var k = 0; k < app_list_filter_arr.length - 1; k++) { + $.each(data, function(i, item) { + if (item.manifest.name == app_list_filter_arr[k][0]) { + if (app_list_filter_arr[k][1] == "root") { + $("div#app-list").append( + '
' + + item.manifest.name + + "
" + ); + } + + if (app_list_filter_arr[k][1] != "root") { + if ($.inArray(app_list_filter_arr[k][1], dirs) == -1) { + dirs.push(app_list_filter_arr[k][1]); + $("div#app-list").append( + '
' + + app_list_filter_arr[k][1] + + '' + + item.manifest.name + + "
" + ); + } + + //first element of dir + else { + $("div#app-list").append( + '
' + + app_list_filter_arr[k][1] + + '' + + item.manifest.name + + "
" + ); + } + } + } + }); + } + } + + items = $("div#app-list > div.items:visible"); + pos_focus = 0; + //dir_view() + set_tabindex(); + } else { + alert("No apps"); + } + }; + + request.onerror = function() { + // Display error name from the DOMError object + alert("Error: " + request.error.name); + }; + } + + function set_tabindex() { + var items_list = $("div#finder div.items:visible"); + items = $("div#app-list > div.items:visible"); + + for (var i = -1; i < items.length; i++) { + $(items[i]).attr("tabindex", i); + pos_focus = 0; + $("div#finder") + .find("div.items[tabindex=0]") + .focus(); + } + } + + function dir_view() { + for (var i = 0; i < dirs.length; i++) { + var test = document.getElementsByClassName(dirs[i]); + $(test).addClass("child-of-dir"); + $(test) + .first() + .removeClass("child-of-dir"); + } + set_tabindex(); + } + + function dir_nav() { + if (dir_level == 1) { + $("div.items").css("display", "block"); + $("div.items") + .children(".dir-name") + .css("display", "block"); + $("div.items") + .children(".app-name") + .css("display", "none"); + $("div.child-of-dir").css("display", "none"); + + $("div#finder") + .find("div.items[tabindex=0]") + .focus(); + $("div#finder div#app-list .dir").css("border-left", "4px solid silver"); + pos_focus = 0; + dir_level = 0; + set_tabindex(); + } + } + + ////////////////// + //LAUNCH APP + ////////////////// + + function launchApp() { + if (page == 0) { + var selected_button = $(":focus")[0]; + var app_url = selected_button.getAttribute("data-url"); + //if element is a dir + if ($(selected_button).hasClass("dir") && dir_level == 0) { + $("div.items").css("display", "none"); + var same_class = $("*:focus") + .eq(0) + .attr("class"); + var elems = document.getElementsByClassName(same_class); + $(elems) + .children(".dir-name") + .css("display", "none"); + $(elems) + .children(".app-name") + .css("display", "block"); + $(elems).css("display", "block"); + pos_focus = 0; + $("div#finder") + .find("div.items[tabindex=0]") + .focus(); + dir_level = 1; + $("div#finder div#app-list .dir").css("border", "0px solid silver"); + set_tabindex(); + + return; + } + //if element is not a dir start app + else { + var request = window.navigator.mozApps.mgmt.getAll(); + request.onsuccess = function() { + if (request.result) { + request.result[app_url].launch(); + return; + } + }; + } + } + } + + ////////////////// + //DELETE APP + ////////////////// + + function delete_app() { + if (page == 0) { + var request = window.navigator.mozApps.mgmt.getAll(); + request.onsuccess = function() { + if (request.result) { + var selected_button = $(":focus")[0]; + var app_url = selected_button.getAttribute("data-url"); + var app_name = selected_button.getAttribute("data-app_name"); + var delete_request = navigator.mozApps.mgmt.uninstall( + request.result[app_url] + ); + + delete_request.error = function(event) { + alert("error: app not unistalled"); + }; + + delete_request.onsuccess = function(event) { + var text = app_name + " successfully uninstalled"; + notify("App", text); + finder(); + setTimeout(function() { + items = document.querySelectorAll("div#app-list > div.items"); + $("div#app-list") + .find("div.items[tabindex=0]") + .focus(); + }, 3000); + }; + } + }; + } + } + + ////////////////// + //SHORTCUT + ////////////////// + + function focus_shortcut(shortcut_number) { + if (page == 0) { + var items = document.querySelectorAll(".items"); + var targetElement = items[shortcut_number]; + targetElement.focus(); + launchApp(); + } + } + + ////////////////// + //Quick-Settings + ////////////////// + + var selected_button; + function quick_settings_toggle() { + if (pages_arr[page] == "quick-settings") { + selected_button = $(":focus")[0]; + var quick_settings_item = selected_button.getAttribute("data-function"); + + switch (true) { + case quick_settings_item == "bluetooth": + bluetooth_toggle("toggle"); + break; + + case quick_settings_item == "wifi": + wifi_toggle("toggle"); + break; + + case quick_settings_item == "mobile_data": + data_toggle("toggle"); + break; + + case quick_settings_item == "tethering": + tethering_toggle("toggle"); + break; + + case quick_settings_item == "airplane": + airplane_toggle("toggle"); + break; + + ///alarm on/off + case quick_settings_item == "sleep": + sleepModeState = localStorage.getItem("sleepMode"); + + if (sleepModeState == "true") { + localStorage.setItem("sleepMode", "false"); + $("div.alarms div.time div").css("opacity", "0.5"); + $("div.alarms div.time div").css("font-style", "italic"); + return; + } + + if (sleepModeState == "false") { + localStorage.setItem("sleepMode", "true"); + $("div.alarms div.time div").css("opacity", "1"); + $("div.alarms div.time div").css("font-style", "normal"); + } + + break; + } + } + } + + /////////////// + ///BLUETOOTH/////// + ///////////// + ///toggle --- toggle setting + ///get --- to know the current state + ///on / off ---- enable / disable strict + + function bluetooth_toggle(param) { + var lock = navigator.mozSettings.createLock(); + var setting = lock.get("bluetooth.enabled"); + + setting.onsuccess = function() { + //strict + if (param == "on") { + var lock = navigator.mozSettings.createLock(); + var result = lock.set({ + "bluetooth.enabled": true + }); + + result.onsuccess = function() { + navigator.mozBluetooth.defaultAdapter.enable(); + $("div#quick-settings div.bluetooth").css("opacity", "1"); + $("div#quick-settings div.bluetooth").css("font-style", "normal"); + localStorage.setItem("bluetooth", "true"); + airplaneState = "false"; + airplane_toggle("get"); + }; + + result.onerror = function() { + alert("An error occure, the settings remain unchanged"); + }; + } + + if (param == "off") { + var lock = navigator.mozSettings.createLock(); + var result = lock.set({ + "bluetooth.enabled": false + }); + + result.onsuccess = function() { + navigator.mozBluetooth.defaultAdapter.disable(); + $("div#quick-settings div.bluetooth").css("opacity", "0.5"); + $("div#quick-settings div.bluetooth").css("font-style", "italic"); + localStorage.setItem("bluetooth", "false"); + }; + + result.onerror = function() { + alert("An error occure, the settings remain unchanged"); + }; + } + + //toogle + var callback = JSON.stringify(setting.result); + + if (callback == '{"bluetooth.enabled":true}') { + if (param == "toggle") { + bluetooth_toggle("off"); + } + + if (param == "get") { + $("div#quick-settings div.bluetooth").css("opacity", "1"); + $("div#quick-settings div.bluetooth").css("font-style", "normal"); + localStorage.setItem("bluetooth", "true"); + airplaneState = "false"; + } + } + + if (callback == '{"bluetooth.enabled":false}') { + if (param == "toggle") { + bluetooth_toggle("on"); + } + + if (param == "get") { + $("div#quick-settings div.bluetooth").css("opacity", "0.5"); + $("div#quick-settings div.bluetooth").css("font-style", "italic"); + localStorage.setItem("bluetooth", "false"); + } + } + }; + + setting.onerror = function() { + console.warn("An error occured: " + setting.error); + }; + } + + /////////////// + ///WIFI/////// + ///////////// + + function wifi_toggle(param) { + var lock = navigator.mozSettings.createLock(); + var setting = lock.get("wifi.enabled"); + + setting.onsuccess = function() { + //strict + if (param == "on") { + var lock = navigator.mozSettings.createLock(); + var result = lock.set({ + "wifi.enabled": true + }); + + result.onsuccess = function() { + $("div#quick-settings div.wifi").css("opacity", "1"); + $("div#quick-settings div.wifi").css("font-style", "normal"); + localStorage.setItem("wifi", "true"); + airplaneState = "false"; + airplane_toggle("get"); + }; + + result.onerror = function() { + alert("An error occure, the settings remain unchanged"); + }; + } + + if (param == "off") { + var lock = navigator.mozSettings.createLock(); + var result = lock.set({ + "wifi.enabled": false + }); + + result.onsuccess = function() { + $("div#quick-settings div.wifi").css("opacity", "0.5"); + $("div#quick-settings div.wifi").css("font-style", "italic"); + localStorage.setItem("wifi", "false"); + }; + + result.onerror = function() { + alert("An error occure, the settings remain unchanged"); + }; + } + + //toogle + var callback = JSON.stringify(setting.result); + + if (callback == '{"wifi.enabled":true}') { + if (param == "toggle") { + wifi_toggle("off"); + } + + if (param == "get") { + $("div#quick-settings div.wifi").css("opacity", "1"); + $("div#quick-settings div.wifi").css("font-style", "normal"); + localStorage.setItem("wifi", "true"); + airplaneState = "false"; + } + } + + if (callback == '{"wifi.enabled":false}') { + if (param == "toggle") { + wifi_toggle("on"); + } + + if (param == "get") { + $("div#quick-settings div.wifi").css("opacity", "0.5"); + $("div#quick-settings div.wifi").css("font-style", "italic"); + localStorage.setItem("wifi", "false"); + } + } + }; + + setting.onerror = function() { + console.warn("An error occured: " + setting.error); + }; + } + + ///////////////////////// + ///DATA CONNECTION/////// + //////////////////////// + + function data_toggle(param) { + var lock = navigator.mozSettings.createLock(); + var setting = lock.get("ril.data.enabled"); + + setting.onsuccess = function() { + //strict + if (param == "on") { + var lock = navigator.mozSettings.createLock(); + var result = lock.set({ + "ril.data.enabled": true, + "ril.radio.disabled": false + }); + + result.onsuccess = function() { + $("div#quick-settings div.mobile-data").css("opacity", "1"); + $("div#quick-settings div.mobile-data").css("font-style", "normal"); + localStorage.setItem("mobileData", "true"); + airplaneState = "false"; + airplane_toggle("get"); + }; + + result.onerror = function() { + alert("An error occure, the settings remain unchanged"); + }; + } + + if (param == "off") { + var lock = navigator.mozSettings.createLock(); + var result = lock.set({ + "ril.data.enabled": false, + "ril.radio.disabled": true + }); + + result.onsuccess = function() { + $("div#quick-settings div.mobile-data").css("opacity", "0.5"); + $("div#quick-settings div.mobile-data").css("font-style", "italic"); + localStorage.setItem("mobileData", "false"); + }; + + result.onerror = function() { + alert("An error occure, the settings remain unchanged"); + }; + } + + //toogle + var callback = JSON.stringify(setting.result); + + if (callback == '{"ril.data.enabled":true}') { + if (param == "toggle") { + data_toggle("off"); + } + + if (param == "get") { + $("div#quick-settings div.mobile-data").css("opacity", "1"); + $("div#quick-settings div.mobile-data").css("font-style", "normal"); + localStorage.setItem("mobileData", "true"); + airplaneState = "false"; + } + } + + if (callback == '{"ril.data.enabled":false}') { + if (param == "toggle") { + data_toggle("on"); + } + + if (param == "get") { + $("div#quick-settings div.mobile-data").css("opacity", "0.5"); + $("div#quick-settings div.mobile-data").css("font-style", "italic"); + localStorage.setItem("mobileData", "false"); + } + } + }; + + setting.onerror = function() { + console.warn("An error occured: " + setting.error); + }; + } + + /////////////////// + ///TETHERING/////// + ////////////////// + + function tethering_toggle(param) { + var lock = navigator.mozSettings.createLock(); + var setting = lock.get("tethering.wifi.enabled"); + + setting.onsuccess = function() { + //strict + if (param == "on") { + var lock = navigator.mozSettings.createLock(); + var result = lock.set({ + "tethering.wifi.enabled": true + }); + + result.onsuccess = function() { + $("div#quick-settings div.tethering").css("opacity", "1"); + $("div#quick-settings div.tethering").css("font-style", "normal"); + localStorage.setItem("tethering", "true"); + + //get PWD + var getPWD = lock.get("tethering.wifi.security.password"); + getPWD.onsuccess = function() { + var stringify_result = JSON.stringify(getPWD.result); + var callback = JSON.parse(stringify_result); + $("div#message-box").css("display", "block"); + $("div#message-box").text( + callback["tethering.wifi.security.password"] + ); + + setTimeout(function() { + $("div#message-box").text(""); + $("div#message-box").css("display", "none"); + }, 10000); + }; + + getPWD.onerror = function() { + alert("Can't show password"); + }; + }; + + result.onerror = function() { + alert("An error occure, the settings remain unchanged"); + }; + } + + if (param == "off") { + var lock = navigator.mozSettings.createLock(); + var result = lock.set({ + "tethering.wifi.enabled": false + }); + + result.onsuccess = function() { + $("div#quick-settings div.tethering").css("opacity", "0.5"); + $("div#quick-settings div.tethering").css("font-style", "italic"); + localStorage.setItem("tethering", "false"); + }; + + result.onerror = function() { + alert("An error occure, the settings remain unchanged"); + }; + } + + //toogle + var callback = JSON.stringify(setting.result); + + if (callback == '{"tethering.wifi.enabled":true}') { + if (param == "toggle") { + tethering_toggle("off"); + } + + if (param == "get") { + $("div#quick-settings div.tethering").css("opacity", "1"); + $("div#quick-settings div.tethering").css("font-style", "normal"); + localStorage.setItem("tethering", "true"); + } + } + + if (callback == '{"tethering.wifi.enabled":false}') { + if (param == "toggle") { + tethering_toggle("on"); + } + + if (param == "get") { + $("div#quick-settings div.tethering").css("opacity", "0.5"); + $("div#quick-settings div.tethering").css("font-style", "italic"); + localStorage.setItem("tethering", "false"); + } + } + }; + + setting.onerror = function() { + console.warn("An error occured: " + setting.error); + }; + } + + /////AIRPLANE + + function airplane_toggle(param) { + if (param == "toggle" && airplaneState == "true") { + airplane_toggle("off"); + airplaneState = "false"; + return; + } + + if (param == "toggle" && airplaneState == "false") { + airplane_toggle("on"); + airplaneState = "true"; + } + + if (param == "off") { + $("div#quick-settings div.airplane").css("opacity", "0.5"); + $("div#quick-settings div.airplane").css("font-style", "italic"); + // + bluetooth_toggle("on"); + wifi_toggle("on"); + data_toggle("on"); + } + + if (param == "on") { + $("div#quick-settings div.airplane").css("opacity", "1"); + $("div#quick-settings div.airplane").css("font-style", "normal"); + //airplaneState = "true" + bluetooth_toggle("off"); + wifi_toggle("off"); + data_toggle("off"); + } + + if ((param = "get")) { + if (airplaneState == "true") { + $("div#quick-settings div.airplane").css("opacity", "1"); + $("div#quick-settings div.airplane").css("font-style", "normal"); + } + + if (airplaneState == "false") { + $("div#quick-settings div.airplane").css("opacity", "0.5"); + $("div#quick-settings div.airplane").css("font-style", "italic"); + } + } + } + + //get status on start + wifi_toggle("get"); + bluetooth_toggle("get"); + data_toggle("get"); + tethering_toggle("get"); + + setTimeout(function() { + airplane_toggle("get"); + }, 1000); + + //////////////////// + ////GEOLOCATION///// + /////////////////// + + function select_location() { + pos_focus = 0; + $("div#weather-wrapper div#locations") + .find("div.items[tabindex=0]") + .focus(); + + k = -1; + $("div#weather-wrapper div#locations").empty(); + for (var i = 0; i < locations.length; i++) { + k++; + $("div#weather-wrapper div#locations").append( + "
" + + locations[i][0] + + "
" + ); + } + + if (pages_arr[page] == "weather-wrapper") { + $("div#weather-wrapper div#locations").css("display", "block"); + $("div#weather-wrapper div#location").css("display", "none"); + $("div#weather-wrapper div#locations div") + .first() + .focus(); + items = document.querySelectorAll( + "div#weather-wrapper div#locations > div.items" + ); + } + } + + function choice_location() { + if (pages_arr[page] == "weather-wrapper") { + var selected_button = $(":focus")[0]; + current_lng = selected_button.getAttribute("data-long"); + current_lat = selected_button.getAttribute("data-lat"); + location_name = $(selected_button).text(); + $("h1#location_name").text(location_name); + + $("div#weather-wrapper div#locations").css("display", "none"); + $("div#weather-wrapper div#location").css("display", "block"); + weather("notgeolocation"); + } + } + + function getCityName() { + var request_url = + "https://nominatim.openstreetmap.org/reverse?format=json&lat=" + + current_lat + + "&lon=" + + current_lng + + "&zoom=18&addressdetails=1"; + var jqxhr = $.getJSON(request_url, function(data) {}) + .done(function(data) { + $.each(data.address, function(key, val) { + if (key === "town") { + $("h1#location_name").text(val); + } + }); + }) + .fail(function() { + alert("error"); + }) + .always(function() {}); + } + + var weather_data = []; + + function weather(param) { + weather_data.length = 0; + + if (param == "geolocation") { + var options = { + enableHighAccuracy: true, + timeout: 30000, + maximumAge: 0 + }; + + function success(pos) { + var crd = pos.coords; + + current_lng = crd.longitude; + current_lat = crd.latitude; + fetch_weather_data(); + getCityName(); + } + + function error(err) { + alert("Position not found" + err.code + ":" + err.message); + select_location(); + } + + navigator.geolocation.getCurrentPosition(success, error, options); + } else { + fetch_weather_data(); + updateChart(); + } + + function fetch_weather_data() { + var request_url = + "https://api.openweathermap.org/data/2.5/forecast?lat=" + + current_lat + + "&lon=" + + current_lng + + "&units=metric&APPID=" + + openweather_api; + var jqxhr = $.getJSON(request_url, function(data) {}) + .done(function(data) { + var wind_dir = ""; + function direction(in_val) { + var degree = data.list[in_val].wind.deg; + + switch (true) { + case degree > 337.5: + wind_dir = "N"; + break; + case degree > 292.5: + wind_dir = "N"; + break; + case degree > 247.5: + wind_dir = "W"; + break; + case degree > 202.5: + wind_dir = "SW"; + break; + case degree > 157.5: + wind_dir = "S"; + break; + case degree > 122.5: + wind_dir = "SE"; + break; + case degree > 67.5: + wind_dir = "E"; + break; + case degree > 22.5: + wind_dir = "NE"; + } + } + + //cloning elements + $("div#weather section") + .not(":first") + .remove(); + //$("div#weather section").first().css("display","block") + + var template = $("section#forecast-0"); + var k = 0; + + for (var i = 0; i < 20; i++) { + k++; + //create elements + template + .clone() + .attr("id", "forecast-" + k) + .appendTo("div#weather"); + + //add data + + var date_format = moment + .unix(data.list[i].dt) + .format("ddd DD MMM HH:mm"); + var date_format_hhmm = moment.unix(data.list[i].dt).format("HH:mm"); + var temp = Math.round(data.list[i].main.temp); + var rain_data = 0; + + if (data.list[i].rain != undefined) { + rain_data = data.list[i].rain["3h"]; + rain_data = Number(rain_data); + } else { + rain_data = 0; + } + + direction(i); + + $("div#location section#forecast-" + i + " div#temp").text( + Math.round(data.list[i].main.temp) + "°" + ); + $( + "div#location section#forecast-" + + i + + " div#wind div#wind-speed div#wind-speed-val" + ).text(data.list[i].wind.speed); + $( + "div#location section#forecast-" + i + " div#wind div#wind-dir" + ).text(wind_dir); + $( + "div#location section#forecast-" + + i + + " div#pressure div#pressure-val" + ).text(Math.round(data.list[i].main.pressure)); + $( + "div#location section#forecast-" + + i + + " div.title div.forecast-time" + ).text(date_format); + $("div#location section#forecast-" + i + " div#icon img").attr( + "src", + "https://openweathermap.org/img/w/" + + data.list[i].weather[0].icon + + ".png" + ); + + weather_data.push([date_format_hhmm, temp, rain_data]); + } + + $("div#weather-wrapper div#message").css("display", "none"); + $("div#location").css("display", "block"); + //$("div#weather section").first().css("display","none") + + //chart + addChart(); + }) + .fail(function() { + //alert( "error" ); + }) + .always(function() { + //alert( "complete" ); + }); + } + } + + var mixedChart; + + function addChart() { + var ctx = document.getElementById("myChart"); + var ctx = document.getElementById("myChart").getContext("2d"); + + mixedChart = new Chart(ctx, { + type: "line", + data: { + datasets: [ + { + label: "temp", + yAxisID: "id1", + data: [ + weather_data[0][1], + weather_data[1][1], + weather_data[2][1], + weather_data[3][1] + ], + borderColor: "rgba(255,0,0,1)" + }, + { + label: "rain", + yAxisID: "id2", + data: [ + weather_data[0][2], + weather_data[1][2], + weather_data[2][2], + weather_data[3][2] + ], + borderColor: "rgba(0,0,255,1)" + } + ], + labels: [ + weather_data[0][0], + weather_data[1][0], + weather_data[2][0], + weather_data[3][0] + ] + }, + options: { + legend: { + display: false, + labels: { + position: "bottom" + } + }, + + scales: { + yAxes: [ + { + id: "id1", + type: "linear", + position: "left" + }, + { + id: "id2", + type: "linear", + position: "right", + ticks: { + min: 0 + } + } + ] + } + } + }); + } + + //update chart + function updateChart() { + mixedChart.update(); + } + + var key_time; + var press_time = 0; + var longpress = false; + function func_interval() { + longpress = false; + press_time = 0; + key_time = setInterval(function() { + press_time++; + + if (press_time > 2) { + longpress = true; + } + if (press_time < 2) { + longpress = false; + } + }, 1000); + } + + ////////////////////////// + ////KEYPAD TRIGGER//////////// + ///////////////////////// + function handleKeyDown(evt) { + switch (evt.key) { + case "Enter": + func_interval(); + quick_settings_toggle(); + + break; + + case "Backspace": + evt.preventDefault(); + + if (dir_level == 0) { + window.close(); + } + dir_nav(); + break; + } + } + + function handleKeyUp(evt) { + clearInterval(key_time); + + switch (evt.key) { + case "Enter": + if (longpress == false) { + launchApp(); + choice_location(); + } + + if (longpress == true) { + delete_app(); + } + break; + + case "Backspace": + evt.preventDefault(); + break; + + case "ArrowDown": + nav("+1"); + break; + + case "ArrowUp": + nav("-1"); + break; + + case "ArrowRight": + nav("slide_right"); + break; + + case "ArrowLeft": + nav("slide_left"); + + break; + + case "SoftLeft": + select_location(); + break; + + case "1": + //checkUpdate(); + focus_shortcut(0); + break; + + case "2": + focus_shortcut(1); + break; + + break; + + case "3": + focus_shortcut(2); + break; + + case "4": + focus_shortcut(3); + break; + + case "5": + focus_shortcut(4); + break; + + case "6": + focus_shortcut(5); + break; + + case "7": + focus_shortcut(6); + break; + + case "8": + focus_shortcut(7); + break; + + case "9": + focus_shortcut(8); + break; + + case "0": + listApps(true); + break; + } + } + + document.addEventListener("keydown", handleKeyDown); + document.addEventListener("keyup", handleKeyUp); + + ////////////////////////// + ////BUG OUTPUT//////////// + ///////////////////////// + + if (debug == true) { + $(window).on("error", function(evt) { + console.log("jQuery error event:", evt); + var e = evt.originalEvent; // get the javascript event + console.log("original event:", e); + if (e.message) { + alert( + "Error:\n\t" + + e.message + + "\nLine:\n\t" + + e.lineno + + "\nFile:\n\t" + + e.filename + ); + } else { + alert( + "Error:\n\t" + e.type + "\nElement:\n\t" + (e.srcElement || e.target) + ); + } + }); + } +}); diff --git a/src/assets/js/Chart.bundle.js b/thirdparty/Chart.bundle.js similarity index 100% rename from src/assets/js/Chart.bundle.js rename to thirdparty/Chart.bundle.js diff --git a/src/assets/js/applait.finder.min.js b/thirdparty/applait.finder.min.js similarity index 100% rename from src/assets/js/applait.finder.min.js rename to thirdparty/applait.finder.min.js diff --git a/src/assets/js/client.min.js b/thirdparty/client.min.js similarity index 100% rename from src/assets/js/client.min.js rename to thirdparty/client.min.js diff --git a/src/assets/js/jQuery-3.1.0.js b/thirdparty/jQuery-3.1.0.js similarity index 100% rename from src/assets/js/jQuery-3.1.0.js rename to thirdparty/jQuery-3.1.0.js diff --git a/src/assets/js/moments.min.js b/thirdparty/moments.min.js similarity index 100% rename from src/assets/js/moments.min.js rename to thirdparty/moments.min.js From 8a0bb7e239fd85d9783f8740e2edba5cd894fc3c Mon Sep 17 00:00:00 2001 From: Simon Laux Date: Mon, 3 Feb 2020 05:01:48 +0100 Subject: [PATCH 4/6] splitup css and convert a tiny bit to scss (for easier readablity) --- src/css/applauncher.scss | 58 +++++++ src/css/main.css | 292 ------------------------------------ src/css/main.scss | 79 ++++++++++ src/css/quick-settings.scss | 26 ++++ src/css/weather.scss | 127 ++++++++++++++++ src/index.html | 2 +- 6 files changed, 291 insertions(+), 293 deletions(-) create mode 100644 src/css/applauncher.scss delete mode 100644 src/css/main.css create mode 100644 src/css/main.scss create mode 100644 src/css/quick-settings.scss create mode 100644 src/css/weather.scss diff --git a/src/css/applauncher.scss b/src/css/applauncher.scss new file mode 100644 index 0000000..1af38fa --- /dev/null +++ b/src/css/applauncher.scss @@ -0,0 +1,58 @@ +/*/////////////////////////// +///FINDER////////////////*/ + +div#finder { + position: relative; + background: black; + padding: 5px; + color: white; + height: 100vh; + width: 100vw; +} + +div#finder-error { + position: absolute; + z-index: 2; + top: 50%; + left: 50%; + margin: -7px 0 0 -50px; + width: 92px; + background: black; + color: white; + font-size: 14px; + padding: 3px; + display: none; +} + +div#finder div#app-list { + background: black; + color: white; + margin: 0 0 3px 0; + padding: 3px; + max-height: 90%; + min-width: 95%; + overflow: hidden; +} + +div#finder div#app-list .child-of-dir { + display: none; +} + +div#finder div#app-list .dir { + border-left: 4px solid silver; + padding: 0 0 0 3px; +} + +div#finder div#app-list .dir span.app-name { + display: none; +} + +div#finder div#app-list div { + min-width: 100%; + margin: 0 0 5px 0; +} + +div#finder div:focus { + background: yellow; + color: black; +} diff --git a/src/css/main.css b/src/css/main.css deleted file mode 100644 index 12f2c68..0000000 --- a/src/css/main.css +++ /dev/null @@ -1,292 +0,0 @@ -/*GENERAL*/ - -:root { - --color-one: black; - --color-two: yellow; - --color-three: silver; - --color-four: rgb(99, 99, 99); - --color-five: rgb(38, 38, 38); - --color-six: rgb(78, 206, 144); - --color-seven: gainsboro; -} -*, -*:before, -*:after { - border: 0px; - padding: 0px; - margin: 0px; - box-sizing: border-box; -} - -*::-webkit-scrollbar { - width: 0 !important; - background-color: transparent !important; - display: none !important; -} - -html, -body { - font-weight: 100; - width: 100%; - position: relative; - margin: 0px; - padding: 0px; - font-size: 1rem; - line-height: 1.4rem; - -webkit-appearance: none; - height: 100%; - margin: 0; -} - -h1 { - margin: 0 0 20px 0; - font-size: 1.2rem; -} - -h2 { - font-size: 1rem; -} - -.debug { - border: 1px solid red; -} - -/*/////////////////////////// -///HELPER////////////////*/ - -div#window-status { - position: fixed; - top: 10px; - left: 5px; - background: black; - color: white; - z-index: 900; - display: none; -} - -/*/////////////////////////// -///FINDER////////////////*/ - -div#finder { - position: relative; - background: black; - padding: 5px; - color: white; - height: 100vh; - width: 100vw; -} - -div#finder-error { - position: absolute; - z-index: 2; - top: 50%; - left: 50%; - margin: -7px 0 0 -50px; - width: 92px; - background: black; - color: white; - font-size: 14px; - padding: 3px; - display: none; -} - -div#finder div#app-list { - background: black; - color: white; - margin: 0 0 3px 0; - padding: 3px; - max-height: 90%; - min-width: 95%; - overflow: hidden; -} - -div#finder div#app-list .child-of-dir { - display: none; -} - -div#finder div#app-list .dir { - border-left: 4px solid silver; - padding: 0 0 0 3px; -} - -div#finder div#app-list .dir span.app-name { - display: none; -} - -div#finder div#app-list div { - min-width: 100%; - margin: 0 0 5px 0; -} - -div#finder div:focus { - background: yellow; - color: black; -} - -div#weather-wrapper { - display: none; - background: black; -} - -div#quick-settings { - display: none; - position: relative; - background: black; - padding: 5px; - color: white; - height: 100vh; - width: 100vw; -} - -div#quick-settings div:focus { - background: yellow; - color: black; -} - -div#quick-settings div.alarms { - margin: 15px 0 0 0; -} - -div#quick-settings div.alarms div { - padding: 0 10px 0 0; -} - -div#quick-settings div.alarms div:first:after { - content: "-"; -} - -/*/////////////////////////// -///LOCATION////////////////*/ - -div#chart { - position: relative; - margin: 25px 0 10px 0; - height: 240px; - width: 99vw; - max-width: 99vw; -} - -div#chart #myChart { - margin: 0 0 0 -5px !important; -} - -div#chart div.legend span { - margin: 5px 5px 0 0; -} - -div#chart div.legend span:first-child { - color: red; -} - -div#chart div.legend span:nth-child(2) { - color: blue; -} - -div#location { - position: absolute; - z-index: 1000; - left: 0; - top: 0; - background: black; - color: white; - font-size: 14px; - padding: 5px 10px 50px 5px; - overflow: hidden; - display: none; -} - -div#weather-wrapper div#locations { - display: none; - position: fixed; - z-index: 1001; - background: black; - top: 0px; - left: 0px; -} - -div#weather-wrapper div#locations:first-child { - outline: 2px solid red; -} - -div#weather-wrapper div#locations div { - display: block; - background: black; - color: white; - width: 100%; - height: auto; - margin: 0 0 5px 0; -} - -div#weather-wrapper div#locations div:focus { - background: yellow; - color: black; -} - -div#weather-wrapper div#message { - position: absolute; - z-index: 5; - color: white; - top: 40%; - text-align: center; -} - -div#location div#weather { - margin: 10px 0 0 0; -} - -div#location div#temp { - font-size: 1.7rem; -} - -div#location div#weather section { - border-top: 2px dashed white; - margin: 0 0 0px 0; - padding: 12px 5px 12px 0px; - background: black; -} - -div#location div#weather div#weather-bar div#icon { - margin: 8px 0 0 0; -} - -div#location div#weather div#wind-dir { - font-size: 1.7rem; - max-height: 1.7rem !important; -} - -div#location div#weather div#wind-speed { - font-size: 0.7rem; - max-height: 1.7rem !important; - margin: -10px 0 0 0; -} - -div#location div#weather div#wind-speed div#wind-speed-val { - max-height: 0.7rem; -} - -div#location div#weather div#wind-speed div#wind-speed-unit { - max-height: 0.7rem; -} - -div#message-box { - display: none; - position: fixed; - bottom: 5px; - left: 0px; - padding: 5px; - min-width: 100vw; - height: auto; - background: pink; - color: black; - z-index: 2000; -} - -/* KaiOS portrait devices (240x320) */ -@media only screen and (orientation: portrait) { - /* styles */ -} - -/* KaiOS landscape devices (320x240) */ -@media screen and (orientation: landscape) { - /* styles */ -} diff --git a/src/css/main.scss b/src/css/main.scss new file mode 100644 index 0000000..ad8a413 --- /dev/null +++ b/src/css/main.scss @@ -0,0 +1,79 @@ +/*GENERAL*/ + +:root { + --color-one: black; + --color-two: yellow; + --color-three: silver; + --color-four: rgb(99, 99, 99); + --color-five: rgb(38, 38, 38); + --color-six: rgb(78, 206, 144); + --color-seven: gainsboro; +} +*, +*:before, +*:after { + border: 0px; + padding: 0px; + margin: 0px; + box-sizing: border-box; +} + +*::-webkit-scrollbar { + width: 0 !important; + background-color: transparent !important; + display: none !important; +} + +html, +body { + font-weight: 100; + width: 100%; + position: relative; + margin: 0px; + padding: 0px; + font-size: 1rem; + line-height: 1.4rem; + -webkit-appearance: none; + height: 100%; + margin: 0; +} + +h1 { + margin: 0 0 20px 0; + font-size: 1.2rem; +} + +h2 { + font-size: 1rem; +} + +.debug { + border: 1px solid red; +} + +/*/////////////////////////// +///HELPER////////////////*/ + +div#window-status { + position: fixed; + top: 10px; + left: 5px; + background: black; + color: white; + z-index: 900; + display: none; +} + +@import "./applauncher.scss"; +@import "./quick-settings.scss"; +@import "./weather.scss"; + +/* KaiOS portrait devices (240x320) */ +@media only screen and (orientation: portrait) { + /* styles */ +} + +/* KaiOS landscape devices (320x240) */ +@media screen and (orientation: landscape) { + /* styles */ +} diff --git a/src/css/quick-settings.scss b/src/css/quick-settings.scss new file mode 100644 index 0000000..167cdf0 --- /dev/null +++ b/src/css/quick-settings.scss @@ -0,0 +1,26 @@ +div#quick-settings { + display: none; + position: relative; + background: black; + padding: 5px; + color: white; + height: 100vh; + width: 100vw; +} + +div#quick-settings div:focus { + background: yellow; + color: black; +} + +div#quick-settings div.alarms { + margin: 15px 0 0 0; +} + +div#quick-settings div.alarms div { + padding: 0 10px 0 0; +} + +div#quick-settings div.alarms div:first:after { + content: "-"; +} diff --git a/src/css/weather.scss b/src/css/weather.scss new file mode 100644 index 0000000..9c60f14 --- /dev/null +++ b/src/css/weather.scss @@ -0,0 +1,127 @@ +div#location { + div#weather { + margin: 10px 0 0 0; + } +} + +div#location div#temp { + font-size: 1.7rem; +} + +div#location div#weather section { + border-top: 2px dashed white; + margin: 0 0 0px 0; + padding: 12px 5px 12px 0px; + background: black; +} + +div#location div#weather div#weather-bar div#icon { + margin: 8px 0 0 0; +} + +div#location div#weather div#wind-dir { + font-size: 1.7rem; + max-height: 1.7rem !important; +} + +div#location div#weather div#wind-speed { + font-size: 0.7rem; + max-height: 1.7rem !important; + margin: -10px 0 0 0; +} + +div#location div#weather div#wind-speed div#wind-speed-val { + max-height: 0.7rem; +} + +div#location div#weather div#wind-speed div#wind-speed-unit { + max-height: 0.7rem; +} + +div#location { + position: absolute; + z-index: 1000; + left: 0; + top: 0; + background: black; + color: white; + font-size: 14px; + padding: 5px 10px 50px 5px; + overflow: hidden; + display: none; +} + +div#weather-wrapper div#locations { + display: none; + position: fixed; + z-index: 1001; + background: black; + top: 0px; + left: 0px; +} + +div#weather-wrapper div#locations:first-child { + outline: 2px solid red; +} + +div#weather-wrapper div#locations div { + display: block; + background: black; + color: white; + width: 100%; + height: auto; + margin: 0 0 5px 0; +} + +div#weather-wrapper div#locations div:focus { + background: yellow; + color: black; +} + +div#weather-wrapper div#message { + position: absolute; + z-index: 5; + color: white; + top: 40%; + text-align: center; +} + +div#weather-wrapper { + display: none; + background: black; +} + +div#chart { + position: relative; + margin: 25px 0 10px 0; + height: 240px; + width: 99vw; + max-width: 99vw; + #myChart { + margin: 0 0 0 -5px !important; + } + div.legend { + span { + margin: 5px 5px 0 0; + } + span:first-child { + color: red; + } + span:nth-child(2) { + color: blue; + } + } +} + +div#message-box { + display: none; + position: fixed; + bottom: 5px; + left: 0px; + padding: 5px; + min-width: 100vw; + height: auto; + background: pink; + color: black; + z-index: 2000; +} diff --git a/src/index.html b/src/index.html index b7729ac..78e3b75 100644 --- a/src/index.html +++ b/src/index.html @@ -10,7 +10,7 @@ - + From dfbfe8b35b5feb00fdeb1a8f22cfd4b5257ed623 Mon Sep 17 00:00:00 2001 From: Simon Laux Date: Mon, 3 Feb 2020 05:28:59 +0100 Subject: [PATCH 5/6] require dependencies from npm --- package-lock.json | 48 +- package.json | 7 +- src/index.html | 5 - src/script.js | 5 + thirdparty/Chart.bundle.js | 19288 ----------------------------- thirdparty/applait.finder.min.js | 15 +- thirdparty/client.min.js | 81 - thirdparty/jQuery-3.1.0.js | 4 - thirdparty/moments.min.js | 1 - 9 files changed, 69 insertions(+), 19385 deletions(-) delete mode 100644 thirdparty/Chart.bundle.js delete mode 100755 thirdparty/client.min.js delete mode 100644 thirdparty/jQuery-3.1.0.js delete mode 100644 thirdparty/moments.min.js diff --git a/package-lock.json b/package-lock.json index 3a20218..00c5a18 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1803,6 +1803,32 @@ "supports-color": "^5.3.0" } }, + "chart.js": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.3.tgz", + "integrity": "sha512-+2jlOobSk52c1VU6fzkh3UwqHMdSlgH1xFv9FKMqHiNCpXsGPQa/+81AFa+i3jZ253Mq9aAycPwDjnn1XbRNNw==", + "requires": { + "chartjs-color": "^2.1.0", + "moment": "^2.10.2" + } + }, + "chartjs-color": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.4.1.tgz", + "integrity": "sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==", + "requires": { + "chartjs-color-string": "^0.6.0", + "color-convert": "^1.9.3" + } + }, + "chartjs-color-string": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz", + "integrity": "sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==", + "requires": { + "color-name": "^1.0.0" + } + }, "chokidar": { "version": "2.1.8", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", @@ -1946,7 +1972,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" } @@ -1954,8 +1979,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "color-string": { "version": "1.5.3", @@ -4724,6 +4748,11 @@ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "dev": true }, + "jquery": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.1.tgz", + "integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==" + }, "js-base64": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.1.tgz", @@ -5289,6 +5318,11 @@ } } }, + "moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -6106,6 +6140,14 @@ } } }, + "parcel-plugin-clean-dist-fsextra": { + "version": "git+https://github.com/Simon-Laux/parcel-plugin-clean-dist.git#9ec97ff36a30f0de1ab88dede7c4d276da1cdd50", + "from": "git+https://github.com/Simon-Laux/parcel-plugin-clean-dist.git", + "dev": true, + "requires": { + "fs-extra": "^8.1.0" + } + }, "parcel-plugin-copy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parcel-plugin-copy/-/parcel-plugin-copy-1.0.2.tgz", diff --git a/package.json b/package.json index c09e602..69cbec1 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "node-sass": "^4.13.0", "parcel": "^1.12.4", "parcel-plugin-bundle-visualiser": "^1.2.0", + "parcel-plugin-clean-dist-fsextra": "git+https://github.com/Simon-Laux/parcel-plugin-clean-dist.git", "parcel-plugin-copy": "^1.0.2", "prettier": "^1.19.1" }, @@ -25,5 +26,9 @@ "source": "/static", "target": "/dist" }, - "dependencies": {} + "dependencies": { + "chart.js": "^2.9.3", + "jquery": "^3.4.1", + "moment": "^2.24.0" + } } diff --git a/src/index.html b/src/index.html index 78e3b75..58f6b3d 100644 --- a/src/index.html +++ b/src/index.html @@ -116,9 +116,4 @@

- - - - - diff --git a/src/script.js b/src/script.js index 659d0ff..7f51aba 100644 --- a/src/script.js +++ b/src/script.js @@ -1,3 +1,8 @@ +import moment from 'moment' +import Chart from 'chart.js' +import $ from 'jquery' +import Applait from '../thirdparty/applait.finder.min.js' + $(document).ready(function() { //Global Vars var windowOpen = false; diff --git a/thirdparty/Chart.bundle.js b/thirdparty/Chart.bundle.js deleted file mode 100644 index 1d1c485..0000000 --- a/thirdparty/Chart.bundle.js +++ /dev/null @@ -1,19288 +0,0 @@ -/*! - * Chart.js v2.8.0 - * https://www.chartjs.org - * (c) 2019 Chart.js Contributors - * Released under the MIT License - */ -(function (global, factory) { -typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : -typeof define === 'function' && define.amd ? define(factory) : -(global.Chart = factory()); -}(this, (function () { 'use strict'; - -/* MIT license */ - -var conversions = { - rgb2hsl: rgb2hsl, - rgb2hsv: rgb2hsv, - rgb2hwb: rgb2hwb, - rgb2cmyk: rgb2cmyk, - rgb2keyword: rgb2keyword, - rgb2xyz: rgb2xyz, - rgb2lab: rgb2lab, - rgb2lch: rgb2lch, - - hsl2rgb: hsl2rgb, - hsl2hsv: hsl2hsv, - hsl2hwb: hsl2hwb, - hsl2cmyk: hsl2cmyk, - hsl2keyword: hsl2keyword, - - hsv2rgb: hsv2rgb, - hsv2hsl: hsv2hsl, - hsv2hwb: hsv2hwb, - hsv2cmyk: hsv2cmyk, - hsv2keyword: hsv2keyword, - - hwb2rgb: hwb2rgb, - hwb2hsl: hwb2hsl, - hwb2hsv: hwb2hsv, - hwb2cmyk: hwb2cmyk, - hwb2keyword: hwb2keyword, - - cmyk2rgb: cmyk2rgb, - cmyk2hsl: cmyk2hsl, - cmyk2hsv: cmyk2hsv, - cmyk2hwb: cmyk2hwb, - cmyk2keyword: cmyk2keyword, - - keyword2rgb: keyword2rgb, - keyword2hsl: keyword2hsl, - keyword2hsv: keyword2hsv, - keyword2hwb: keyword2hwb, - keyword2cmyk: keyword2cmyk, - keyword2lab: keyword2lab, - keyword2xyz: keyword2xyz, - - xyz2rgb: xyz2rgb, - xyz2lab: xyz2lab, - xyz2lch: xyz2lch, - - lab2xyz: lab2xyz, - lab2rgb: lab2rgb, - lab2lch: lab2lch, - - lch2lab: lch2lab, - lch2xyz: lch2xyz, - lch2rgb: lch2rgb -}; - - -function rgb2hsl(rgb) { - var r = rgb[0]/255, - g = rgb[1]/255, - b = rgb[2]/255, - min = Math.min(r, g, b), - max = Math.max(r, g, b), - delta = max - min, - h, s, l; - - if (max == min) - h = 0; - else if (r == max) - h = (g - b) / delta; - else if (g == max) - h = 2 + (b - r) / delta; - else if (b == max) - h = 4 + (r - g)/ delta; - - h = Math.min(h * 60, 360); - - if (h < 0) - h += 360; - - l = (min + max) / 2; - - if (max == min) - s = 0; - else if (l <= 0.5) - s = delta / (max + min); - else - s = delta / (2 - max - min); - - return [h, s * 100, l * 100]; -} - -function rgb2hsv(rgb) { - var r = rgb[0], - g = rgb[1], - b = rgb[2], - min = Math.min(r, g, b), - max = Math.max(r, g, b), - delta = max - min, - h, s, v; - - if (max == 0) - s = 0; - else - s = (delta/max * 1000)/10; - - if (max == min) - h = 0; - else if (r == max) - h = (g - b) / delta; - else if (g == max) - h = 2 + (b - r) / delta; - else if (b == max) - h = 4 + (r - g) / delta; - - h = Math.min(h * 60, 360); - - if (h < 0) - h += 360; - - v = ((max / 255) * 1000) / 10; - - return [h, s, v]; -} - -function rgb2hwb(rgb) { - var r = rgb[0], - g = rgb[1], - b = rgb[2], - h = rgb2hsl(rgb)[0], - w = 1/255 * Math.min(r, Math.min(g, b)), - b = 1 - 1/255 * Math.max(r, Math.max(g, b)); - - return [h, w * 100, b * 100]; -} - -function rgb2cmyk(rgb) { - var r = rgb[0] / 255, - g = rgb[1] / 255, - b = rgb[2] / 255, - c, m, y, k; - - k = Math.min(1 - r, 1 - g, 1 - b); - c = (1 - r - k) / (1 - k) || 0; - m = (1 - g - k) / (1 - k) || 0; - y = (1 - b - k) / (1 - k) || 0; - return [c * 100, m * 100, y * 100, k * 100]; -} - -function rgb2keyword(rgb) { - return reverseKeywords[JSON.stringify(rgb)]; -} - -function rgb2xyz(rgb) { - var r = rgb[0] / 255, - g = rgb[1] / 255, - b = rgb[2] / 255; - - // assume sRGB - r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92); - g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92); - b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92); - - var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); - var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); - var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); - - return [x * 100, y *100, z * 100]; -} - -function rgb2lab(rgb) { - var xyz = rgb2xyz(rgb), - x = xyz[0], - y = xyz[1], - z = xyz[2], - l, a, b; - - x /= 95.047; - y /= 100; - z /= 108.883; - - x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116); - - l = (116 * y) - 16; - a = 500 * (x - y); - b = 200 * (y - z); - - return [l, a, b]; -} - -function rgb2lch(args) { - return lab2lch(rgb2lab(args)); -} - -function hsl2rgb(hsl) { - var h = hsl[0] / 360, - s = hsl[1] / 100, - l = hsl[2] / 100, - t1, t2, t3, rgb, val; - - if (s == 0) { - val = l * 255; - return [val, val, val]; - } - - if (l < 0.5) - t2 = l * (1 + s); - else - t2 = l + s - l * s; - t1 = 2 * l - t2; - - rgb = [0, 0, 0]; - for (var i = 0; i < 3; i++) { - t3 = h + 1 / 3 * - (i - 1); - t3 < 0 && t3++; - t3 > 1 && t3--; - - if (6 * t3 < 1) - val = t1 + (t2 - t1) * 6 * t3; - else if (2 * t3 < 1) - val = t2; - else if (3 * t3 < 2) - val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; - else - val = t1; - - rgb[i] = val * 255; - } - - return rgb; -} - -function hsl2hsv(hsl) { - var h = hsl[0], - s = hsl[1] / 100, - l = hsl[2] / 100, - sv, v; - - if(l === 0) { - // no need to do calc on black - // also avoids divide by 0 error - return [0, 0, 0]; - } - - l *= 2; - s *= (l <= 1) ? l : 2 - l; - v = (l + s) / 2; - sv = (2 * s) / (l + s); - return [h, sv * 100, v * 100]; -} - -function hsl2hwb(args) { - return rgb2hwb(hsl2rgb(args)); -} - -function hsl2cmyk(args) { - return rgb2cmyk(hsl2rgb(args)); -} - -function hsl2keyword(args) { - return rgb2keyword(hsl2rgb(args)); -} - - -function hsv2rgb(hsv) { - var h = hsv[0] / 60, - s = hsv[1] / 100, - v = hsv[2] / 100, - hi = Math.floor(h) % 6; - - var f = h - Math.floor(h), - p = 255 * v * (1 - s), - q = 255 * v * (1 - (s * f)), - t = 255 * v * (1 - (s * (1 - f))), - v = 255 * v; - - switch(hi) { - case 0: - return [v, t, p]; - case 1: - return [q, v, p]; - case 2: - return [p, v, t]; - case 3: - return [p, q, v]; - case 4: - return [t, p, v]; - case 5: - return [v, p, q]; - } -} - -function hsv2hsl(hsv) { - var h = hsv[0], - s = hsv[1] / 100, - v = hsv[2] / 100, - sl, l; - - l = (2 - s) * v; - sl = s * v; - sl /= (l <= 1) ? l : 2 - l; - sl = sl || 0; - l /= 2; - return [h, sl * 100, l * 100]; -} - -function hsv2hwb(args) { - return rgb2hwb(hsv2rgb(args)) -} - -function hsv2cmyk(args) { - return rgb2cmyk(hsv2rgb(args)); -} - -function hsv2keyword(args) { - return rgb2keyword(hsv2rgb(args)); -} - -// http://dev.w3.org/csswg/css-color/#hwb-to-rgb -function hwb2rgb(hwb) { - var h = hwb[0] / 360, - wh = hwb[1] / 100, - bl = hwb[2] / 100, - ratio = wh + bl, - i, v, f, n; - - // wh + bl cant be > 1 - if (ratio > 1) { - wh /= ratio; - bl /= ratio; - } - - i = Math.floor(6 * h); - v = 1 - bl; - f = 6 * h - i; - if ((i & 0x01) != 0) { - f = 1 - f; - } - n = wh + f * (v - wh); // linear interpolation - - switch (i) { - default: - case 6: - case 0: r = v; g = n; b = wh; break; - case 1: r = n; g = v; b = wh; break; - case 2: r = wh; g = v; b = n; break; - case 3: r = wh; g = n; b = v; break; - case 4: r = n; g = wh; b = v; break; - case 5: r = v; g = wh; b = n; break; - } - - return [r * 255, g * 255, b * 255]; -} - -function hwb2hsl(args) { - return rgb2hsl(hwb2rgb(args)); -} - -function hwb2hsv(args) { - return rgb2hsv(hwb2rgb(args)); -} - -function hwb2cmyk(args) { - return rgb2cmyk(hwb2rgb(args)); -} - -function hwb2keyword(args) { - return rgb2keyword(hwb2rgb(args)); -} - -function cmyk2rgb(cmyk) { - var c = cmyk[0] / 100, - m = cmyk[1] / 100, - y = cmyk[2] / 100, - k = cmyk[3] / 100, - r, g, b; - - r = 1 - Math.min(1, c * (1 - k) + k); - g = 1 - Math.min(1, m * (1 - k) + k); - b = 1 - Math.min(1, y * (1 - k) + k); - return [r * 255, g * 255, b * 255]; -} - -function cmyk2hsl(args) { - return rgb2hsl(cmyk2rgb(args)); -} - -function cmyk2hsv(args) { - return rgb2hsv(cmyk2rgb(args)); -} - -function cmyk2hwb(args) { - return rgb2hwb(cmyk2rgb(args)); -} - -function cmyk2keyword(args) { - return rgb2keyword(cmyk2rgb(args)); -} - - -function xyz2rgb(xyz) { - var x = xyz[0] / 100, - y = xyz[1] / 100, - z = xyz[2] / 100, - r, g, b; - - r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); - g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); - b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); - - // assume sRGB - r = r > 0.0031308 ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055) - : r = (r * 12.92); - - g = g > 0.0031308 ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055) - : g = (g * 12.92); - - b = b > 0.0031308 ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055) - : b = (b * 12.92); - - r = Math.min(Math.max(0, r), 1); - g = Math.min(Math.max(0, g), 1); - b = Math.min(Math.max(0, b), 1); - - return [r * 255, g * 255, b * 255]; -} - -function xyz2lab(xyz) { - var x = xyz[0], - y = xyz[1], - z = xyz[2], - l, a, b; - - x /= 95.047; - y /= 100; - z /= 108.883; - - x = x > 0.008856 ? Math.pow(x, 1/3) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? Math.pow(y, 1/3) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? Math.pow(z, 1/3) : (7.787 * z) + (16 / 116); - - l = (116 * y) - 16; - a = 500 * (x - y); - b = 200 * (y - z); - - return [l, a, b]; -} - -function xyz2lch(args) { - return lab2lch(xyz2lab(args)); -} - -function lab2xyz(lab) { - var l = lab[0], - a = lab[1], - b = lab[2], - x, y, z, y2; - - if (l <= 8) { - y = (l * 100) / 903.3; - y2 = (7.787 * (y / 100)) + (16 / 116); - } else { - y = 100 * Math.pow((l + 16) / 116, 3); - y2 = Math.pow(y / 100, 1/3); - } - - x = x / 95.047 <= 0.008856 ? x = (95.047 * ((a / 500) + y2 - (16 / 116))) / 7.787 : 95.047 * Math.pow((a / 500) + y2, 3); - - z = z / 108.883 <= 0.008859 ? z = (108.883 * (y2 - (b / 200) - (16 / 116))) / 7.787 : 108.883 * Math.pow(y2 - (b / 200), 3); - - return [x, y, z]; -} - -function lab2lch(lab) { - var l = lab[0], - a = lab[1], - b = lab[2], - hr, h, c; - - hr = Math.atan2(b, a); - h = hr * 360 / 2 / Math.PI; - if (h < 0) { - h += 360; - } - c = Math.sqrt(a * a + b * b); - return [l, c, h]; -} - -function lab2rgb(args) { - return xyz2rgb(lab2xyz(args)); -} - -function lch2lab(lch) { - var l = lch[0], - c = lch[1], - h = lch[2], - a, b, hr; - - hr = h / 360 * 2 * Math.PI; - a = c * Math.cos(hr); - b = c * Math.sin(hr); - return [l, a, b]; -} - -function lch2xyz(args) { - return lab2xyz(lch2lab(args)); -} - -function lch2rgb(args) { - return lab2rgb(lch2lab(args)); -} - -function keyword2rgb(keyword) { - return cssKeywords[keyword]; -} - -function keyword2hsl(args) { - return rgb2hsl(keyword2rgb(args)); -} - -function keyword2hsv(args) { - return rgb2hsv(keyword2rgb(args)); -} - -function keyword2hwb(args) { - return rgb2hwb(keyword2rgb(args)); -} - -function keyword2cmyk(args) { - return rgb2cmyk(keyword2rgb(args)); -} - -function keyword2lab(args) { - return rgb2lab(keyword2rgb(args)); -} - -function keyword2xyz(args) { - return rgb2xyz(keyword2rgb(args)); -} - -var cssKeywords = { - aliceblue: [240,248,255], - antiquewhite: [250,235,215], - aqua: [0,255,255], - aquamarine: [127,255,212], - azure: [240,255,255], - beige: [245,245,220], - bisque: [255,228,196], - black: [0,0,0], - blanchedalmond: [255,235,205], - blue: [0,0,255], - blueviolet: [138,43,226], - brown: [165,42,42], - burlywood: [222,184,135], - cadetblue: [95,158,160], - chartreuse: [127,255,0], - chocolate: [210,105,30], - coral: [255,127,80], - cornflowerblue: [100,149,237], - cornsilk: [255,248,220], - crimson: [220,20,60], - cyan: [0,255,255], - darkblue: [0,0,139], - darkcyan: [0,139,139], - darkgoldenrod: [184,134,11], - darkgray: [169,169,169], - darkgreen: [0,100,0], - darkgrey: [169,169,169], - darkkhaki: [189,183,107], - darkmagenta: [139,0,139], - darkolivegreen: [85,107,47], - darkorange: [255,140,0], - darkorchid: [153,50,204], - darkred: [139,0,0], - darksalmon: [233,150,122], - darkseagreen: [143,188,143], - darkslateblue: [72,61,139], - darkslategray: [47,79,79], - darkslategrey: [47,79,79], - darkturquoise: [0,206,209], - darkviolet: [148,0,211], - deeppink: [255,20,147], - deepskyblue: [0,191,255], - dimgray: [105,105,105], - dimgrey: [105,105,105], - dodgerblue: [30,144,255], - firebrick: [178,34,34], - floralwhite: [255,250,240], - forestgreen: [34,139,34], - fuchsia: [255,0,255], - gainsboro: [220,220,220], - ghostwhite: [248,248,255], - gold: [255,215,0], - goldenrod: [218,165,32], - gray: [128,128,128], - green: [0,128,0], - greenyellow: [173,255,47], - grey: [128,128,128], - honeydew: [240,255,240], - hotpink: [255,105,180], - indianred: [205,92,92], - indigo: [75,0,130], - ivory: [255,255,240], - khaki: [240,230,140], - lavender: [230,230,250], - lavenderblush: [255,240,245], - lawngreen: [124,252,0], - lemonchiffon: [255,250,205], - lightblue: [173,216,230], - lightcoral: [240,128,128], - lightcyan: [224,255,255], - lightgoldenrodyellow: [250,250,210], - lightgray: [211,211,211], - lightgreen: [144,238,144], - lightgrey: [211,211,211], - lightpink: [255,182,193], - lightsalmon: [255,160,122], - lightseagreen: [32,178,170], - lightskyblue: [135,206,250], - lightslategray: [119,136,153], - lightslategrey: [119,136,153], - lightsteelblue: [176,196,222], - lightyellow: [255,255,224], - lime: [0,255,0], - limegreen: [50,205,50], - linen: [250,240,230], - magenta: [255,0,255], - maroon: [128,0,0], - mediumaquamarine: [102,205,170], - mediumblue: [0,0,205], - mediumorchid: [186,85,211], - mediumpurple: [147,112,219], - mediumseagreen: [60,179,113], - mediumslateblue: [123,104,238], - mediumspringgreen: [0,250,154], - mediumturquoise: [72,209,204], - mediumvioletred: [199,21,133], - midnightblue: [25,25,112], - mintcream: [245,255,250], - mistyrose: [255,228,225], - moccasin: [255,228,181], - navajowhite: [255,222,173], - navy: [0,0,128], - oldlace: [253,245,230], - olive: [128,128,0], - olivedrab: [107,142,35], - orange: [255,165,0], - orangered: [255,69,0], - orchid: [218,112,214], - palegoldenrod: [238,232,170], - palegreen: [152,251,152], - paleturquoise: [175,238,238], - palevioletred: [219,112,147], - papayawhip: [255,239,213], - peachpuff: [255,218,185], - peru: [205,133,63], - pink: [255,192,203], - plum: [221,160,221], - powderblue: [176,224,230], - purple: [128,0,128], - rebeccapurple: [102, 51, 153], - red: [255,0,0], - rosybrown: [188,143,143], - royalblue: [65,105,225], - saddlebrown: [139,69,19], - salmon: [250,128,114], - sandybrown: [244,164,96], - seagreen: [46,139,87], - seashell: [255,245,238], - sienna: [160,82,45], - silver: [192,192,192], - skyblue: [135,206,235], - slateblue: [106,90,205], - slategray: [112,128,144], - slategrey: [112,128,144], - snow: [255,250,250], - springgreen: [0,255,127], - steelblue: [70,130,180], - tan: [210,180,140], - teal: [0,128,128], - thistle: [216,191,216], - tomato: [255,99,71], - turquoise: [64,224,208], - violet: [238,130,238], - wheat: [245,222,179], - white: [255,255,255], - whitesmoke: [245,245,245], - yellow: [255,255,0], - yellowgreen: [154,205,50] -}; - -var reverseKeywords = {}; -for (var key in cssKeywords) { - reverseKeywords[JSON.stringify(cssKeywords[key])] = key; -} - -var convert = function() { - return new Converter(); -}; - -for (var func in conversions) { - // export Raw versions - convert[func + "Raw"] = (function(func) { - // accept array or plain args - return function(arg) { - if (typeof arg == "number") - arg = Array.prototype.slice.call(arguments); - return conversions[func](arg); - } - })(func); - - var pair = /(\w+)2(\w+)/.exec(func), - from = pair[1], - to = pair[2]; - - // export rgb2hsl and ["rgb"]["hsl"] - convert[from] = convert[from] || {}; - - convert[from][to] = convert[func] = (function(func) { - return function(arg) { - if (typeof arg == "number") - arg = Array.prototype.slice.call(arguments); - - var val = conversions[func](arg); - if (typeof val == "string" || val === undefined) - return val; // keyword - - for (var i = 0; i < val.length; i++) - val[i] = Math.round(val[i]); - return val; - } - })(func); -} - - -/* Converter does lazy conversion and caching */ -var Converter = function() { - this.convs = {}; -}; - -/* Either get the values for a space or - set the values for a space, depending on args */ -Converter.prototype.routeSpace = function(space, args) { - var values = args[0]; - if (values === undefined) { - // color.rgb() - return this.getValues(space); - } - // color.rgb(10, 10, 10) - if (typeof values == "number") { - values = Array.prototype.slice.call(args); - } - - return this.setValues(space, values); -}; - -/* Set the values for a space, invalidating cache */ -Converter.prototype.setValues = function(space, values) { - this.space = space; - this.convs = {}; - this.convs[space] = values; - return this; -}; - -/* Get the values for a space. If there's already - a conversion for the space, fetch it, otherwise - compute it */ -Converter.prototype.getValues = function(space) { - var vals = this.convs[space]; - if (!vals) { - var fspace = this.space, - from = this.convs[fspace]; - vals = convert[fspace][space](from); - - this.convs[space] = vals; - } - return vals; -}; - -["rgb", "hsl", "hsv", "cmyk", "keyword"].forEach(function(space) { - Converter.prototype[space] = function(vals) { - return this.routeSpace(space, arguments); - }; -}); - -var colorConvert = convert; - -var colorName = { - "aliceblue": [240, 248, 255], - "antiquewhite": [250, 235, 215], - "aqua": [0, 255, 255], - "aquamarine": [127, 255, 212], - "azure": [240, 255, 255], - "beige": [245, 245, 220], - "bisque": [255, 228, 196], - "black": [0, 0, 0], - "blanchedalmond": [255, 235, 205], - "blue": [0, 0, 255], - "blueviolet": [138, 43, 226], - "brown": [165, 42, 42], - "burlywood": [222, 184, 135], - "cadetblue": [95, 158, 160], - "chartreuse": [127, 255, 0], - "chocolate": [210, 105, 30], - "coral": [255, 127, 80], - "cornflowerblue": [100, 149, 237], - "cornsilk": [255, 248, 220], - "crimson": [220, 20, 60], - "cyan": [0, 255, 255], - "darkblue": [0, 0, 139], - "darkcyan": [0, 139, 139], - "darkgoldenrod": [184, 134, 11], - "darkgray": [169, 169, 169], - "darkgreen": [0, 100, 0], - "darkgrey": [169, 169, 169], - "darkkhaki": [189, 183, 107], - "darkmagenta": [139, 0, 139], - "darkolivegreen": [85, 107, 47], - "darkorange": [255, 140, 0], - "darkorchid": [153, 50, 204], - "darkred": [139, 0, 0], - "darksalmon": [233, 150, 122], - "darkseagreen": [143, 188, 143], - "darkslateblue": [72, 61, 139], - "darkslategray": [47, 79, 79], - "darkslategrey": [47, 79, 79], - "darkturquoise": [0, 206, 209], - "darkviolet": [148, 0, 211], - "deeppink": [255, 20, 147], - "deepskyblue": [0, 191, 255], - "dimgray": [105, 105, 105], - "dimgrey": [105, 105, 105], - "dodgerblue": [30, 144, 255], - "firebrick": [178, 34, 34], - "floralwhite": [255, 250, 240], - "forestgreen": [34, 139, 34], - "fuchsia": [255, 0, 255], - "gainsboro": [220, 220, 220], - "ghostwhite": [248, 248, 255], - "gold": [255, 215, 0], - "goldenrod": [218, 165, 32], - "gray": [128, 128, 128], - "green": [0, 128, 0], - "greenyellow": [173, 255, 47], - "grey": [128, 128, 128], - "honeydew": [240, 255, 240], - "hotpink": [255, 105, 180], - "indianred": [205, 92, 92], - "indigo": [75, 0, 130], - "ivory": [255, 255, 240], - "khaki": [240, 230, 140], - "lavender": [230, 230, 250], - "lavenderblush": [255, 240, 245], - "lawngreen": [124, 252, 0], - "lemonchiffon": [255, 250, 205], - "lightblue": [173, 216, 230], - "lightcoral": [240, 128, 128], - "lightcyan": [224, 255, 255], - "lightgoldenrodyellow": [250, 250, 210], - "lightgray": [211, 211, 211], - "lightgreen": [144, 238, 144], - "lightgrey": [211, 211, 211], - "lightpink": [255, 182, 193], - "lightsalmon": [255, 160, 122], - "lightseagreen": [32, 178, 170], - "lightskyblue": [135, 206, 250], - "lightslategray": [119, 136, 153], - "lightslategrey": [119, 136, 153], - "lightsteelblue": [176, 196, 222], - "lightyellow": [255, 255, 224], - "lime": [0, 255, 0], - "limegreen": [50, 205, 50], - "linen": [250, 240, 230], - "magenta": [255, 0, 255], - "maroon": [128, 0, 0], - "mediumaquamarine": [102, 205, 170], - "mediumblue": [0, 0, 205], - "mediumorchid": [186, 85, 211], - "mediumpurple": [147, 112, 219], - "mediumseagreen": [60, 179, 113], - "mediumslateblue": [123, 104, 238], - "mediumspringgreen": [0, 250, 154], - "mediumturquoise": [72, 209, 204], - "mediumvioletred": [199, 21, 133], - "midnightblue": [25, 25, 112], - "mintcream": [245, 255, 250], - "mistyrose": [255, 228, 225], - "moccasin": [255, 228, 181], - "navajowhite": [255, 222, 173], - "navy": [0, 0, 128], - "oldlace": [253, 245, 230], - "olive": [128, 128, 0], - "olivedrab": [107, 142, 35], - "orange": [255, 165, 0], - "orangered": [255, 69, 0], - "orchid": [218, 112, 214], - "palegoldenrod": [238, 232, 170], - "palegreen": [152, 251, 152], - "paleturquoise": [175, 238, 238], - "palevioletred": [219, 112, 147], - "papayawhip": [255, 239, 213], - "peachpuff": [255, 218, 185], - "peru": [205, 133, 63], - "pink": [255, 192, 203], - "plum": [221, 160, 221], - "powderblue": [176, 224, 230], - "purple": [128, 0, 128], - "rebeccapurple": [102, 51, 153], - "red": [255, 0, 0], - "rosybrown": [188, 143, 143], - "royalblue": [65, 105, 225], - "saddlebrown": [139, 69, 19], - "salmon": [250, 128, 114], - "sandybrown": [244, 164, 96], - "seagreen": [46, 139, 87], - "seashell": [255, 245, 238], - "sienna": [160, 82, 45], - "silver": [192, 192, 192], - "skyblue": [135, 206, 235], - "slateblue": [106, 90, 205], - "slategray": [112, 128, 144], - "slategrey": [112, 128, 144], - "snow": [255, 250, 250], - "springgreen": [0, 255, 127], - "steelblue": [70, 130, 180], - "tan": [210, 180, 140], - "teal": [0, 128, 128], - "thistle": [216, 191, 216], - "tomato": [255, 99, 71], - "turquoise": [64, 224, 208], - "violet": [238, 130, 238], - "wheat": [245, 222, 179], - "white": [255, 255, 255], - "whitesmoke": [245, 245, 245], - "yellow": [255, 255, 0], - "yellowgreen": [154, 205, 50] -}; - -/* MIT license */ - - -var colorString = { - getRgba: getRgba, - getHsla: getHsla, - getRgb: getRgb, - getHsl: getHsl, - getHwb: getHwb, - getAlpha: getAlpha, - - hexString: hexString, - rgbString: rgbString, - rgbaString: rgbaString, - percentString: percentString, - percentaString: percentaString, - hslString: hslString, - hslaString: hslaString, - hwbString: hwbString, - keyword: keyword -}; - -function getRgba(string) { - if (!string) { - return; - } - var abbr = /^#([a-fA-F0-9]{3,4})$/i, - hex = /^#([a-fA-F0-9]{6}([a-fA-F0-9]{2})?)$/i, - rgba = /^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i, - per = /^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i, - keyword = /(\w+)/; - - var rgb = [0, 0, 0], - a = 1, - match = string.match(abbr), - hexAlpha = ""; - if (match) { - match = match[1]; - hexAlpha = match[3]; - for (var i = 0; i < rgb.length; i++) { - rgb[i] = parseInt(match[i] + match[i], 16); - } - if (hexAlpha) { - a = Math.round((parseInt(hexAlpha + hexAlpha, 16) / 255) * 100) / 100; - } - } - else if (match = string.match(hex)) { - hexAlpha = match[2]; - match = match[1]; - for (var i = 0; i < rgb.length; i++) { - rgb[i] = parseInt(match.slice(i * 2, i * 2 + 2), 16); - } - if (hexAlpha) { - a = Math.round((parseInt(hexAlpha, 16) / 255) * 100) / 100; - } - } - else if (match = string.match(rgba)) { - for (var i = 0; i < rgb.length; i++) { - rgb[i] = parseInt(match[i + 1]); - } - a = parseFloat(match[4]); - } - else if (match = string.match(per)) { - for (var i = 0; i < rgb.length; i++) { - rgb[i] = Math.round(parseFloat(match[i + 1]) * 2.55); - } - a = parseFloat(match[4]); - } - else if (match = string.match(keyword)) { - if (match[1] == "transparent") { - return [0, 0, 0, 0]; - } - rgb = colorName[match[1]]; - if (!rgb) { - return; - } - } - - for (var i = 0; i < rgb.length; i++) { - rgb[i] = scale(rgb[i], 0, 255); - } - if (!a && a != 0) { - a = 1; - } - else { - a = scale(a, 0, 1); - } - rgb[3] = a; - return rgb; -} - -function getHsla(string) { - if (!string) { - return; - } - var hsl = /^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/; - var match = string.match(hsl); - if (match) { - var alpha = parseFloat(match[4]); - var h = scale(parseInt(match[1]), 0, 360), - s = scale(parseFloat(match[2]), 0, 100), - l = scale(parseFloat(match[3]), 0, 100), - a = scale(isNaN(alpha) ? 1 : alpha, 0, 1); - return [h, s, l, a]; - } -} - -function getHwb(string) { - if (!string) { - return; - } - var hwb = /^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/; - var match = string.match(hwb); - if (match) { - var alpha = parseFloat(match[4]); - var h = scale(parseInt(match[1]), 0, 360), - w = scale(parseFloat(match[2]), 0, 100), - b = scale(parseFloat(match[3]), 0, 100), - a = scale(isNaN(alpha) ? 1 : alpha, 0, 1); - return [h, w, b, a]; - } -} - -function getRgb(string) { - var rgba = getRgba(string); - return rgba && rgba.slice(0, 3); -} - -function getHsl(string) { - var hsla = getHsla(string); - return hsla && hsla.slice(0, 3); -} - -function getAlpha(string) { - var vals = getRgba(string); - if (vals) { - return vals[3]; - } - else if (vals = getHsla(string)) { - return vals[3]; - } - else if (vals = getHwb(string)) { - return vals[3]; - } -} - -// generators -function hexString(rgba, a) { - var a = (a !== undefined && rgba.length === 3) ? a : rgba[3]; - return "#" + hexDouble(rgba[0]) - + hexDouble(rgba[1]) - + hexDouble(rgba[2]) - + ( - (a >= 0 && a < 1) - ? hexDouble(Math.round(a * 255)) - : "" - ); -} - -function rgbString(rgba, alpha) { - if (alpha < 1 || (rgba[3] && rgba[3] < 1)) { - return rgbaString(rgba, alpha); - } - return "rgb(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] + ")"; -} - -function rgbaString(rgba, alpha) { - if (alpha === undefined) { - alpha = (rgba[3] !== undefined ? rgba[3] : 1); - } - return "rgba(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] - + ", " + alpha + ")"; -} - -function percentString(rgba, alpha) { - if (alpha < 1 || (rgba[3] && rgba[3] < 1)) { - return percentaString(rgba, alpha); - } - var r = Math.round(rgba[0]/255 * 100), - g = Math.round(rgba[1]/255 * 100), - b = Math.round(rgba[2]/255 * 100); - - return "rgb(" + r + "%, " + g + "%, " + b + "%)"; -} - -function percentaString(rgba, alpha) { - var r = Math.round(rgba[0]/255 * 100), - g = Math.round(rgba[1]/255 * 100), - b = Math.round(rgba[2]/255 * 100); - return "rgba(" + r + "%, " + g + "%, " + b + "%, " + (alpha || rgba[3] || 1) + ")"; -} - -function hslString(hsla, alpha) { - if (alpha < 1 || (hsla[3] && hsla[3] < 1)) { - return hslaString(hsla, alpha); - } - return "hsl(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%)"; -} - -function hslaString(hsla, alpha) { - if (alpha === undefined) { - alpha = (hsla[3] !== undefined ? hsla[3] : 1); - } - return "hsla(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%, " - + alpha + ")"; -} - -// hwb is a bit different than rgb(a) & hsl(a) since there is no alpha specific syntax -// (hwb have alpha optional & 1 is default value) -function hwbString(hwb, alpha) { - if (alpha === undefined) { - alpha = (hwb[3] !== undefined ? hwb[3] : 1); - } - return "hwb(" + hwb[0] + ", " + hwb[1] + "%, " + hwb[2] + "%" - + (alpha !== undefined && alpha !== 1 ? ", " + alpha : "") + ")"; -} - -function keyword(rgb) { - return reverseNames[rgb.slice(0, 3)]; -} - -// helpers -function scale(num, min, max) { - return Math.min(Math.max(min, num), max); -} - -function hexDouble(num) { - var str = num.toString(16).toUpperCase(); - return (str.length < 2) ? "0" + str : str; -} - - -//create a list of reverse color names -var reverseNames = {}; -for (var name in colorName) { - reverseNames[colorName[name]] = name; -} - -/* MIT license */ - - - -var Color = function (obj) { - if (obj instanceof Color) { - return obj; - } - if (!(this instanceof Color)) { - return new Color(obj); - } - - this.valid = false; - this.values = { - rgb: [0, 0, 0], - hsl: [0, 0, 0], - hsv: [0, 0, 0], - hwb: [0, 0, 0], - cmyk: [0, 0, 0, 0], - alpha: 1 - }; - - // parse Color() argument - var vals; - if (typeof obj === 'string') { - vals = colorString.getRgba(obj); - if (vals) { - this.setValues('rgb', vals); - } else if (vals = colorString.getHsla(obj)) { - this.setValues('hsl', vals); - } else if (vals = colorString.getHwb(obj)) { - this.setValues('hwb', vals); - } - } else if (typeof obj === 'object') { - vals = obj; - if (vals.r !== undefined || vals.red !== undefined) { - this.setValues('rgb', vals); - } else if (vals.l !== undefined || vals.lightness !== undefined) { - this.setValues('hsl', vals); - } else if (vals.v !== undefined || vals.value !== undefined) { - this.setValues('hsv', vals); - } else if (vals.w !== undefined || vals.whiteness !== undefined) { - this.setValues('hwb', vals); - } else if (vals.c !== undefined || vals.cyan !== undefined) { - this.setValues('cmyk', vals); - } - } -}; - -Color.prototype = { - isValid: function () { - return this.valid; - }, - rgb: function () { - return this.setSpace('rgb', arguments); - }, - hsl: function () { - return this.setSpace('hsl', arguments); - }, - hsv: function () { - return this.setSpace('hsv', arguments); - }, - hwb: function () { - return this.setSpace('hwb', arguments); - }, - cmyk: function () { - return this.setSpace('cmyk', arguments); - }, - - rgbArray: function () { - return this.values.rgb; - }, - hslArray: function () { - return this.values.hsl; - }, - hsvArray: function () { - return this.values.hsv; - }, - hwbArray: function () { - var values = this.values; - if (values.alpha !== 1) { - return values.hwb.concat([values.alpha]); - } - return values.hwb; - }, - cmykArray: function () { - return this.values.cmyk; - }, - rgbaArray: function () { - var values = this.values; - return values.rgb.concat([values.alpha]); - }, - hslaArray: function () { - var values = this.values; - return values.hsl.concat([values.alpha]); - }, - alpha: function (val) { - if (val === undefined) { - return this.values.alpha; - } - this.setValues('alpha', val); - return this; - }, - - red: function (val) { - return this.setChannel('rgb', 0, val); - }, - green: function (val) { - return this.setChannel('rgb', 1, val); - }, - blue: function (val) { - return this.setChannel('rgb', 2, val); - }, - hue: function (val) { - if (val) { - val %= 360; - val = val < 0 ? 360 + val : val; - } - return this.setChannel('hsl', 0, val); - }, - saturation: function (val) { - return this.setChannel('hsl', 1, val); - }, - lightness: function (val) { - return this.setChannel('hsl', 2, val); - }, - saturationv: function (val) { - return this.setChannel('hsv', 1, val); - }, - whiteness: function (val) { - return this.setChannel('hwb', 1, val); - }, - blackness: function (val) { - return this.setChannel('hwb', 2, val); - }, - value: function (val) { - return this.setChannel('hsv', 2, val); - }, - cyan: function (val) { - return this.setChannel('cmyk', 0, val); - }, - magenta: function (val) { - return this.setChannel('cmyk', 1, val); - }, - yellow: function (val) { - return this.setChannel('cmyk', 2, val); - }, - black: function (val) { - return this.setChannel('cmyk', 3, val); - }, - - hexString: function () { - return colorString.hexString(this.values.rgb); - }, - rgbString: function () { - return colorString.rgbString(this.values.rgb, this.values.alpha); - }, - rgbaString: function () { - return colorString.rgbaString(this.values.rgb, this.values.alpha); - }, - percentString: function () { - return colorString.percentString(this.values.rgb, this.values.alpha); - }, - hslString: function () { - return colorString.hslString(this.values.hsl, this.values.alpha); - }, - hslaString: function () { - return colorString.hslaString(this.values.hsl, this.values.alpha); - }, - hwbString: function () { - return colorString.hwbString(this.values.hwb, this.values.alpha); - }, - keyword: function () { - return colorString.keyword(this.values.rgb, this.values.alpha); - }, - - rgbNumber: function () { - var rgb = this.values.rgb; - return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2]; - }, - - luminosity: function () { - // http://www.w3.org/TR/WCAG20/#relativeluminancedef - var rgb = this.values.rgb; - var lum = []; - for (var i = 0; i < rgb.length; i++) { - var chan = rgb[i] / 255; - lum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4); - } - return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2]; - }, - - contrast: function (color2) { - // http://www.w3.org/TR/WCAG20/#contrast-ratiodef - var lum1 = this.luminosity(); - var lum2 = color2.luminosity(); - if (lum1 > lum2) { - return (lum1 + 0.05) / (lum2 + 0.05); - } - return (lum2 + 0.05) / (lum1 + 0.05); - }, - - level: function (color2) { - var contrastRatio = this.contrast(color2); - if (contrastRatio >= 7.1) { - return 'AAA'; - } - - return (contrastRatio >= 4.5) ? 'AA' : ''; - }, - - dark: function () { - // YIQ equation from http://24ways.org/2010/calculating-color-contrast - var rgb = this.values.rgb; - var yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000; - return yiq < 128; - }, - - light: function () { - return !this.dark(); - }, - - negate: function () { - var rgb = []; - for (var i = 0; i < 3; i++) { - rgb[i] = 255 - this.values.rgb[i]; - } - this.setValues('rgb', rgb); - return this; - }, - - lighten: function (ratio) { - var hsl = this.values.hsl; - hsl[2] += hsl[2] * ratio; - this.setValues('hsl', hsl); - return this; - }, - - darken: function (ratio) { - var hsl = this.values.hsl; - hsl[2] -= hsl[2] * ratio; - this.setValues('hsl', hsl); - return this; - }, - - saturate: function (ratio) { - var hsl = this.values.hsl; - hsl[1] += hsl[1] * ratio; - this.setValues('hsl', hsl); - return this; - }, - - desaturate: function (ratio) { - var hsl = this.values.hsl; - hsl[1] -= hsl[1] * ratio; - this.setValues('hsl', hsl); - return this; - }, - - whiten: function (ratio) { - var hwb = this.values.hwb; - hwb[1] += hwb[1] * ratio; - this.setValues('hwb', hwb); - return this; - }, - - blacken: function (ratio) { - var hwb = this.values.hwb; - hwb[2] += hwb[2] * ratio; - this.setValues('hwb', hwb); - return this; - }, - - greyscale: function () { - var rgb = this.values.rgb; - // http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale - var val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11; - this.setValues('rgb', [val, val, val]); - return this; - }, - - clearer: function (ratio) { - var alpha = this.values.alpha; - this.setValues('alpha', alpha - (alpha * ratio)); - return this; - }, - - opaquer: function (ratio) { - var alpha = this.values.alpha; - this.setValues('alpha', alpha + (alpha * ratio)); - return this; - }, - - rotate: function (degrees) { - var hsl = this.values.hsl; - var hue = (hsl[0] + degrees) % 360; - hsl[0] = hue < 0 ? 360 + hue : hue; - this.setValues('hsl', hsl); - return this; - }, - - /** - * Ported from sass implementation in C - * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209 - */ - mix: function (mixinColor, weight) { - var color1 = this; - var color2 = mixinColor; - var p = weight === undefined ? 0.5 : weight; - - var w = 2 * p - 1; - var a = color1.alpha() - color2.alpha(); - - var w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0; - var w2 = 1 - w1; - - return this - .rgb( - w1 * color1.red() + w2 * color2.red(), - w1 * color1.green() + w2 * color2.green(), - w1 * color1.blue() + w2 * color2.blue() - ) - .alpha(color1.alpha() * p + color2.alpha() * (1 - p)); - }, - - toJSON: function () { - return this.rgb(); - }, - - clone: function () { - // NOTE(SB): using node-clone creates a dependency to Buffer when using browserify, - // making the final build way to big to embed in Chart.js. So let's do it manually, - // assuming that values to clone are 1 dimension arrays containing only numbers, - // except 'alpha' which is a number. - var result = new Color(); - var source = this.values; - var target = result.values; - var value, type; - - for (var prop in source) { - if (source.hasOwnProperty(prop)) { - value = source[prop]; - type = ({}).toString.call(value); - if (type === '[object Array]') { - target[prop] = value.slice(0); - } else if (type === '[object Number]') { - target[prop] = value; - } else { - console.error('unexpected color value:', value); - } - } - } - - return result; - } -}; - -Color.prototype.spaces = { - rgb: ['red', 'green', 'blue'], - hsl: ['hue', 'saturation', 'lightness'], - hsv: ['hue', 'saturation', 'value'], - hwb: ['hue', 'whiteness', 'blackness'], - cmyk: ['cyan', 'magenta', 'yellow', 'black'] -}; - -Color.prototype.maxes = { - rgb: [255, 255, 255], - hsl: [360, 100, 100], - hsv: [360, 100, 100], - hwb: [360, 100, 100], - cmyk: [100, 100, 100, 100] -}; - -Color.prototype.getValues = function (space) { - var values = this.values; - var vals = {}; - - for (var i = 0; i < space.length; i++) { - vals[space.charAt(i)] = values[space][i]; - } - - if (values.alpha !== 1) { - vals.a = values.alpha; - } - - // {r: 255, g: 255, b: 255, a: 0.4} - return vals; -}; - -Color.prototype.setValues = function (space, vals) { - var values = this.values; - var spaces = this.spaces; - var maxes = this.maxes; - var alpha = 1; - var i; - - this.valid = true; - - if (space === 'alpha') { - alpha = vals; - } else if (vals.length) { - // [10, 10, 10] - values[space] = vals.slice(0, space.length); - alpha = vals[space.length]; - } else if (vals[space.charAt(0)] !== undefined) { - // {r: 10, g: 10, b: 10} - for (i = 0; i < space.length; i++) { - values[space][i] = vals[space.charAt(i)]; - } - - alpha = vals.a; - } else if (vals[spaces[space][0]] !== undefined) { - // {red: 10, green: 10, blue: 10} - var chans = spaces[space]; - - for (i = 0; i < space.length; i++) { - values[space][i] = vals[chans[i]]; - } - - alpha = vals.alpha; - } - - values.alpha = Math.max(0, Math.min(1, (alpha === undefined ? values.alpha : alpha))); - - if (space === 'alpha') { - return false; - } - - var capped; - - // cap values of the space prior converting all values - for (i = 0; i < space.length; i++) { - capped = Math.max(0, Math.min(maxes[space][i], values[space][i])); - values[space][i] = Math.round(capped); - } - - // convert to all the other color spaces - for (var sname in spaces) { - if (sname !== space) { - values[sname] = colorConvert[space][sname](values[space]); - } - } - - return true; -}; - -Color.prototype.setSpace = function (space, args) { - var vals = args[0]; - - if (vals === undefined) { - // color.rgb() - return this.getValues(space); - } - - // color.rgb(10, 10, 10) - if (typeof vals === 'number') { - vals = Array.prototype.slice.call(args); - } - - this.setValues(space, vals); - return this; -}; - -Color.prototype.setChannel = function (space, index, val) { - var svalues = this.values[space]; - if (val === undefined) { - // color.red() - return svalues[index]; - } else if (val === svalues[index]) { - // color.red(color.red()) - return this; - } - - // color.red(100) - svalues[index] = val; - this.setValues(space, svalues); - - return this; -}; - -if (typeof window !== 'undefined') { - window.Color = Color; -} - -var chartjsColor = Color; - -/** - * @namespace Chart.helpers - */ -var helpers = { - /** - * An empty function that can be used, for example, for optional callback. - */ - noop: function() {}, - - /** - * Returns a unique id, sequentially generated from a global variable. - * @returns {number} - * @function - */ - uid: (function() { - var id = 0; - return function() { - return id++; - }; - }()), - - /** - * Returns true if `value` is neither null nor undefined, else returns false. - * @param {*} value - The value to test. - * @returns {boolean} - * @since 2.7.0 - */ - isNullOrUndef: function(value) { - return value === null || typeof value === 'undefined'; - }, - - /** - * Returns true if `value` is an array (including typed arrays), else returns false. - * @param {*} value - The value to test. - * @returns {boolean} - * @function - */ - isArray: function(value) { - if (Array.isArray && Array.isArray(value)) { - return true; - } - var type = Object.prototype.toString.call(value); - if (type.substr(0, 7) === '[object' && type.substr(-6) === 'Array]') { - return true; - } - return false; - }, - - /** - * Returns true if `value` is an object (excluding null), else returns false. - * @param {*} value - The value to test. - * @returns {boolean} - * @since 2.7.0 - */ - isObject: function(value) { - return value !== null && Object.prototype.toString.call(value) === '[object Object]'; - }, - - /** - * Returns true if `value` is a finite number, else returns false - * @param {*} value - The value to test. - * @returns {boolean} - */ - isFinite: function(value) { - return (typeof value === 'number' || value instanceof Number) && isFinite(value); - }, - - /** - * Returns `value` if defined, else returns `defaultValue`. - * @param {*} value - The value to return if defined. - * @param {*} defaultValue - The value to return if `value` is undefined. - * @returns {*} - */ - valueOrDefault: function(value, defaultValue) { - return typeof value === 'undefined' ? defaultValue : value; - }, - - /** - * Returns value at the given `index` in array if defined, else returns `defaultValue`. - * @param {Array} value - The array to lookup for value at `index`. - * @param {number} index - The index in `value` to lookup for value. - * @param {*} defaultValue - The value to return if `value[index]` is undefined. - * @returns {*} - */ - valueAtIndexOrDefault: function(value, index, defaultValue) { - return helpers.valueOrDefault(helpers.isArray(value) ? value[index] : value, defaultValue); - }, - - /** - * Calls `fn` with the given `args` in the scope defined by `thisArg` and returns the - * value returned by `fn`. If `fn` is not a function, this method returns undefined. - * @param {function} fn - The function to call. - * @param {Array|undefined|null} args - The arguments with which `fn` should be called. - * @param {object} [thisArg] - The value of `this` provided for the call to `fn`. - * @returns {*} - */ - callback: function(fn, args, thisArg) { - if (fn && typeof fn.call === 'function') { - return fn.apply(thisArg, args); - } - }, - - /** - * Note(SB) for performance sake, this method should only be used when loopable type - * is unknown or in none intensive code (not called often and small loopable). Else - * it's preferable to use a regular for() loop and save extra function calls. - * @param {object|Array} loopable - The object or array to be iterated. - * @param {function} fn - The function to call for each item. - * @param {object} [thisArg] - The value of `this` provided for the call to `fn`. - * @param {boolean} [reverse] - If true, iterates backward on the loopable. - */ - each: function(loopable, fn, thisArg, reverse) { - var i, len, keys; - if (helpers.isArray(loopable)) { - len = loopable.length; - if (reverse) { - for (i = len - 1; i >= 0; i--) { - fn.call(thisArg, loopable[i], i); - } - } else { - for (i = 0; i < len; i++) { - fn.call(thisArg, loopable[i], i); - } - } - } else if (helpers.isObject(loopable)) { - keys = Object.keys(loopable); - len = keys.length; - for (i = 0; i < len; i++) { - fn.call(thisArg, loopable[keys[i]], keys[i]); - } - } - }, - - /** - * Returns true if the `a0` and `a1` arrays have the same content, else returns false. - * @see https://stackoverflow.com/a/14853974 - * @param {Array} a0 - The array to compare - * @param {Array} a1 - The array to compare - * @returns {boolean} - */ - arrayEquals: function(a0, a1) { - var i, ilen, v0, v1; - - if (!a0 || !a1 || a0.length !== a1.length) { - return false; - } - - for (i = 0, ilen = a0.length; i < ilen; ++i) { - v0 = a0[i]; - v1 = a1[i]; - - if (v0 instanceof Array && v1 instanceof Array) { - if (!helpers.arrayEquals(v0, v1)) { - return false; - } - } else if (v0 !== v1) { - // NOTE: two different object instances will never be equal: {x:20} != {x:20} - return false; - } - } - - return true; - }, - - /** - * Returns a deep copy of `source` without keeping references on objects and arrays. - * @param {*} source - The value to clone. - * @returns {*} - */ - clone: function(source) { - if (helpers.isArray(source)) { - return source.map(helpers.clone); - } - - if (helpers.isObject(source)) { - var target = {}; - var keys = Object.keys(source); - var klen = keys.length; - var k = 0; - - for (; k < klen; ++k) { - target[keys[k]] = helpers.clone(source[keys[k]]); - } - - return target; - } - - return source; - }, - - /** - * The default merger when Chart.helpers.merge is called without merger option. - * Note(SB): also used by mergeConfig and mergeScaleConfig as fallback. - * @private - */ - _merger: function(key, target, source, options) { - var tval = target[key]; - var sval = source[key]; - - if (helpers.isObject(tval) && helpers.isObject(sval)) { - helpers.merge(tval, sval, options); - } else { - target[key] = helpers.clone(sval); - } - }, - - /** - * Merges source[key] in target[key] only if target[key] is undefined. - * @private - */ - _mergerIf: function(key, target, source) { - var tval = target[key]; - var sval = source[key]; - - if (helpers.isObject(tval) && helpers.isObject(sval)) { - helpers.mergeIf(tval, sval); - } else if (!target.hasOwnProperty(key)) { - target[key] = helpers.clone(sval); - } - }, - - /** - * Recursively deep copies `source` properties into `target` with the given `options`. - * IMPORTANT: `target` is not cloned and will be updated with `source` properties. - * @param {object} target - The target object in which all sources are merged into. - * @param {object|object[]} source - Object(s) to merge into `target`. - * @param {object} [options] - Merging options: - * @param {function} [options.merger] - The merge method (key, target, source, options) - * @returns {object} The `target` object. - */ - merge: function(target, source, options) { - var sources = helpers.isArray(source) ? source : [source]; - var ilen = sources.length; - var merge, i, keys, klen, k; - - if (!helpers.isObject(target)) { - return target; - } - - options = options || {}; - merge = options.merger || helpers._merger; - - for (i = 0; i < ilen; ++i) { - source = sources[i]; - if (!helpers.isObject(source)) { - continue; - } - - keys = Object.keys(source); - for (k = 0, klen = keys.length; k < klen; ++k) { - merge(keys[k], target, source, options); - } - } - - return target; - }, - - /** - * Recursively deep copies `source` properties into `target` *only* if not defined in target. - * IMPORTANT: `target` is not cloned and will be updated with `source` properties. - * @param {object} target - The target object in which all sources are merged into. - * @param {object|object[]} source - Object(s) to merge into `target`. - * @returns {object} The `target` object. - */ - mergeIf: function(target, source) { - return helpers.merge(target, source, {merger: helpers._mergerIf}); - }, - - /** - * Applies the contents of two or more objects together into the first object. - * @param {object} target - The target object in which all objects are merged into. - * @param {object} arg1 - Object containing additional properties to merge in target. - * @param {object} argN - Additional objects containing properties to merge in target. - * @returns {object} The `target` object. - */ - extend: function(target) { - var setFn = function(value, key) { - target[key] = value; - }; - for (var i = 1, ilen = arguments.length; i < ilen; ++i) { - helpers.each(arguments[i], setFn); - } - return target; - }, - - /** - * Basic javascript inheritance based on the model created in Backbone.js - */ - inherits: function(extensions) { - var me = this; - var ChartElement = (extensions && extensions.hasOwnProperty('constructor')) ? extensions.constructor : function() { - return me.apply(this, arguments); - }; - - var Surrogate = function() { - this.constructor = ChartElement; - }; - - Surrogate.prototype = me.prototype; - ChartElement.prototype = new Surrogate(); - ChartElement.extend = helpers.inherits; - - if (extensions) { - helpers.extend(ChartElement.prototype, extensions); - } - - ChartElement.__super__ = me.prototype; - return ChartElement; - } -}; - -var helpers_core = helpers; - -// DEPRECATIONS - -/** - * Provided for backward compatibility, use Chart.helpers.callback instead. - * @function Chart.helpers.callCallback - * @deprecated since version 2.6.0 - * @todo remove at version 3 - * @private - */ -helpers.callCallback = helpers.callback; - -/** - * Provided for backward compatibility, use Array.prototype.indexOf instead. - * Array.prototype.indexOf compatibility: Chrome, Opera, Safari, FF1.5+, IE9+ - * @function Chart.helpers.indexOf - * @deprecated since version 2.7.0 - * @todo remove at version 3 - * @private - */ -helpers.indexOf = function(array, item, fromIndex) { - return Array.prototype.indexOf.call(array, item, fromIndex); -}; - -/** - * Provided for backward compatibility, use Chart.helpers.valueOrDefault instead. - * @function Chart.helpers.getValueOrDefault - * @deprecated since version 2.7.0 - * @todo remove at version 3 - * @private - */ -helpers.getValueOrDefault = helpers.valueOrDefault; - -/** - * Provided for backward compatibility, use Chart.helpers.valueAtIndexOrDefault instead. - * @function Chart.helpers.getValueAtIndexOrDefault - * @deprecated since version 2.7.0 - * @todo remove at version 3 - * @private - */ -helpers.getValueAtIndexOrDefault = helpers.valueAtIndexOrDefault; - -/** - * Easing functions adapted from Robert Penner's easing equations. - * @namespace Chart.helpers.easingEffects - * @see http://www.robertpenner.com/easing/ - */ -var effects = { - linear: function(t) { - return t; - }, - - easeInQuad: function(t) { - return t * t; - }, - - easeOutQuad: function(t) { - return -t * (t - 2); - }, - - easeInOutQuad: function(t) { - if ((t /= 0.5) < 1) { - return 0.5 * t * t; - } - return -0.5 * ((--t) * (t - 2) - 1); - }, - - easeInCubic: function(t) { - return t * t * t; - }, - - easeOutCubic: function(t) { - return (t = t - 1) * t * t + 1; - }, - - easeInOutCubic: function(t) { - if ((t /= 0.5) < 1) { - return 0.5 * t * t * t; - } - return 0.5 * ((t -= 2) * t * t + 2); - }, - - easeInQuart: function(t) { - return t * t * t * t; - }, - - easeOutQuart: function(t) { - return -((t = t - 1) * t * t * t - 1); - }, - - easeInOutQuart: function(t) { - if ((t /= 0.5) < 1) { - return 0.5 * t * t * t * t; - } - return -0.5 * ((t -= 2) * t * t * t - 2); - }, - - easeInQuint: function(t) { - return t * t * t * t * t; - }, - - easeOutQuint: function(t) { - return (t = t - 1) * t * t * t * t + 1; - }, - - easeInOutQuint: function(t) { - if ((t /= 0.5) < 1) { - return 0.5 * t * t * t * t * t; - } - return 0.5 * ((t -= 2) * t * t * t * t + 2); - }, - - easeInSine: function(t) { - return -Math.cos(t * (Math.PI / 2)) + 1; - }, - - easeOutSine: function(t) { - return Math.sin(t * (Math.PI / 2)); - }, - - easeInOutSine: function(t) { - return -0.5 * (Math.cos(Math.PI * t) - 1); - }, - - easeInExpo: function(t) { - return (t === 0) ? 0 : Math.pow(2, 10 * (t - 1)); - }, - - easeOutExpo: function(t) { - return (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1; - }, - - easeInOutExpo: function(t) { - if (t === 0) { - return 0; - } - if (t === 1) { - return 1; - } - if ((t /= 0.5) < 1) { - return 0.5 * Math.pow(2, 10 * (t - 1)); - } - return 0.5 * (-Math.pow(2, -10 * --t) + 2); - }, - - easeInCirc: function(t) { - if (t >= 1) { - return t; - } - return -(Math.sqrt(1 - t * t) - 1); - }, - - easeOutCirc: function(t) { - return Math.sqrt(1 - (t = t - 1) * t); - }, - - easeInOutCirc: function(t) { - if ((t /= 0.5) < 1) { - return -0.5 * (Math.sqrt(1 - t * t) - 1); - } - return 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1); - }, - - easeInElastic: function(t) { - var s = 1.70158; - var p = 0; - var a = 1; - if (t === 0) { - return 0; - } - if (t === 1) { - return 1; - } - if (!p) { - p = 0.3; - } - if (a < 1) { - a = 1; - s = p / 4; - } else { - s = p / (2 * Math.PI) * Math.asin(1 / a); - } - return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p)); - }, - - easeOutElastic: function(t) { - var s = 1.70158; - var p = 0; - var a = 1; - if (t === 0) { - return 0; - } - if (t === 1) { - return 1; - } - if (!p) { - p = 0.3; - } - if (a < 1) { - a = 1; - s = p / 4; - } else { - s = p / (2 * Math.PI) * Math.asin(1 / a); - } - return a * Math.pow(2, -10 * t) * Math.sin((t - s) * (2 * Math.PI) / p) + 1; - }, - - easeInOutElastic: function(t) { - var s = 1.70158; - var p = 0; - var a = 1; - if (t === 0) { - return 0; - } - if ((t /= 0.5) === 2) { - return 1; - } - if (!p) { - p = 0.45; - } - if (a < 1) { - a = 1; - s = p / 4; - } else { - s = p / (2 * Math.PI) * Math.asin(1 / a); - } - if (t < 1) { - return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p)); - } - return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p) * 0.5 + 1; - }, - easeInBack: function(t) { - var s = 1.70158; - return t * t * ((s + 1) * t - s); - }, - - easeOutBack: function(t) { - var s = 1.70158; - return (t = t - 1) * t * ((s + 1) * t + s) + 1; - }, - - easeInOutBack: function(t) { - var s = 1.70158; - if ((t /= 0.5) < 1) { - return 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s)); - } - return 0.5 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2); - }, - - easeInBounce: function(t) { - return 1 - effects.easeOutBounce(1 - t); - }, - - easeOutBounce: function(t) { - if (t < (1 / 2.75)) { - return 7.5625 * t * t; - } - if (t < (2 / 2.75)) { - return 7.5625 * (t -= (1.5 / 2.75)) * t + 0.75; - } - if (t < (2.5 / 2.75)) { - return 7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375; - } - return 7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375; - }, - - easeInOutBounce: function(t) { - if (t < 0.5) { - return effects.easeInBounce(t * 2) * 0.5; - } - return effects.easeOutBounce(t * 2 - 1) * 0.5 + 0.5; - } -}; - -var helpers_easing = { - effects: effects -}; - -// DEPRECATIONS - -/** - * Provided for backward compatibility, use Chart.helpers.easing.effects instead. - * @function Chart.helpers.easingEffects - * @deprecated since version 2.7.0 - * @todo remove at version 3 - * @private - */ -helpers_core.easingEffects = effects; - -var PI = Math.PI; -var RAD_PER_DEG = PI / 180; -var DOUBLE_PI = PI * 2; -var HALF_PI = PI / 2; -var QUARTER_PI = PI / 4; -var TWO_THIRDS_PI = PI * 2 / 3; - -/** - * @namespace Chart.helpers.canvas - */ -var exports$1 = { - /** - * Clears the entire canvas associated to the given `chart`. - * @param {Chart} chart - The chart for which to clear the canvas. - */ - clear: function(chart) { - chart.ctx.clearRect(0, 0, chart.width, chart.height); - }, - - /** - * Creates a "path" for a rectangle with rounded corners at position (x, y) with a - * given size (width, height) and the same `radius` for all corners. - * @param {CanvasRenderingContext2D} ctx - The canvas 2D Context. - * @param {number} x - The x axis of the coordinate for the rectangle starting point. - * @param {number} y - The y axis of the coordinate for the rectangle starting point. - * @param {number} width - The rectangle's width. - * @param {number} height - The rectangle's height. - * @param {number} radius - The rounded amount (in pixels) for the four corners. - * @todo handle `radius` as top-left, top-right, bottom-right, bottom-left array/object? - */ - roundedRect: function(ctx, x, y, width, height, radius) { - if (radius) { - var r = Math.min(radius, height / 2, width / 2); - var left = x + r; - var top = y + r; - var right = x + width - r; - var bottom = y + height - r; - - ctx.moveTo(x, top); - if (left < right && top < bottom) { - ctx.arc(left, top, r, -PI, -HALF_PI); - ctx.arc(right, top, r, -HALF_PI, 0); - ctx.arc(right, bottom, r, 0, HALF_PI); - ctx.arc(left, bottom, r, HALF_PI, PI); - } else if (left < right) { - ctx.moveTo(left, y); - ctx.arc(right, top, r, -HALF_PI, HALF_PI); - ctx.arc(left, top, r, HALF_PI, PI + HALF_PI); - } else if (top < bottom) { - ctx.arc(left, top, r, -PI, 0); - ctx.arc(left, bottom, r, 0, PI); - } else { - ctx.arc(left, top, r, -PI, PI); - } - ctx.closePath(); - ctx.moveTo(x, y); - } else { - ctx.rect(x, y, width, height); - } - }, - - drawPoint: function(ctx, style, radius, x, y, rotation) { - var type, xOffset, yOffset, size, cornerRadius; - var rad = (rotation || 0) * RAD_PER_DEG; - - if (style && typeof style === 'object') { - type = style.toString(); - if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') { - ctx.drawImage(style, x - style.width / 2, y - style.height / 2, style.width, style.height); - return; - } - } - - if (isNaN(radius) || radius <= 0) { - return; - } - - ctx.beginPath(); - - switch (style) { - // Default includes circle - default: - ctx.arc(x, y, radius, 0, DOUBLE_PI); - ctx.closePath(); - break; - case 'triangle': - ctx.moveTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius); - rad += TWO_THIRDS_PI; - ctx.lineTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius); - rad += TWO_THIRDS_PI; - ctx.lineTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius); - ctx.closePath(); - break; - case 'rectRounded': - // NOTE: the rounded rect implementation changed to use `arc` instead of - // `quadraticCurveTo` since it generates better results when rect is - // almost a circle. 0.516 (instead of 0.5) produces results with visually - // closer proportion to the previous impl and it is inscribed in the - // circle with `radius`. For more details, see the following PRs: - // https://github.com/chartjs/Chart.js/issues/5597 - // https://github.com/chartjs/Chart.js/issues/5858 - cornerRadius = radius * 0.516; - size = radius - cornerRadius; - xOffset = Math.cos(rad + QUARTER_PI) * size; - yOffset = Math.sin(rad + QUARTER_PI) * size; - ctx.arc(x - xOffset, y - yOffset, cornerRadius, rad - PI, rad - HALF_PI); - ctx.arc(x + yOffset, y - xOffset, cornerRadius, rad - HALF_PI, rad); - ctx.arc(x + xOffset, y + yOffset, cornerRadius, rad, rad + HALF_PI); - ctx.arc(x - yOffset, y + xOffset, cornerRadius, rad + HALF_PI, rad + PI); - ctx.closePath(); - break; - case 'rect': - if (!rotation) { - size = Math.SQRT1_2 * radius; - ctx.rect(x - size, y - size, 2 * size, 2 * size); - break; - } - rad += QUARTER_PI; - /* falls through */ - case 'rectRot': - xOffset = Math.cos(rad) * radius; - yOffset = Math.sin(rad) * radius; - ctx.moveTo(x - xOffset, y - yOffset); - ctx.lineTo(x + yOffset, y - xOffset); - ctx.lineTo(x + xOffset, y + yOffset); - ctx.lineTo(x - yOffset, y + xOffset); - ctx.closePath(); - break; - case 'crossRot': - rad += QUARTER_PI; - /* falls through */ - case 'cross': - xOffset = Math.cos(rad) * radius; - yOffset = Math.sin(rad) * radius; - ctx.moveTo(x - xOffset, y - yOffset); - ctx.lineTo(x + xOffset, y + yOffset); - ctx.moveTo(x + yOffset, y - xOffset); - ctx.lineTo(x - yOffset, y + xOffset); - break; - case 'star': - xOffset = Math.cos(rad) * radius; - yOffset = Math.sin(rad) * radius; - ctx.moveTo(x - xOffset, y - yOffset); - ctx.lineTo(x + xOffset, y + yOffset); - ctx.moveTo(x + yOffset, y - xOffset); - ctx.lineTo(x - yOffset, y + xOffset); - rad += QUARTER_PI; - xOffset = Math.cos(rad) * radius; - yOffset = Math.sin(rad) * radius; - ctx.moveTo(x - xOffset, y - yOffset); - ctx.lineTo(x + xOffset, y + yOffset); - ctx.moveTo(x + yOffset, y - xOffset); - ctx.lineTo(x - yOffset, y + xOffset); - break; - case 'line': - xOffset = Math.cos(rad) * radius; - yOffset = Math.sin(rad) * radius; - ctx.moveTo(x - xOffset, y - yOffset); - ctx.lineTo(x + xOffset, y + yOffset); - break; - case 'dash': - ctx.moveTo(x, y); - ctx.lineTo(x + Math.cos(rad) * radius, y + Math.sin(rad) * radius); - break; - } - - ctx.fill(); - ctx.stroke(); - }, - - /** - * Returns true if the point is inside the rectangle - * @param {object} point - The point to test - * @param {object} area - The rectangle - * @returns {boolean} - * @private - */ - _isPointInArea: function(point, area) { - var epsilon = 1e-6; // 1e-6 is margin in pixels for accumulated error. - - return point.x > area.left - epsilon && point.x < area.right + epsilon && - point.y > area.top - epsilon && point.y < area.bottom + epsilon; - }, - - clipArea: function(ctx, area) { - ctx.save(); - ctx.beginPath(); - ctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top); - ctx.clip(); - }, - - unclipArea: function(ctx) { - ctx.restore(); - }, - - lineTo: function(ctx, previous, target, flip) { - var stepped = target.steppedLine; - if (stepped) { - if (stepped === 'middle') { - var midpoint = (previous.x + target.x) / 2.0; - ctx.lineTo(midpoint, flip ? target.y : previous.y); - ctx.lineTo(midpoint, flip ? previous.y : target.y); - } else if ((stepped === 'after' && !flip) || (stepped !== 'after' && flip)) { - ctx.lineTo(previous.x, target.y); - } else { - ctx.lineTo(target.x, previous.y); - } - ctx.lineTo(target.x, target.y); - return; - } - - if (!target.tension) { - ctx.lineTo(target.x, target.y); - return; - } - - ctx.bezierCurveTo( - flip ? previous.controlPointPreviousX : previous.controlPointNextX, - flip ? previous.controlPointPreviousY : previous.controlPointNextY, - flip ? target.controlPointNextX : target.controlPointPreviousX, - flip ? target.controlPointNextY : target.controlPointPreviousY, - target.x, - target.y); - } -}; - -var helpers_canvas = exports$1; - -// DEPRECATIONS - -/** - * Provided for backward compatibility, use Chart.helpers.canvas.clear instead. - * @namespace Chart.helpers.clear - * @deprecated since version 2.7.0 - * @todo remove at version 3 - * @private - */ -helpers_core.clear = exports$1.clear; - -/** - * Provided for backward compatibility, use Chart.helpers.canvas.roundedRect instead. - * @namespace Chart.helpers.drawRoundedRectangle - * @deprecated since version 2.7.0 - * @todo remove at version 3 - * @private - */ -helpers_core.drawRoundedRectangle = function(ctx) { - ctx.beginPath(); - exports$1.roundedRect.apply(exports$1, arguments); -}; - -var defaults = { - /** - * @private - */ - _set: function(scope, values) { - return helpers_core.merge(this[scope] || (this[scope] = {}), values); - } -}; - -defaults._set('global', { - defaultColor: 'rgba(0,0,0,0.1)', - defaultFontColor: '#666', - defaultFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif", - defaultFontSize: 12, - defaultFontStyle: 'normal', - defaultLineHeight: 1.2, - showLines: true -}); - -var core_defaults = defaults; - -var valueOrDefault = helpers_core.valueOrDefault; - -/** - * Converts the given font object into a CSS font string. - * @param {object} font - A font object. - * @return {string} The CSS font string. See https://developer.mozilla.org/en-US/docs/Web/CSS/font - * @private - */ -function toFontString(font) { - if (!font || helpers_core.isNullOrUndef(font.size) || helpers_core.isNullOrUndef(font.family)) { - return null; - } - - return (font.style ? font.style + ' ' : '') - + (font.weight ? font.weight + ' ' : '') - + font.size + 'px ' - + font.family; -} - -/** - * @alias Chart.helpers.options - * @namespace - */ -var helpers_options = { - /** - * Converts the given line height `value` in pixels for a specific font `size`. - * @param {number|string} value - The lineHeight to parse (eg. 1.6, '14px', '75%', '1.6em'). - * @param {number} size - The font size (in pixels) used to resolve relative `value`. - * @returns {number} The effective line height in pixels (size * 1.2 if value is invalid). - * @see https://developer.mozilla.org/en-US/docs/Web/CSS/line-height - * @since 2.7.0 - */ - toLineHeight: function(value, size) { - var matches = ('' + value).match(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/); - if (!matches || matches[1] === 'normal') { - return size * 1.2; - } - - value = +matches[2]; - - switch (matches[3]) { - case 'px': - return value; - case '%': - value /= 100; - break; - default: - break; - } - - return size * value; - }, - - /** - * Converts the given value into a padding object with pre-computed width/height. - * @param {number|object} value - If a number, set the value to all TRBL component, - * else, if and object, use defined properties and sets undefined ones to 0. - * @returns {object} The padding values (top, right, bottom, left, width, height) - * @since 2.7.0 - */ - toPadding: function(value) { - var t, r, b, l; - - if (helpers_core.isObject(value)) { - t = +value.top || 0; - r = +value.right || 0; - b = +value.bottom || 0; - l = +value.left || 0; - } else { - t = r = b = l = +value || 0; - } - - return { - top: t, - right: r, - bottom: b, - left: l, - height: t + b, - width: l + r - }; - }, - - /** - * Parses font options and returns the font object. - * @param {object} options - A object that contains font options to be parsed. - * @return {object} The font object. - * @todo Support font.* options and renamed to toFont(). - * @private - */ - _parseFont: function(options) { - var globalDefaults = core_defaults.global; - var size = valueOrDefault(options.fontSize, globalDefaults.defaultFontSize); - var font = { - family: valueOrDefault(options.fontFamily, globalDefaults.defaultFontFamily), - lineHeight: helpers_core.options.toLineHeight(valueOrDefault(options.lineHeight, globalDefaults.defaultLineHeight), size), - size: size, - style: valueOrDefault(options.fontStyle, globalDefaults.defaultFontStyle), - weight: null, - string: '' - }; - - font.string = toFontString(font); - return font; - }, - - /** - * Evaluates the given `inputs` sequentially and returns the first defined value. - * @param {Array} inputs - An array of values, falling back to the last value. - * @param {object} [context] - If defined and the current value is a function, the value - * is called with `context` as first argument and the result becomes the new input. - * @param {number} [index] - If defined and the current value is an array, the value - * at `index` become the new input. - * @since 2.7.0 - */ - resolve: function(inputs, context, index) { - var i, ilen, value; - - for (i = 0, ilen = inputs.length; i < ilen; ++i) { - value = inputs[i]; - if (value === undefined) { - continue; - } - if (context !== undefined && typeof value === 'function') { - value = value(context); - } - if (index !== undefined && helpers_core.isArray(value)) { - value = value[index]; - } - if (value !== undefined) { - return value; - } - } - } -}; - -var helpers$1 = helpers_core; -var easing = helpers_easing; -var canvas = helpers_canvas; -var options = helpers_options; -helpers$1.easing = easing; -helpers$1.canvas = canvas; -helpers$1.options = options; - -function interpolate(start, view, model, ease) { - var keys = Object.keys(model); - var i, ilen, key, actual, origin, target, type, c0, c1; - - for (i = 0, ilen = keys.length; i < ilen; ++i) { - key = keys[i]; - - target = model[key]; - - // if a value is added to the model after pivot() has been called, the view - // doesn't contain it, so let's initialize the view to the target value. - if (!view.hasOwnProperty(key)) { - view[key] = target; - } - - actual = view[key]; - - if (actual === target || key[0] === '_') { - continue; - } - - if (!start.hasOwnProperty(key)) { - start[key] = actual; - } - - origin = start[key]; - - type = typeof target; - - if (type === typeof origin) { - if (type === 'string') { - c0 = chartjsColor(origin); - if (c0.valid) { - c1 = chartjsColor(target); - if (c1.valid) { - view[key] = c1.mix(c0, ease).rgbString(); - continue; - } - } - } else if (helpers$1.isFinite(origin) && helpers$1.isFinite(target)) { - view[key] = origin + (target - origin) * ease; - continue; - } - } - - view[key] = target; - } -} - -var Element = function(configuration) { - helpers$1.extend(this, configuration); - this.initialize.apply(this, arguments); -}; - -helpers$1.extend(Element.prototype, { - - initialize: function() { - this.hidden = false; - }, - - pivot: function() { - var me = this; - if (!me._view) { - me._view = helpers$1.clone(me._model); - } - me._start = {}; - return me; - }, - - transition: function(ease) { - var me = this; - var model = me._model; - var start = me._start; - var view = me._view; - - // No animation -> No Transition - if (!model || ease === 1) { - me._view = model; - me._start = null; - return me; - } - - if (!view) { - view = me._view = {}; - } - - if (!start) { - start = me._start = {}; - } - - interpolate(start, view, model, ease); - - return me; - }, - - tooltipPosition: function() { - return { - x: this._model.x, - y: this._model.y - }; - }, - - hasValue: function() { - return helpers$1.isNumber(this._model.x) && helpers$1.isNumber(this._model.y); - } -}); - -Element.extend = helpers$1.inherits; - -var core_element = Element; - -var exports$2 = core_element.extend({ - chart: null, // the animation associated chart instance - currentStep: 0, // the current animation step - numSteps: 60, // default number of steps - easing: '', // the easing to use for this animation - render: null, // render function used by the animation service - - onAnimationProgress: null, // user specified callback to fire on each step of the animation - onAnimationComplete: null, // user specified callback to fire when the animation finishes -}); - -var core_animation = exports$2; - -// DEPRECATIONS - -/** - * Provided for backward compatibility, use Chart.Animation instead - * @prop Chart.Animation#animationObject - * @deprecated since version 2.6.0 - * @todo remove at version 3 - */ -Object.defineProperty(exports$2.prototype, 'animationObject', { - get: function() { - return this; - } -}); - -/** - * Provided for backward compatibility, use Chart.Animation#chart instead - * @prop Chart.Animation#chartInstance - * @deprecated since version 2.6.0 - * @todo remove at version 3 - */ -Object.defineProperty(exports$2.prototype, 'chartInstance', { - get: function() { - return this.chart; - }, - set: function(value) { - this.chart = value; - } -}); - -core_defaults._set('global', { - animation: { - duration: 1000, - easing: 'easeOutQuart', - onProgress: helpers$1.noop, - onComplete: helpers$1.noop - } -}); - -var core_animations = { - animations: [], - request: null, - - /** - * @param {Chart} chart - The chart to animate. - * @param {Chart.Animation} animation - The animation that we will animate. - * @param {number} duration - The animation duration in ms. - * @param {boolean} lazy - if true, the chart is not marked as animating to enable more responsive interactions - */ - addAnimation: function(chart, animation, duration, lazy) { - var animations = this.animations; - var i, ilen; - - animation.chart = chart; - animation.startTime = Date.now(); - animation.duration = duration; - - if (!lazy) { - chart.animating = true; - } - - for (i = 0, ilen = animations.length; i < ilen; ++i) { - if (animations[i].chart === chart) { - animations[i] = animation; - return; - } - } - - animations.push(animation); - - // If there are no animations queued, manually kickstart a digest, for lack of a better word - if (animations.length === 1) { - this.requestAnimationFrame(); - } - }, - - cancelAnimation: function(chart) { - var index = helpers$1.findIndex(this.animations, function(animation) { - return animation.chart === chart; - }); - - if (index !== -1) { - this.animations.splice(index, 1); - chart.animating = false; - } - }, - - requestAnimationFrame: function() { - var me = this; - if (me.request === null) { - // Skip animation frame requests until the active one is executed. - // This can happen when processing mouse events, e.g. 'mousemove' - // and 'mouseout' events will trigger multiple renders. - me.request = helpers$1.requestAnimFrame.call(window, function() { - me.request = null; - me.startDigest(); - }); - } - }, - - /** - * @private - */ - startDigest: function() { - var me = this; - - me.advance(); - - // Do we have more stuff to animate? - if (me.animations.length > 0) { - me.requestAnimationFrame(); - } - }, - - /** - * @private - */ - advance: function() { - var animations = this.animations; - var animation, chart, numSteps, nextStep; - var i = 0; - - // 1 animation per chart, so we are looping charts here - while (i < animations.length) { - animation = animations[i]; - chart = animation.chart; - numSteps = animation.numSteps; - - // Make sure that currentStep starts at 1 - // https://github.com/chartjs/Chart.js/issues/6104 - nextStep = Math.floor((Date.now() - animation.startTime) / animation.duration * numSteps) + 1; - animation.currentStep = Math.min(nextStep, numSteps); - - helpers$1.callback(animation.render, [chart, animation], chart); - helpers$1.callback(animation.onAnimationProgress, [animation], chart); - - if (animation.currentStep >= numSteps) { - helpers$1.callback(animation.onAnimationComplete, [animation], chart); - chart.animating = false; - animations.splice(i, 1); - } else { - ++i; - } - } - } -}; - -var resolve = helpers$1.options.resolve; - -var arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift']; - -/** - * Hooks the array methods that add or remove values ('push', pop', 'shift', 'splice', - * 'unshift') and notify the listener AFTER the array has been altered. Listeners are - * called on the 'onData*' callbacks (e.g. onDataPush, etc.) with same arguments. - */ -function listenArrayEvents(array, listener) { - if (array._chartjs) { - array._chartjs.listeners.push(listener); - return; - } - - Object.defineProperty(array, '_chartjs', { - configurable: true, - enumerable: false, - value: { - listeners: [listener] - } - }); - - arrayEvents.forEach(function(key) { - var method = 'onData' + key.charAt(0).toUpperCase() + key.slice(1); - var base = array[key]; - - Object.defineProperty(array, key, { - configurable: true, - enumerable: false, - value: function() { - var args = Array.prototype.slice.call(arguments); - var res = base.apply(this, args); - - helpers$1.each(array._chartjs.listeners, function(object) { - if (typeof object[method] === 'function') { - object[method].apply(object, args); - } - }); - - return res; - } - }); - }); -} - -/** - * Removes the given array event listener and cleanup extra attached properties (such as - * the _chartjs stub and overridden methods) if array doesn't have any more listeners. - */ -function unlistenArrayEvents(array, listener) { - var stub = array._chartjs; - if (!stub) { - return; - } - - var listeners = stub.listeners; - var index = listeners.indexOf(listener); - if (index !== -1) { - listeners.splice(index, 1); - } - - if (listeners.length > 0) { - return; - } - - arrayEvents.forEach(function(key) { - delete array[key]; - }); - - delete array._chartjs; -} - -// Base class for all dataset controllers (line, bar, etc) -var DatasetController = function(chart, datasetIndex) { - this.initialize(chart, datasetIndex); -}; - -helpers$1.extend(DatasetController.prototype, { - - /** - * Element type used to generate a meta dataset (e.g. Chart.element.Line). - * @type {Chart.core.element} - */ - datasetElementType: null, - - /** - * Element type used to generate a meta data (e.g. Chart.element.Point). - * @type {Chart.core.element} - */ - dataElementType: null, - - initialize: function(chart, datasetIndex) { - var me = this; - me.chart = chart; - me.index = datasetIndex; - me.linkScales(); - me.addElements(); - }, - - updateIndex: function(datasetIndex) { - this.index = datasetIndex; - }, - - linkScales: function() { - var me = this; - var meta = me.getMeta(); - var dataset = me.getDataset(); - - if (meta.xAxisID === null || !(meta.xAxisID in me.chart.scales)) { - meta.xAxisID = dataset.xAxisID || me.chart.options.scales.xAxes[0].id; - } - if (meta.yAxisID === null || !(meta.yAxisID in me.chart.scales)) { - meta.yAxisID = dataset.yAxisID || me.chart.options.scales.yAxes[0].id; - } - }, - - getDataset: function() { - return this.chart.data.datasets[this.index]; - }, - - getMeta: function() { - return this.chart.getDatasetMeta(this.index); - }, - - getScaleForId: function(scaleID) { - return this.chart.scales[scaleID]; - }, - - /** - * @private - */ - _getValueScaleId: function() { - return this.getMeta().yAxisID; - }, - - /** - * @private - */ - _getIndexScaleId: function() { - return this.getMeta().xAxisID; - }, - - /** - * @private - */ - _getValueScale: function() { - return this.getScaleForId(this._getValueScaleId()); - }, - - /** - * @private - */ - _getIndexScale: function() { - return this.getScaleForId(this._getIndexScaleId()); - }, - - reset: function() { - this.update(true); - }, - - /** - * @private - */ - destroy: function() { - if (this._data) { - unlistenArrayEvents(this._data, this); - } - }, - - createMetaDataset: function() { - var me = this; - var type = me.datasetElementType; - return type && new type({ - _chart: me.chart, - _datasetIndex: me.index - }); - }, - - createMetaData: function(index) { - var me = this; - var type = me.dataElementType; - return type && new type({ - _chart: me.chart, - _datasetIndex: me.index, - _index: index - }); - }, - - addElements: function() { - var me = this; - var meta = me.getMeta(); - var data = me.getDataset().data || []; - var metaData = meta.data; - var i, ilen; - - for (i = 0, ilen = data.length; i < ilen; ++i) { - metaData[i] = metaData[i] || me.createMetaData(i); - } - - meta.dataset = meta.dataset || me.createMetaDataset(); - }, - - addElementAndReset: function(index) { - var element = this.createMetaData(index); - this.getMeta().data.splice(index, 0, element); - this.updateElement(element, index, true); - }, - - buildOrUpdateElements: function() { - var me = this; - var dataset = me.getDataset(); - var data = dataset.data || (dataset.data = []); - - // In order to correctly handle data addition/deletion animation (an thus simulate - // real-time charts), we need to monitor these data modifications and synchronize - // the internal meta data accordingly. - if (me._data !== data) { - if (me._data) { - // This case happens when the user replaced the data array instance. - unlistenArrayEvents(me._data, me); - } - - if (data && Object.isExtensible(data)) { - listenArrayEvents(data, me); - } - me._data = data; - } - - // Re-sync meta data in case the user replaced the data array or if we missed - // any updates and so make sure that we handle number of datapoints changing. - me.resyncElements(); - }, - - update: helpers$1.noop, - - transition: function(easingValue) { - var meta = this.getMeta(); - var elements = meta.data || []; - var ilen = elements.length; - var i = 0; - - for (; i < ilen; ++i) { - elements[i].transition(easingValue); - } - - if (meta.dataset) { - meta.dataset.transition(easingValue); - } - }, - - draw: function() { - var meta = this.getMeta(); - var elements = meta.data || []; - var ilen = elements.length; - var i = 0; - - if (meta.dataset) { - meta.dataset.draw(); - } - - for (; i < ilen; ++i) { - elements[i].draw(); - } - }, - - removeHoverStyle: function(element) { - helpers$1.merge(element._model, element.$previousStyle || {}); - delete element.$previousStyle; - }, - - setHoverStyle: function(element) { - var dataset = this.chart.data.datasets[element._datasetIndex]; - var index = element._index; - var custom = element.custom || {}; - var model = element._model; - var getHoverColor = helpers$1.getHoverColor; - - element.$previousStyle = { - backgroundColor: model.backgroundColor, - borderColor: model.borderColor, - borderWidth: model.borderWidth - }; - - model.backgroundColor = resolve([custom.hoverBackgroundColor, dataset.hoverBackgroundColor, getHoverColor(model.backgroundColor)], undefined, index); - model.borderColor = resolve([custom.hoverBorderColor, dataset.hoverBorderColor, getHoverColor(model.borderColor)], undefined, index); - model.borderWidth = resolve([custom.hoverBorderWidth, dataset.hoverBorderWidth, model.borderWidth], undefined, index); - }, - - /** - * @private - */ - resyncElements: function() { - var me = this; - var meta = me.getMeta(); - var data = me.getDataset().data; - var numMeta = meta.data.length; - var numData = data.length; - - if (numData < numMeta) { - meta.data.splice(numData, numMeta - numData); - } else if (numData > numMeta) { - me.insertElements(numMeta, numData - numMeta); - } - }, - - /** - * @private - */ - insertElements: function(start, count) { - for (var i = 0; i < count; ++i) { - this.addElementAndReset(start + i); - } - }, - - /** - * @private - */ - onDataPush: function() { - var count = arguments.length; - this.insertElements(this.getDataset().data.length - count, count); - }, - - /** - * @private - */ - onDataPop: function() { - this.getMeta().data.pop(); - }, - - /** - * @private - */ - onDataShift: function() { - this.getMeta().data.shift(); - }, - - /** - * @private - */ - onDataSplice: function(start, count) { - this.getMeta().data.splice(start, count); - this.insertElements(start, arguments.length - 2); - }, - - /** - * @private - */ - onDataUnshift: function() { - this.insertElements(0, arguments.length); - } -}); - -DatasetController.extend = helpers$1.inherits; - -var core_datasetController = DatasetController; - -core_defaults._set('global', { - elements: { - arc: { - backgroundColor: core_defaults.global.defaultColor, - borderColor: '#fff', - borderWidth: 2, - borderAlign: 'center' - } - } -}); - -var element_arc = core_element.extend({ - inLabelRange: function(mouseX) { - var vm = this._view; - - if (vm) { - return (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hoverRadius, 2)); - } - return false; - }, - - inRange: function(chartX, chartY) { - var vm = this._view; - - if (vm) { - var pointRelativePosition = helpers$1.getAngleFromPoint(vm, {x: chartX, y: chartY}); - var angle = pointRelativePosition.angle; - var distance = pointRelativePosition.distance; - - // Sanitise angle range - var startAngle = vm.startAngle; - var endAngle = vm.endAngle; - while (endAngle < startAngle) { - endAngle += 2.0 * Math.PI; - } - while (angle > endAngle) { - angle -= 2.0 * Math.PI; - } - while (angle < startAngle) { - angle += 2.0 * Math.PI; - } - - // Check if within the range of the open/close angle - var betweenAngles = (angle >= startAngle && angle <= endAngle); - var withinRadius = (distance >= vm.innerRadius && distance <= vm.outerRadius); - - return (betweenAngles && withinRadius); - } - return false; - }, - - getCenterPoint: function() { - var vm = this._view; - var halfAngle = (vm.startAngle + vm.endAngle) / 2; - var halfRadius = (vm.innerRadius + vm.outerRadius) / 2; - return { - x: vm.x + Math.cos(halfAngle) * halfRadius, - y: vm.y + Math.sin(halfAngle) * halfRadius - }; - }, - - getArea: function() { - var vm = this._view; - return Math.PI * ((vm.endAngle - vm.startAngle) / (2 * Math.PI)) * (Math.pow(vm.outerRadius, 2) - Math.pow(vm.innerRadius, 2)); - }, - - tooltipPosition: function() { - var vm = this._view; - var centreAngle = vm.startAngle + ((vm.endAngle - vm.startAngle) / 2); - var rangeFromCentre = (vm.outerRadius - vm.innerRadius) / 2 + vm.innerRadius; - - return { - x: vm.x + (Math.cos(centreAngle) * rangeFromCentre), - y: vm.y + (Math.sin(centreAngle) * rangeFromCentre) - }; - }, - - draw: function() { - var ctx = this._chart.ctx; - var vm = this._view; - var sA = vm.startAngle; - var eA = vm.endAngle; - var pixelMargin = (vm.borderAlign === 'inner') ? 0.33 : 0; - var angleMargin; - - ctx.save(); - - ctx.beginPath(); - ctx.arc(vm.x, vm.y, Math.max(vm.outerRadius - pixelMargin, 0), sA, eA); - ctx.arc(vm.x, vm.y, vm.innerRadius, eA, sA, true); - ctx.closePath(); - - ctx.fillStyle = vm.backgroundColor; - ctx.fill(); - - if (vm.borderWidth) { - if (vm.borderAlign === 'inner') { - // Draw an inner border by cliping the arc and drawing a double-width border - // Enlarge the clipping arc by 0.33 pixels to eliminate glitches between borders - ctx.beginPath(); - angleMargin = pixelMargin / vm.outerRadius; - ctx.arc(vm.x, vm.y, vm.outerRadius, sA - angleMargin, eA + angleMargin); - if (vm.innerRadius > pixelMargin) { - angleMargin = pixelMargin / vm.innerRadius; - ctx.arc(vm.x, vm.y, vm.innerRadius - pixelMargin, eA + angleMargin, sA - angleMargin, true); - } else { - ctx.arc(vm.x, vm.y, pixelMargin, eA + Math.PI / 2, sA - Math.PI / 2); - } - ctx.closePath(); - ctx.clip(); - - ctx.beginPath(); - ctx.arc(vm.x, vm.y, vm.outerRadius, sA, eA); - ctx.arc(vm.x, vm.y, vm.innerRadius, eA, sA, true); - ctx.closePath(); - - ctx.lineWidth = vm.borderWidth * 2; - ctx.lineJoin = 'round'; - } else { - ctx.lineWidth = vm.borderWidth; - ctx.lineJoin = 'bevel'; - } - - ctx.strokeStyle = vm.borderColor; - ctx.stroke(); - } - - ctx.restore(); - } -}); - -var valueOrDefault$1 = helpers$1.valueOrDefault; - -var defaultColor = core_defaults.global.defaultColor; - -core_defaults._set('global', { - elements: { - line: { - tension: 0.4, - backgroundColor: defaultColor, - borderWidth: 3, - borderColor: defaultColor, - borderCapStyle: 'butt', - borderDash: [], - borderDashOffset: 0.0, - borderJoinStyle: 'miter', - capBezierPoints: true, - fill: true, // do we fill in the area between the line and its base axis - } - } -}); - -var element_line = core_element.extend({ - draw: function() { - var me = this; - var vm = me._view; - var ctx = me._chart.ctx; - var spanGaps = vm.spanGaps; - var points = me._children.slice(); // clone array - var globalDefaults = core_defaults.global; - var globalOptionLineElements = globalDefaults.elements.line; - var lastDrawnIndex = -1; - var index, current, previous, currentVM; - - // If we are looping, adding the first point again - if (me._loop && points.length) { - points.push(points[0]); - } - - ctx.save(); - - // Stroke Line Options - ctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle; - - // IE 9 and 10 do not support line dash - if (ctx.setLineDash) { - ctx.setLineDash(vm.borderDash || globalOptionLineElements.borderDash); - } - - ctx.lineDashOffset = valueOrDefault$1(vm.borderDashOffset, globalOptionLineElements.borderDashOffset); - ctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle; - ctx.lineWidth = valueOrDefault$1(vm.borderWidth, globalOptionLineElements.borderWidth); - ctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor; - - // Stroke Line - ctx.beginPath(); - lastDrawnIndex = -1; - - for (index = 0; index < points.length; ++index) { - current = points[index]; - previous = helpers$1.previousItem(points, index); - currentVM = current._view; - - // First point moves to it's starting position no matter what - if (index === 0) { - if (!currentVM.skip) { - ctx.moveTo(currentVM.x, currentVM.y); - lastDrawnIndex = index; - } - } else { - previous = lastDrawnIndex === -1 ? previous : points[lastDrawnIndex]; - - if (!currentVM.skip) { - if ((lastDrawnIndex !== (index - 1) && !spanGaps) || lastDrawnIndex === -1) { - // There was a gap and this is the first point after the gap - ctx.moveTo(currentVM.x, currentVM.y); - } else { - // Line to next point - helpers$1.canvas.lineTo(ctx, previous._view, current._view); - } - lastDrawnIndex = index; - } - } - } - - ctx.stroke(); - ctx.restore(); - } -}); - -var valueOrDefault$2 = helpers$1.valueOrDefault; - -var defaultColor$1 = core_defaults.global.defaultColor; - -core_defaults._set('global', { - elements: { - point: { - radius: 3, - pointStyle: 'circle', - backgroundColor: defaultColor$1, - borderColor: defaultColor$1, - borderWidth: 1, - // Hover - hitRadius: 1, - hoverRadius: 4, - hoverBorderWidth: 1 - } - } -}); - -function xRange(mouseX) { - var vm = this._view; - return vm ? (Math.abs(mouseX - vm.x) < vm.radius + vm.hitRadius) : false; -} - -function yRange(mouseY) { - var vm = this._view; - return vm ? (Math.abs(mouseY - vm.y) < vm.radius + vm.hitRadius) : false; -} - -var element_point = core_element.extend({ - inRange: function(mouseX, mouseY) { - var vm = this._view; - return vm ? ((Math.pow(mouseX - vm.x, 2) + Math.pow(mouseY - vm.y, 2)) < Math.pow(vm.hitRadius + vm.radius, 2)) : false; - }, - - inLabelRange: xRange, - inXRange: xRange, - inYRange: yRange, - - getCenterPoint: function() { - var vm = this._view; - return { - x: vm.x, - y: vm.y - }; - }, - - getArea: function() { - return Math.PI * Math.pow(this._view.radius, 2); - }, - - tooltipPosition: function() { - var vm = this._view; - return { - x: vm.x, - y: vm.y, - padding: vm.radius + vm.borderWidth - }; - }, - - draw: function(chartArea) { - var vm = this._view; - var ctx = this._chart.ctx; - var pointStyle = vm.pointStyle; - var rotation = vm.rotation; - var radius = vm.radius; - var x = vm.x; - var y = vm.y; - var globalDefaults = core_defaults.global; - var defaultColor = globalDefaults.defaultColor; // eslint-disable-line no-shadow - - if (vm.skip) { - return; - } - - // Clipping for Points. - if (chartArea === undefined || helpers$1.canvas._isPointInArea(vm, chartArea)) { - ctx.strokeStyle = vm.borderColor || defaultColor; - ctx.lineWidth = valueOrDefault$2(vm.borderWidth, globalDefaults.elements.point.borderWidth); - ctx.fillStyle = vm.backgroundColor || defaultColor; - helpers$1.canvas.drawPoint(ctx, pointStyle, radius, x, y, rotation); - } - } -}); - -var defaultColor$2 = core_defaults.global.defaultColor; - -core_defaults._set('global', { - elements: { - rectangle: { - backgroundColor: defaultColor$2, - borderColor: defaultColor$2, - borderSkipped: 'bottom', - borderWidth: 0 - } - } -}); - -function isVertical(vm) { - return vm && vm.width !== undefined; -} - -/** - * Helper function to get the bounds of the bar regardless of the orientation - * @param bar {Chart.Element.Rectangle} the bar - * @return {Bounds} bounds of the bar - * @private - */ -function getBarBounds(vm) { - var x1, x2, y1, y2, half; - - if (isVertical(vm)) { - half = vm.width / 2; - x1 = vm.x - half; - x2 = vm.x + half; - y1 = Math.min(vm.y, vm.base); - y2 = Math.max(vm.y, vm.base); - } else { - half = vm.height / 2; - x1 = Math.min(vm.x, vm.base); - x2 = Math.max(vm.x, vm.base); - y1 = vm.y - half; - y2 = vm.y + half; - } - - return { - left: x1, - top: y1, - right: x2, - bottom: y2 - }; -} - -function swap(orig, v1, v2) { - return orig === v1 ? v2 : orig === v2 ? v1 : orig; -} - -function parseBorderSkipped(vm) { - var edge = vm.borderSkipped; - var res = {}; - - if (!edge) { - return res; - } - - if (vm.horizontal) { - if (vm.base > vm.x) { - edge = swap(edge, 'left', 'right'); - } - } else if (vm.base < vm.y) { - edge = swap(edge, 'bottom', 'top'); - } - - res[edge] = true; - return res; -} - -function parseBorderWidth(vm, maxW, maxH) { - var value = vm.borderWidth; - var skip = parseBorderSkipped(vm); - var t, r, b, l; - - if (helpers$1.isObject(value)) { - t = +value.top || 0; - r = +value.right || 0; - b = +value.bottom || 0; - l = +value.left || 0; - } else { - t = r = b = l = +value || 0; - } - - return { - t: skip.top || (t < 0) ? 0 : t > maxH ? maxH : t, - r: skip.right || (r < 0) ? 0 : r > maxW ? maxW : r, - b: skip.bottom || (b < 0) ? 0 : b > maxH ? maxH : b, - l: skip.left || (l < 0) ? 0 : l > maxW ? maxW : l - }; -} - -function boundingRects(vm) { - var bounds = getBarBounds(vm); - var width = bounds.right - bounds.left; - var height = bounds.bottom - bounds.top; - var border = parseBorderWidth(vm, width / 2, height / 2); - - return { - outer: { - x: bounds.left, - y: bounds.top, - w: width, - h: height - }, - inner: { - x: bounds.left + border.l, - y: bounds.top + border.t, - w: width - border.l - border.r, - h: height - border.t - border.b - } - }; -} - -function inRange(vm, x, y) { - var skipX = x === null; - var skipY = y === null; - var bounds = !vm || (skipX && skipY) ? false : getBarBounds(vm); - - return bounds - && (skipX || x >= bounds.left && x <= bounds.right) - && (skipY || y >= bounds.top && y <= bounds.bottom); -} - -var element_rectangle = core_element.extend({ - draw: function() { - var ctx = this._chart.ctx; - var vm = this._view; - var rects = boundingRects(vm); - var outer = rects.outer; - var inner = rects.inner; - - ctx.fillStyle = vm.backgroundColor; - ctx.fillRect(outer.x, outer.y, outer.w, outer.h); - - if (outer.w === inner.w && outer.h === inner.h) { - return; - } - - ctx.save(); - ctx.beginPath(); - ctx.rect(outer.x, outer.y, outer.w, outer.h); - ctx.clip(); - ctx.fillStyle = vm.borderColor; - ctx.rect(inner.x, inner.y, inner.w, inner.h); - ctx.fill('evenodd'); - ctx.restore(); - }, - - height: function() { - var vm = this._view; - return vm.base - vm.y; - }, - - inRange: function(mouseX, mouseY) { - return inRange(this._view, mouseX, mouseY); - }, - - inLabelRange: function(mouseX, mouseY) { - var vm = this._view; - return isVertical(vm) - ? inRange(vm, mouseX, null) - : inRange(vm, null, mouseY); - }, - - inXRange: function(mouseX) { - return inRange(this._view, mouseX, null); - }, - - inYRange: function(mouseY) { - return inRange(this._view, null, mouseY); - }, - - getCenterPoint: function() { - var vm = this._view; - var x, y; - if (isVertical(vm)) { - x = vm.x; - y = (vm.y + vm.base) / 2; - } else { - x = (vm.x + vm.base) / 2; - y = vm.y; - } - - return {x: x, y: y}; - }, - - getArea: function() { - var vm = this._view; - - return isVertical(vm) - ? vm.width * Math.abs(vm.y - vm.base) - : vm.height * Math.abs(vm.x - vm.base); - }, - - tooltipPosition: function() { - var vm = this._view; - return { - x: vm.x, - y: vm.y - }; - } -}); - -var elements = {}; -var Arc = element_arc; -var Line = element_line; -var Point = element_point; -var Rectangle = element_rectangle; -elements.Arc = Arc; -elements.Line = Line; -elements.Point = Point; -elements.Rectangle = Rectangle; - -var resolve$1 = helpers$1.options.resolve; - -core_defaults._set('bar', { - hover: { - mode: 'label' - }, - - scales: { - xAxes: [{ - type: 'category', - categoryPercentage: 0.8, - barPercentage: 0.9, - offset: true, - gridLines: { - offsetGridLines: true - } - }], - - yAxes: [{ - type: 'linear' - }] - } -}); - -/** - * Computes the "optimal" sample size to maintain bars equally sized while preventing overlap. - * @private - */ -function computeMinSampleSize(scale, pixels) { - var min = scale.isHorizontal() ? scale.width : scale.height; - var ticks = scale.getTicks(); - var prev, curr, i, ilen; - - for (i = 1, ilen = pixels.length; i < ilen; ++i) { - min = Math.min(min, Math.abs(pixels[i] - pixels[i - 1])); - } - - for (i = 0, ilen = ticks.length; i < ilen; ++i) { - curr = scale.getPixelForTick(i); - min = i > 0 ? Math.min(min, curr - prev) : min; - prev = curr; - } - - return min; -} - -/** - * Computes an "ideal" category based on the absolute bar thickness or, if undefined or null, - * uses the smallest interval (see computeMinSampleSize) that prevents bar overlapping. This - * mode currently always generates bars equally sized (until we introduce scriptable options?). - * @private - */ -function computeFitCategoryTraits(index, ruler, options) { - var thickness = options.barThickness; - var count = ruler.stackCount; - var curr = ruler.pixels[index]; - var size, ratio; - - if (helpers$1.isNullOrUndef(thickness)) { - size = ruler.min * options.categoryPercentage; - ratio = options.barPercentage; - } else { - // When bar thickness is enforced, category and bar percentages are ignored. - // Note(SB): we could add support for relative bar thickness (e.g. barThickness: '50%') - // and deprecate barPercentage since this value is ignored when thickness is absolute. - size = thickness * count; - ratio = 1; - } - - return { - chunk: size / count, - ratio: ratio, - start: curr - (size / 2) - }; -} - -/** - * Computes an "optimal" category that globally arranges bars side by side (no gap when - * percentage options are 1), based on the previous and following categories. This mode - * generates bars with different widths when data are not evenly spaced. - * @private - */ -function computeFlexCategoryTraits(index, ruler, options) { - var pixels = ruler.pixels; - var curr = pixels[index]; - var prev = index > 0 ? pixels[index - 1] : null; - var next = index < pixels.length - 1 ? pixels[index + 1] : null; - var percent = options.categoryPercentage; - var start, size; - - if (prev === null) { - // first data: its size is double based on the next point or, - // if it's also the last data, we use the scale size. - prev = curr - (next === null ? ruler.end - ruler.start : next - curr); - } - - if (next === null) { - // last data: its size is also double based on the previous point. - next = curr + curr - prev; - } - - start = curr - (curr - Math.min(prev, next)) / 2 * percent; - size = Math.abs(next - prev) / 2 * percent; - - return { - chunk: size / ruler.stackCount, - ratio: options.barPercentage, - start: start - }; -} - -var controller_bar = core_datasetController.extend({ - - dataElementType: elements.Rectangle, - - initialize: function() { - var me = this; - var meta; - - core_datasetController.prototype.initialize.apply(me, arguments); - - meta = me.getMeta(); - meta.stack = me.getDataset().stack; - meta.bar = true; - }, - - update: function(reset) { - var me = this; - var rects = me.getMeta().data; - var i, ilen; - - me._ruler = me.getRuler(); - - for (i = 0, ilen = rects.length; i < ilen; ++i) { - me.updateElement(rects[i], i, reset); - } - }, - - updateElement: function(rectangle, index, reset) { - var me = this; - var meta = me.getMeta(); - var dataset = me.getDataset(); - var options = me._resolveElementOptions(rectangle, index); - - rectangle._xScale = me.getScaleForId(meta.xAxisID); - rectangle._yScale = me.getScaleForId(meta.yAxisID); - rectangle._datasetIndex = me.index; - rectangle._index = index; - rectangle._model = { - backgroundColor: options.backgroundColor, - borderColor: options.borderColor, - borderSkipped: options.borderSkipped, - borderWidth: options.borderWidth, - datasetLabel: dataset.label, - label: me.chart.data.labels[index] - }; - - me._updateElementGeometry(rectangle, index, reset); - - rectangle.pivot(); - }, - - /** - * @private - */ - _updateElementGeometry: function(rectangle, index, reset) { - var me = this; - var model = rectangle._model; - var vscale = me._getValueScale(); - var base = vscale.getBasePixel(); - var horizontal = vscale.isHorizontal(); - var ruler = me._ruler || me.getRuler(); - var vpixels = me.calculateBarValuePixels(me.index, index); - var ipixels = me.calculateBarIndexPixels(me.index, index, ruler); - - model.horizontal = horizontal; - model.base = reset ? base : vpixels.base; - model.x = horizontal ? reset ? base : vpixels.head : ipixels.center; - model.y = horizontal ? ipixels.center : reset ? base : vpixels.head; - model.height = horizontal ? ipixels.size : undefined; - model.width = horizontal ? undefined : ipixels.size; - }, - - /** - * Returns the stacks based on groups and bar visibility. - * @param {number} [last] - The dataset index - * @returns {string[]} The list of stack IDs - * @private - */ - _getStacks: function(last) { - var me = this; - var chart = me.chart; - var scale = me._getIndexScale(); - var stacked = scale.options.stacked; - var ilen = last === undefined ? chart.data.datasets.length : last + 1; - var stacks = []; - var i, meta; - - for (i = 0; i < ilen; ++i) { - meta = chart.getDatasetMeta(i); - if (meta.bar && chart.isDatasetVisible(i) && - (stacked === false || - (stacked === true && stacks.indexOf(meta.stack) === -1) || - (stacked === undefined && (meta.stack === undefined || stacks.indexOf(meta.stack) === -1)))) { - stacks.push(meta.stack); - } - } - - return stacks; - }, - - /** - * Returns the effective number of stacks based on groups and bar visibility. - * @private - */ - getStackCount: function() { - return this._getStacks().length; - }, - - /** - * Returns the stack index for the given dataset based on groups and bar visibility. - * @param {number} [datasetIndex] - The dataset index - * @param {string} [name] - The stack name to find - * @returns {number} The stack index - * @private - */ - getStackIndex: function(datasetIndex, name) { - var stacks = this._getStacks(datasetIndex); - var index = (name !== undefined) - ? stacks.indexOf(name) - : -1; // indexOf returns -1 if element is not present - - return (index === -1) - ? stacks.length - 1 - : index; - }, - - /** - * @private - */ - getRuler: function() { - var me = this; - var scale = me._getIndexScale(); - var stackCount = me.getStackCount(); - var datasetIndex = me.index; - var isHorizontal = scale.isHorizontal(); - var start = isHorizontal ? scale.left : scale.top; - var end = start + (isHorizontal ? scale.width : scale.height); - var pixels = []; - var i, ilen, min; - - for (i = 0, ilen = me.getMeta().data.length; i < ilen; ++i) { - pixels.push(scale.getPixelForValue(null, i, datasetIndex)); - } - - min = helpers$1.isNullOrUndef(scale.options.barThickness) - ? computeMinSampleSize(scale, pixels) - : -1; - - return { - min: min, - pixels: pixels, - start: start, - end: end, - stackCount: stackCount, - scale: scale - }; - }, - - /** - * Note: pixel values are not clamped to the scale area. - * @private - */ - calculateBarValuePixels: function(datasetIndex, index) { - var me = this; - var chart = me.chart; - var meta = me.getMeta(); - var scale = me._getValueScale(); - var isHorizontal = scale.isHorizontal(); - var datasets = chart.data.datasets; - var value = +scale.getRightValue(datasets[datasetIndex].data[index]); - var minBarLength = scale.options.minBarLength; - var stacked = scale.options.stacked; - var stack = meta.stack; - var start = 0; - var i, imeta, ivalue, base, head, size; - - if (stacked || (stacked === undefined && stack !== undefined)) { - for (i = 0; i < datasetIndex; ++i) { - imeta = chart.getDatasetMeta(i); - - if (imeta.bar && - imeta.stack === stack && - imeta.controller._getValueScaleId() === scale.id && - chart.isDatasetVisible(i)) { - - ivalue = +scale.getRightValue(datasets[i].data[index]); - if ((value < 0 && ivalue < 0) || (value >= 0 && ivalue > 0)) { - start += ivalue; - } - } - } - } - - base = scale.getPixelForValue(start); - head = scale.getPixelForValue(start + value); - size = head - base; - - if (minBarLength !== undefined && Math.abs(size) < minBarLength) { - size = minBarLength; - if (value >= 0 && !isHorizontal || value < 0 && isHorizontal) { - head = base - minBarLength; - } else { - head = base + minBarLength; - } - } - - return { - size: size, - base: base, - head: head, - center: head + size / 2 - }; - }, - - /** - * @private - */ - calculateBarIndexPixels: function(datasetIndex, index, ruler) { - var me = this; - var options = ruler.scale.options; - var range = options.barThickness === 'flex' - ? computeFlexCategoryTraits(index, ruler, options) - : computeFitCategoryTraits(index, ruler, options); - - var stackIndex = me.getStackIndex(datasetIndex, me.getMeta().stack); - var center = range.start + (range.chunk * stackIndex) + (range.chunk / 2); - var size = Math.min( - helpers$1.valueOrDefault(options.maxBarThickness, Infinity), - range.chunk * range.ratio); - - return { - base: center - size / 2, - head: center + size / 2, - center: center, - size: size - }; - }, - - draw: function() { - var me = this; - var chart = me.chart; - var scale = me._getValueScale(); - var rects = me.getMeta().data; - var dataset = me.getDataset(); - var ilen = rects.length; - var i = 0; - - helpers$1.canvas.clipArea(chart.ctx, chart.chartArea); - - for (; i < ilen; ++i) { - if (!isNaN(scale.getRightValue(dataset.data[i]))) { - rects[i].draw(); - } - } - - helpers$1.canvas.unclipArea(chart.ctx); - }, - - /** - * @private - */ - _resolveElementOptions: function(rectangle, index) { - var me = this; - var chart = me.chart; - var datasets = chart.data.datasets; - var dataset = datasets[me.index]; - var custom = rectangle.custom || {}; - var options = chart.options.elements.rectangle; - var values = {}; - var i, ilen, key; - - // Scriptable options - var context = { - chart: chart, - dataIndex: index, - dataset: dataset, - datasetIndex: me.index - }; - - var keys = [ - 'backgroundColor', - 'borderColor', - 'borderSkipped', - 'borderWidth' - ]; - - for (i = 0, ilen = keys.length; i < ilen; ++i) { - key = keys[i]; - values[key] = resolve$1([ - custom[key], - dataset[key], - options[key] - ], context, index); - } - - return values; - } -}); - -var valueOrDefault$3 = helpers$1.valueOrDefault; -var resolve$2 = helpers$1.options.resolve; - -core_defaults._set('bubble', { - hover: { - mode: 'single' - }, - - scales: { - xAxes: [{ - type: 'linear', // bubble should probably use a linear scale by default - position: 'bottom', - id: 'x-axis-0' // need an ID so datasets can reference the scale - }], - yAxes: [{ - type: 'linear', - position: 'left', - id: 'y-axis-0' - }] - }, - - tooltips: { - callbacks: { - title: function() { - // Title doesn't make sense for scatter since we format the data as a point - return ''; - }, - label: function(item, data) { - var datasetLabel = data.datasets[item.datasetIndex].label || ''; - var dataPoint = data.datasets[item.datasetIndex].data[item.index]; - return datasetLabel + ': (' + item.xLabel + ', ' + item.yLabel + ', ' + dataPoint.r + ')'; - } - } - } -}); - -var controller_bubble = core_datasetController.extend({ - /** - * @protected - */ - dataElementType: elements.Point, - - /** - * @protected - */ - update: function(reset) { - var me = this; - var meta = me.getMeta(); - var points = meta.data; - - // Update Points - helpers$1.each(points, function(point, index) { - me.updateElement(point, index, reset); - }); - }, - - /** - * @protected - */ - updateElement: function(point, index, reset) { - var me = this; - var meta = me.getMeta(); - var custom = point.custom || {}; - var xScale = me.getScaleForId(meta.xAxisID); - var yScale = me.getScaleForId(meta.yAxisID); - var options = me._resolveElementOptions(point, index); - var data = me.getDataset().data[index]; - var dsIndex = me.index; - - var x = reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(typeof data === 'object' ? data : NaN, index, dsIndex); - var y = reset ? yScale.getBasePixel() : yScale.getPixelForValue(data, index, dsIndex); - - point._xScale = xScale; - point._yScale = yScale; - point._options = options; - point._datasetIndex = dsIndex; - point._index = index; - point._model = { - backgroundColor: options.backgroundColor, - borderColor: options.borderColor, - borderWidth: options.borderWidth, - hitRadius: options.hitRadius, - pointStyle: options.pointStyle, - rotation: options.rotation, - radius: reset ? 0 : options.radius, - skip: custom.skip || isNaN(x) || isNaN(y), - x: x, - y: y, - }; - - point.pivot(); - }, - - /** - * @protected - */ - setHoverStyle: function(point) { - var model = point._model; - var options = point._options; - var getHoverColor = helpers$1.getHoverColor; - - point.$previousStyle = { - backgroundColor: model.backgroundColor, - borderColor: model.borderColor, - borderWidth: model.borderWidth, - radius: model.radius - }; - - model.backgroundColor = valueOrDefault$3(options.hoverBackgroundColor, getHoverColor(options.backgroundColor)); - model.borderColor = valueOrDefault$3(options.hoverBorderColor, getHoverColor(options.borderColor)); - model.borderWidth = valueOrDefault$3(options.hoverBorderWidth, options.borderWidth); - model.radius = options.radius + options.hoverRadius; - }, - - /** - * @private - */ - _resolveElementOptions: function(point, index) { - var me = this; - var chart = me.chart; - var datasets = chart.data.datasets; - var dataset = datasets[me.index]; - var custom = point.custom || {}; - var options = chart.options.elements.point; - var data = dataset.data[index]; - var values = {}; - var i, ilen, key; - - // Scriptable options - var context = { - chart: chart, - dataIndex: index, - dataset: dataset, - datasetIndex: me.index - }; - - var keys = [ - 'backgroundColor', - 'borderColor', - 'borderWidth', - 'hoverBackgroundColor', - 'hoverBorderColor', - 'hoverBorderWidth', - 'hoverRadius', - 'hitRadius', - 'pointStyle', - 'rotation' - ]; - - for (i = 0, ilen = keys.length; i < ilen; ++i) { - key = keys[i]; - values[key] = resolve$2([ - custom[key], - dataset[key], - options[key] - ], context, index); - } - - // Custom radius resolution - values.radius = resolve$2([ - custom.radius, - data ? data.r : undefined, - dataset.radius, - options.radius - ], context, index); - - return values; - } -}); - -var resolve$3 = helpers$1.options.resolve; -var valueOrDefault$4 = helpers$1.valueOrDefault; - -core_defaults._set('doughnut', { - animation: { - // Boolean - Whether we animate the rotation of the Doughnut - animateRotate: true, - // Boolean - Whether we animate scaling the Doughnut from the centre - animateScale: false - }, - hover: { - mode: 'single' - }, - legendCallback: function(chart) { - var text = []; - text.push('
    '); - - var data = chart.data; - var datasets = data.datasets; - var labels = data.labels; - - if (datasets.length) { - for (var i = 0; i < datasets[0].data.length; ++i) { - text.push('
  • '); - if (labels[i]) { - text.push(labels[i]); - } - text.push('
  • '); - } - } - - text.push('
'); - return text.join(''); - }, - legend: { - labels: { - generateLabels: function(chart) { - var data = chart.data; - if (data.labels.length && data.datasets.length) { - return data.labels.map(function(label, i) { - var meta = chart.getDatasetMeta(0); - var ds = data.datasets[0]; - var arc = meta.data[i]; - var custom = arc && arc.custom || {}; - var arcOpts = chart.options.elements.arc; - var fill = resolve$3([custom.backgroundColor, ds.backgroundColor, arcOpts.backgroundColor], undefined, i); - var stroke = resolve$3([custom.borderColor, ds.borderColor, arcOpts.borderColor], undefined, i); - var bw = resolve$3([custom.borderWidth, ds.borderWidth, arcOpts.borderWidth], undefined, i); - - return { - text: label, - fillStyle: fill, - strokeStyle: stroke, - lineWidth: bw, - hidden: isNaN(ds.data[i]) || meta.data[i].hidden, - - // Extra data used for toggling the correct item - index: i - }; - }); - } - return []; - } - }, - - onClick: function(e, legendItem) { - var index = legendItem.index; - var chart = this.chart; - var i, ilen, meta; - - for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) { - meta = chart.getDatasetMeta(i); - // toggle visibility of index if exists - if (meta.data[index]) { - meta.data[index].hidden = !meta.data[index].hidden; - } - } - - chart.update(); - } - }, - - // The percentage of the chart that we cut out of the middle. - cutoutPercentage: 50, - - // The rotation of the chart, where the first data arc begins. - rotation: Math.PI * -0.5, - - // The total circumference of the chart. - circumference: Math.PI * 2.0, - - // Need to override these to give a nice default - tooltips: { - callbacks: { - title: function() { - return ''; - }, - label: function(tooltipItem, data) { - var dataLabel = data.labels[tooltipItem.index]; - var value = ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]; - - if (helpers$1.isArray(dataLabel)) { - // show value on first line of multiline label - // need to clone because we are changing the value - dataLabel = dataLabel.slice(); - dataLabel[0] += value; - } else { - dataLabel += value; - } - - return dataLabel; - } - } - } -}); - -var controller_doughnut = core_datasetController.extend({ - - dataElementType: elements.Arc, - - linkScales: helpers$1.noop, - - // Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly - getRingIndex: function(datasetIndex) { - var ringIndex = 0; - - for (var j = 0; j < datasetIndex; ++j) { - if (this.chart.isDatasetVisible(j)) { - ++ringIndex; - } - } - - return ringIndex; - }, - - update: function(reset) { - var me = this; - var chart = me.chart; - var chartArea = chart.chartArea; - var opts = chart.options; - var availableWidth = chartArea.right - chartArea.left; - var availableHeight = chartArea.bottom - chartArea.top; - var minSize = Math.min(availableWidth, availableHeight); - var offset = {x: 0, y: 0}; - var meta = me.getMeta(); - var arcs = meta.data; - var cutoutPercentage = opts.cutoutPercentage; - var circumference = opts.circumference; - var chartWeight = me._getRingWeight(me.index); - var i, ilen; - - // If the chart's circumference isn't a full circle, calculate minSize as a ratio of the width/height of the arc - if (circumference < Math.PI * 2.0) { - var startAngle = opts.rotation % (Math.PI * 2.0); - startAngle += Math.PI * 2.0 * (startAngle >= Math.PI ? -1 : startAngle < -Math.PI ? 1 : 0); - var endAngle = startAngle + circumference; - var start = {x: Math.cos(startAngle), y: Math.sin(startAngle)}; - var end = {x: Math.cos(endAngle), y: Math.sin(endAngle)}; - var contains0 = (startAngle <= 0 && endAngle >= 0) || (startAngle <= Math.PI * 2.0 && Math.PI * 2.0 <= endAngle); - var contains90 = (startAngle <= Math.PI * 0.5 && Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 2.5 && Math.PI * 2.5 <= endAngle); - var contains180 = (startAngle <= -Math.PI && -Math.PI <= endAngle) || (startAngle <= Math.PI && Math.PI <= endAngle); - var contains270 = (startAngle <= -Math.PI * 0.5 && -Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 1.5 && Math.PI * 1.5 <= endAngle); - var cutout = cutoutPercentage / 100.0; - var min = {x: contains180 ? -1 : Math.min(start.x * (start.x < 0 ? 1 : cutout), end.x * (end.x < 0 ? 1 : cutout)), y: contains270 ? -1 : Math.min(start.y * (start.y < 0 ? 1 : cutout), end.y * (end.y < 0 ? 1 : cutout))}; - var max = {x: contains0 ? 1 : Math.max(start.x * (start.x > 0 ? 1 : cutout), end.x * (end.x > 0 ? 1 : cutout)), y: contains90 ? 1 : Math.max(start.y * (start.y > 0 ? 1 : cutout), end.y * (end.y > 0 ? 1 : cutout))}; - var size = {width: (max.x - min.x) * 0.5, height: (max.y - min.y) * 0.5}; - minSize = Math.min(availableWidth / size.width, availableHeight / size.height); - offset = {x: (max.x + min.x) * -0.5, y: (max.y + min.y) * -0.5}; - } - - for (i = 0, ilen = arcs.length; i < ilen; ++i) { - arcs[i]._options = me._resolveElementOptions(arcs[i], i); - } - - chart.borderWidth = me.getMaxBorderWidth(); - chart.outerRadius = Math.max((minSize - chart.borderWidth) / 2, 0); - chart.innerRadius = Math.max(cutoutPercentage ? (chart.outerRadius / 100) * (cutoutPercentage) : 0, 0); - chart.radiusLength = (chart.outerRadius - chart.innerRadius) / (me._getVisibleDatasetWeightTotal() || 1); - chart.offsetX = offset.x * chart.outerRadius; - chart.offsetY = offset.y * chart.outerRadius; - - meta.total = me.calculateTotal(); - - me.outerRadius = chart.outerRadius - chart.radiusLength * me._getRingWeightOffset(me.index); - me.innerRadius = Math.max(me.outerRadius - chart.radiusLength * chartWeight, 0); - - for (i = 0, ilen = arcs.length; i < ilen; ++i) { - me.updateElement(arcs[i], i, reset); - } - }, - - updateElement: function(arc, index, reset) { - var me = this; - var chart = me.chart; - var chartArea = chart.chartArea; - var opts = chart.options; - var animationOpts = opts.animation; - var centerX = (chartArea.left + chartArea.right) / 2; - var centerY = (chartArea.top + chartArea.bottom) / 2; - var startAngle = opts.rotation; // non reset case handled later - var endAngle = opts.rotation; // non reset case handled later - var dataset = me.getDataset(); - var circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(dataset.data[index]) * (opts.circumference / (2.0 * Math.PI)); - var innerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius; - var outerRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius; - var options = arc._options || {}; - - helpers$1.extend(arc, { - // Utility - _datasetIndex: me.index, - _index: index, - - // Desired view properties - _model: { - backgroundColor: options.backgroundColor, - borderColor: options.borderColor, - borderWidth: options.borderWidth, - borderAlign: options.borderAlign, - x: centerX + chart.offsetX, - y: centerY + chart.offsetY, - startAngle: startAngle, - endAngle: endAngle, - circumference: circumference, - outerRadius: outerRadius, - innerRadius: innerRadius, - label: helpers$1.valueAtIndexOrDefault(dataset.label, index, chart.data.labels[index]) - } - }); - - var model = arc._model; - - // Set correct angles if not resetting - if (!reset || !animationOpts.animateRotate) { - if (index === 0) { - model.startAngle = opts.rotation; - } else { - model.startAngle = me.getMeta().data[index - 1]._model.endAngle; - } - - model.endAngle = model.startAngle + model.circumference; - } - - arc.pivot(); - }, - - calculateTotal: function() { - var dataset = this.getDataset(); - var meta = this.getMeta(); - var total = 0; - var value; - - helpers$1.each(meta.data, function(element, index) { - value = dataset.data[index]; - if (!isNaN(value) && !element.hidden) { - total += Math.abs(value); - } - }); - - /* if (total === 0) { - total = NaN; - }*/ - - return total; - }, - - calculateCircumference: function(value) { - var total = this.getMeta().total; - if (total > 0 && !isNaN(value)) { - return (Math.PI * 2.0) * (Math.abs(value) / total); - } - return 0; - }, - - // gets the max border or hover width to properly scale pie charts - getMaxBorderWidth: function(arcs) { - var me = this; - var max = 0; - var chart = me.chart; - var i, ilen, meta, arc, controller, options, borderWidth, hoverWidth; - - if (!arcs) { - // Find the outmost visible dataset - for (i = 0, ilen = chart.data.datasets.length; i < ilen; ++i) { - if (chart.isDatasetVisible(i)) { - meta = chart.getDatasetMeta(i); - arcs = meta.data; - if (i !== me.index) { - controller = meta.controller; - } - break; - } - } - } - - if (!arcs) { - return 0; - } - - for (i = 0, ilen = arcs.length; i < ilen; ++i) { - arc = arcs[i]; - options = controller ? controller._resolveElementOptions(arc, i) : arc._options; - if (options.borderAlign !== 'inner') { - borderWidth = options.borderWidth; - hoverWidth = options.hoverBorderWidth; - - max = borderWidth > max ? borderWidth : max; - max = hoverWidth > max ? hoverWidth : max; - } - } - return max; - }, - - /** - * @protected - */ - setHoverStyle: function(arc) { - var model = arc._model; - var options = arc._options; - var getHoverColor = helpers$1.getHoverColor; - - arc.$previousStyle = { - backgroundColor: model.backgroundColor, - borderColor: model.borderColor, - borderWidth: model.borderWidth, - }; - - model.backgroundColor = valueOrDefault$4(options.hoverBackgroundColor, getHoverColor(options.backgroundColor)); - model.borderColor = valueOrDefault$4(options.hoverBorderColor, getHoverColor(options.borderColor)); - model.borderWidth = valueOrDefault$4(options.hoverBorderWidth, options.borderWidth); - }, - - /** - * @private - */ - _resolveElementOptions: function(arc, index) { - var me = this; - var chart = me.chart; - var dataset = me.getDataset(); - var custom = arc.custom || {}; - var options = chart.options.elements.arc; - var values = {}; - var i, ilen, key; - - // Scriptable options - var context = { - chart: chart, - dataIndex: index, - dataset: dataset, - datasetIndex: me.index - }; - - var keys = [ - 'backgroundColor', - 'borderColor', - 'borderWidth', - 'borderAlign', - 'hoverBackgroundColor', - 'hoverBorderColor', - 'hoverBorderWidth', - ]; - - for (i = 0, ilen = keys.length; i < ilen; ++i) { - key = keys[i]; - values[key] = resolve$3([ - custom[key], - dataset[key], - options[key] - ], context, index); - } - - return values; - }, - - /** - * Get radius length offset of the dataset in relation to the visible datasets weights. This allows determining the inner and outer radius correctly - * @private - */ - _getRingWeightOffset: function(datasetIndex) { - var ringWeightOffset = 0; - - for (var i = 0; i < datasetIndex; ++i) { - if (this.chart.isDatasetVisible(i)) { - ringWeightOffset += this._getRingWeight(i); - } - } - - return ringWeightOffset; - }, - - /** - * @private - */ - _getRingWeight: function(dataSetIndex) { - return Math.max(valueOrDefault$4(this.chart.data.datasets[dataSetIndex].weight, 1), 0); - }, - - /** - * Returns the sum of all visibile data set weights. This value can be 0. - * @private - */ - _getVisibleDatasetWeightTotal: function() { - return this._getRingWeightOffset(this.chart.data.datasets.length); - } -}); - -core_defaults._set('horizontalBar', { - hover: { - mode: 'index', - axis: 'y' - }, - - scales: { - xAxes: [{ - type: 'linear', - position: 'bottom' - }], - - yAxes: [{ - type: 'category', - position: 'left', - categoryPercentage: 0.8, - barPercentage: 0.9, - offset: true, - gridLines: { - offsetGridLines: true - } - }] - }, - - elements: { - rectangle: { - borderSkipped: 'left' - } - }, - - tooltips: { - mode: 'index', - axis: 'y' - } -}); - -var controller_horizontalBar = controller_bar.extend({ - /** - * @private - */ - _getValueScaleId: function() { - return this.getMeta().xAxisID; - }, - - /** - * @private - */ - _getIndexScaleId: function() { - return this.getMeta().yAxisID; - } -}); - -var valueOrDefault$5 = helpers$1.valueOrDefault; -var resolve$4 = helpers$1.options.resolve; -var isPointInArea = helpers$1.canvas._isPointInArea; - -core_defaults._set('line', { - showLines: true, - spanGaps: false, - - hover: { - mode: 'label' - }, - - scales: { - xAxes: [{ - type: 'category', - id: 'x-axis-0' - }], - yAxes: [{ - type: 'linear', - id: 'y-axis-0' - }] - } -}); - -function lineEnabled(dataset, options) { - return valueOrDefault$5(dataset.showLine, options.showLines); -} - -var controller_line = core_datasetController.extend({ - - datasetElementType: elements.Line, - - dataElementType: elements.Point, - - update: function(reset) { - var me = this; - var meta = me.getMeta(); - var line = meta.dataset; - var points = meta.data || []; - var scale = me.getScaleForId(meta.yAxisID); - var dataset = me.getDataset(); - var showLine = lineEnabled(dataset, me.chart.options); - var i, ilen; - - // Update Line - if (showLine) { - // Compatibility: If the properties are defined with only the old name, use those values - if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) { - dataset.lineTension = dataset.tension; - } - - // Utility - line._scale = scale; - line._datasetIndex = me.index; - // Data - line._children = points; - // Model - line._model = me._resolveLineOptions(line); - - line.pivot(); - } - - // Update Points - for (i = 0, ilen = points.length; i < ilen; ++i) { - me.updateElement(points[i], i, reset); - } - - if (showLine && line._model.tension !== 0) { - me.updateBezierControlPoints(); - } - - // Now pivot the point for animation - for (i = 0, ilen = points.length; i < ilen; ++i) { - points[i].pivot(); - } - }, - - updateElement: function(point, index, reset) { - var me = this; - var meta = me.getMeta(); - var custom = point.custom || {}; - var dataset = me.getDataset(); - var datasetIndex = me.index; - var value = dataset.data[index]; - var yScale = me.getScaleForId(meta.yAxisID); - var xScale = me.getScaleForId(meta.xAxisID); - var lineModel = meta.dataset._model; - var x, y; - - var options = me._resolvePointOptions(point, index); - - x = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex); - y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex); - - // Utility - point._xScale = xScale; - point._yScale = yScale; - point._options = options; - point._datasetIndex = datasetIndex; - point._index = index; - - // Desired view properties - point._model = { - x: x, - y: y, - skip: custom.skip || isNaN(x) || isNaN(y), - // Appearance - radius: options.radius, - pointStyle: options.pointStyle, - rotation: options.rotation, - backgroundColor: options.backgroundColor, - borderColor: options.borderColor, - borderWidth: options.borderWidth, - tension: valueOrDefault$5(custom.tension, lineModel ? lineModel.tension : 0), - steppedLine: lineModel ? lineModel.steppedLine : false, - // Tooltip - hitRadius: options.hitRadius - }; - }, - - /** - * @private - */ - _resolvePointOptions: function(element, index) { - var me = this; - var chart = me.chart; - var dataset = chart.data.datasets[me.index]; - var custom = element.custom || {}; - var options = chart.options.elements.point; - var values = {}; - var i, ilen, key; - - // Scriptable options - var context = { - chart: chart, - dataIndex: index, - dataset: dataset, - datasetIndex: me.index - }; - - var ELEMENT_OPTIONS = { - backgroundColor: 'pointBackgroundColor', - borderColor: 'pointBorderColor', - borderWidth: 'pointBorderWidth', - hitRadius: 'pointHitRadius', - hoverBackgroundColor: 'pointHoverBackgroundColor', - hoverBorderColor: 'pointHoverBorderColor', - hoverBorderWidth: 'pointHoverBorderWidth', - hoverRadius: 'pointHoverRadius', - pointStyle: 'pointStyle', - radius: 'pointRadius', - rotation: 'pointRotation' - }; - var keys = Object.keys(ELEMENT_OPTIONS); - - for (i = 0, ilen = keys.length; i < ilen; ++i) { - key = keys[i]; - values[key] = resolve$4([ - custom[key], - dataset[ELEMENT_OPTIONS[key]], - dataset[key], - options[key] - ], context, index); - } - - return values; - }, - - /** - * @private - */ - _resolveLineOptions: function(element) { - var me = this; - var chart = me.chart; - var dataset = chart.data.datasets[me.index]; - var custom = element.custom || {}; - var options = chart.options; - var elementOptions = options.elements.line; - var values = {}; - var i, ilen, key; - - var keys = [ - 'backgroundColor', - 'borderWidth', - 'borderColor', - 'borderCapStyle', - 'borderDash', - 'borderDashOffset', - 'borderJoinStyle', - 'fill', - 'cubicInterpolationMode' - ]; - - for (i = 0, ilen = keys.length; i < ilen; ++i) { - key = keys[i]; - values[key] = resolve$4([ - custom[key], - dataset[key], - elementOptions[key] - ]); - } - - // The default behavior of lines is to break at null values, according - // to https://github.com/chartjs/Chart.js/issues/2435#issuecomment-216718158 - // This option gives lines the ability to span gaps - values.spanGaps = valueOrDefault$5(dataset.spanGaps, options.spanGaps); - values.tension = valueOrDefault$5(dataset.lineTension, elementOptions.tension); - values.steppedLine = resolve$4([custom.steppedLine, dataset.steppedLine, elementOptions.stepped]); - - return values; - }, - - calculatePointY: function(value, index, datasetIndex) { - var me = this; - var chart = me.chart; - var meta = me.getMeta(); - var yScale = me.getScaleForId(meta.yAxisID); - var sumPos = 0; - var sumNeg = 0; - var i, ds, dsMeta; - - if (yScale.options.stacked) { - for (i = 0; i < datasetIndex; i++) { - ds = chart.data.datasets[i]; - dsMeta = chart.getDatasetMeta(i); - if (dsMeta.type === 'line' && dsMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) { - var stackedRightValue = Number(yScale.getRightValue(ds.data[index])); - if (stackedRightValue < 0) { - sumNeg += stackedRightValue || 0; - } else { - sumPos += stackedRightValue || 0; - } - } - } - - var rightValue = Number(yScale.getRightValue(value)); - if (rightValue < 0) { - return yScale.getPixelForValue(sumNeg + rightValue); - } - return yScale.getPixelForValue(sumPos + rightValue); - } - - return yScale.getPixelForValue(value); - }, - - updateBezierControlPoints: function() { - var me = this; - var chart = me.chart; - var meta = me.getMeta(); - var lineModel = meta.dataset._model; - var area = chart.chartArea; - var points = meta.data || []; - var i, ilen, model, controlPoints; - - // Only consider points that are drawn in case the spanGaps option is used - if (lineModel.spanGaps) { - points = points.filter(function(pt) { - return !pt._model.skip; - }); - } - - function capControlPoint(pt, min, max) { - return Math.max(Math.min(pt, max), min); - } - - if (lineModel.cubicInterpolationMode === 'monotone') { - helpers$1.splineCurveMonotone(points); - } else { - for (i = 0, ilen = points.length; i < ilen; ++i) { - model = points[i]._model; - controlPoints = helpers$1.splineCurve( - helpers$1.previousItem(points, i)._model, - model, - helpers$1.nextItem(points, i)._model, - lineModel.tension - ); - model.controlPointPreviousX = controlPoints.previous.x; - model.controlPointPreviousY = controlPoints.previous.y; - model.controlPointNextX = controlPoints.next.x; - model.controlPointNextY = controlPoints.next.y; - } - } - - if (chart.options.elements.line.capBezierPoints) { - for (i = 0, ilen = points.length; i < ilen; ++i) { - model = points[i]._model; - if (isPointInArea(model, area)) { - if (i > 0 && isPointInArea(points[i - 1]._model, area)) { - model.controlPointPreviousX = capControlPoint(model.controlPointPreviousX, area.left, area.right); - model.controlPointPreviousY = capControlPoint(model.controlPointPreviousY, area.top, area.bottom); - } - if (i < points.length - 1 && isPointInArea(points[i + 1]._model, area)) { - model.controlPointNextX = capControlPoint(model.controlPointNextX, area.left, area.right); - model.controlPointNextY = capControlPoint(model.controlPointNextY, area.top, area.bottom); - } - } - } - } - }, - - draw: function() { - var me = this; - var chart = me.chart; - var meta = me.getMeta(); - var points = meta.data || []; - var area = chart.chartArea; - var ilen = points.length; - var halfBorderWidth; - var i = 0; - - if (lineEnabled(me.getDataset(), chart.options)) { - halfBorderWidth = (meta.dataset._model.borderWidth || 0) / 2; - - helpers$1.canvas.clipArea(chart.ctx, { - left: area.left, - right: area.right, - top: area.top - halfBorderWidth, - bottom: area.bottom + halfBorderWidth - }); - - meta.dataset.draw(); - - helpers$1.canvas.unclipArea(chart.ctx); - } - - // Draw the points - for (; i < ilen; ++i) { - points[i].draw(area); - } - }, - - /** - * @protected - */ - setHoverStyle: function(point) { - var model = point._model; - var options = point._options; - var getHoverColor = helpers$1.getHoverColor; - - point.$previousStyle = { - backgroundColor: model.backgroundColor, - borderColor: model.borderColor, - borderWidth: model.borderWidth, - radius: model.radius - }; - - model.backgroundColor = valueOrDefault$5(options.hoverBackgroundColor, getHoverColor(options.backgroundColor)); - model.borderColor = valueOrDefault$5(options.hoverBorderColor, getHoverColor(options.borderColor)); - model.borderWidth = valueOrDefault$5(options.hoverBorderWidth, options.borderWidth); - model.radius = valueOrDefault$5(options.hoverRadius, options.radius); - }, -}); - -var resolve$5 = helpers$1.options.resolve; - -core_defaults._set('polarArea', { - scale: { - type: 'radialLinear', - angleLines: { - display: false - }, - gridLines: { - circular: true - }, - pointLabels: { - display: false - }, - ticks: { - beginAtZero: true - } - }, - - // Boolean - Whether to animate the rotation of the chart - animation: { - animateRotate: true, - animateScale: true - }, - - startAngle: -0.5 * Math.PI, - legendCallback: function(chart) { - var text = []; - text.push('
    '); - - var data = chart.data; - var datasets = data.datasets; - var labels = data.labels; - - if (datasets.length) { - for (var i = 0; i < datasets[0].data.length; ++i) { - text.push('
  • '); - if (labels[i]) { - text.push(labels[i]); - } - text.push('
  • '); - } - } - - text.push('
'); - return text.join(''); - }, - legend: { - labels: { - generateLabels: function(chart) { - var data = chart.data; - if (data.labels.length && data.datasets.length) { - return data.labels.map(function(label, i) { - var meta = chart.getDatasetMeta(0); - var ds = data.datasets[0]; - var arc = meta.data[i]; - var custom = arc.custom || {}; - var arcOpts = chart.options.elements.arc; - var fill = resolve$5([custom.backgroundColor, ds.backgroundColor, arcOpts.backgroundColor], undefined, i); - var stroke = resolve$5([custom.borderColor, ds.borderColor, arcOpts.borderColor], undefined, i); - var bw = resolve$5([custom.borderWidth, ds.borderWidth, arcOpts.borderWidth], undefined, i); - - return { - text: label, - fillStyle: fill, - strokeStyle: stroke, - lineWidth: bw, - hidden: isNaN(ds.data[i]) || meta.data[i].hidden, - - // Extra data used for toggling the correct item - index: i - }; - }); - } - return []; - } - }, - - onClick: function(e, legendItem) { - var index = legendItem.index; - var chart = this.chart; - var i, ilen, meta; - - for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) { - meta = chart.getDatasetMeta(i); - meta.data[index].hidden = !meta.data[index].hidden; - } - - chart.update(); - } - }, - - // Need to override these to give a nice default - tooltips: { - callbacks: { - title: function() { - return ''; - }, - label: function(item, data) { - return data.labels[item.index] + ': ' + item.yLabel; - } - } - } -}); - -var controller_polarArea = core_datasetController.extend({ - - dataElementType: elements.Arc, - - linkScales: helpers$1.noop, - - update: function(reset) { - var me = this; - var dataset = me.getDataset(); - var meta = me.getMeta(); - var start = me.chart.options.startAngle || 0; - var starts = me._starts = []; - var angles = me._angles = []; - var arcs = meta.data; - var i, ilen, angle; - - me._updateRadius(); - - meta.count = me.countVisibleElements(); - - for (i = 0, ilen = dataset.data.length; i < ilen; i++) { - starts[i] = start; - angle = me._computeAngle(i); - angles[i] = angle; - start += angle; - } - - for (i = 0, ilen = arcs.length; i < ilen; ++i) { - arcs[i]._options = me._resolveElementOptions(arcs[i], i); - me.updateElement(arcs[i], i, reset); - } - }, - - /** - * @private - */ - _updateRadius: function() { - var me = this; - var chart = me.chart; - var chartArea = chart.chartArea; - var opts = chart.options; - var minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top); - - chart.outerRadius = Math.max(minSize / 2, 0); - chart.innerRadius = Math.max(opts.cutoutPercentage ? (chart.outerRadius / 100) * (opts.cutoutPercentage) : 1, 0); - chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount(); - - me.outerRadius = chart.outerRadius - (chart.radiusLength * me.index); - me.innerRadius = me.outerRadius - chart.radiusLength; - }, - - updateElement: function(arc, index, reset) { - var me = this; - var chart = me.chart; - var dataset = me.getDataset(); - var opts = chart.options; - var animationOpts = opts.animation; - var scale = chart.scale; - var labels = chart.data.labels; - - var centerX = scale.xCenter; - var centerY = scale.yCenter; - - // var negHalfPI = -0.5 * Math.PI; - var datasetStartAngle = opts.startAngle; - var distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]); - var startAngle = me._starts[index]; - var endAngle = startAngle + (arc.hidden ? 0 : me._angles[index]); - - var resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]); - var options = arc._options || {}; - - helpers$1.extend(arc, { - // Utility - _datasetIndex: me.index, - _index: index, - _scale: scale, - - // Desired view properties - _model: { - backgroundColor: options.backgroundColor, - borderColor: options.borderColor, - borderWidth: options.borderWidth, - borderAlign: options.borderAlign, - x: centerX, - y: centerY, - innerRadius: 0, - outerRadius: reset ? resetRadius : distance, - startAngle: reset && animationOpts.animateRotate ? datasetStartAngle : startAngle, - endAngle: reset && animationOpts.animateRotate ? datasetStartAngle : endAngle, - label: helpers$1.valueAtIndexOrDefault(labels, index, labels[index]) - } - }); - - arc.pivot(); - }, - - countVisibleElements: function() { - var dataset = this.getDataset(); - var meta = this.getMeta(); - var count = 0; - - helpers$1.each(meta.data, function(element, index) { - if (!isNaN(dataset.data[index]) && !element.hidden) { - count++; - } - }); - - return count; - }, - - /** - * @protected - */ - setHoverStyle: function(arc) { - var model = arc._model; - var options = arc._options; - var getHoverColor = helpers$1.getHoverColor; - var valueOrDefault = helpers$1.valueOrDefault; - - arc.$previousStyle = { - backgroundColor: model.backgroundColor, - borderColor: model.borderColor, - borderWidth: model.borderWidth, - }; - - model.backgroundColor = valueOrDefault(options.hoverBackgroundColor, getHoverColor(options.backgroundColor)); - model.borderColor = valueOrDefault(options.hoverBorderColor, getHoverColor(options.borderColor)); - model.borderWidth = valueOrDefault(options.hoverBorderWidth, options.borderWidth); - }, - - /** - * @private - */ - _resolveElementOptions: function(arc, index) { - var me = this; - var chart = me.chart; - var dataset = me.getDataset(); - var custom = arc.custom || {}; - var options = chart.options.elements.arc; - var values = {}; - var i, ilen, key; - - // Scriptable options - var context = { - chart: chart, - dataIndex: index, - dataset: dataset, - datasetIndex: me.index - }; - - var keys = [ - 'backgroundColor', - 'borderColor', - 'borderWidth', - 'borderAlign', - 'hoverBackgroundColor', - 'hoverBorderColor', - 'hoverBorderWidth', - ]; - - for (i = 0, ilen = keys.length; i < ilen; ++i) { - key = keys[i]; - values[key] = resolve$5([ - custom[key], - dataset[key], - options[key] - ], context, index); - } - - return values; - }, - - /** - * @private - */ - _computeAngle: function(index) { - var me = this; - var count = this.getMeta().count; - var dataset = me.getDataset(); - var meta = me.getMeta(); - - if (isNaN(dataset.data[index]) || meta.data[index].hidden) { - return 0; - } - - // Scriptable options - var context = { - chart: me.chart, - dataIndex: index, - dataset: dataset, - datasetIndex: me.index - }; - - return resolve$5([ - me.chart.options.elements.arc.angle, - (2 * Math.PI) / count - ], context, index); - } -}); - -core_defaults._set('pie', helpers$1.clone(core_defaults.doughnut)); -core_defaults._set('pie', { - cutoutPercentage: 0 -}); - -// Pie charts are Doughnut chart with different defaults -var controller_pie = controller_doughnut; - -var valueOrDefault$6 = helpers$1.valueOrDefault; -var resolve$6 = helpers$1.options.resolve; - -core_defaults._set('radar', { - scale: { - type: 'radialLinear' - }, - elements: { - line: { - tension: 0 // no bezier in radar - } - } -}); - -var controller_radar = core_datasetController.extend({ - - datasetElementType: elements.Line, - - dataElementType: elements.Point, - - linkScales: helpers$1.noop, - - update: function(reset) { - var me = this; - var meta = me.getMeta(); - var line = meta.dataset; - var points = meta.data || []; - var scale = me.chart.scale; - var dataset = me.getDataset(); - var i, ilen; - - // Compatibility: If the properties are defined with only the old name, use those values - if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) { - dataset.lineTension = dataset.tension; - } - - // Utility - line._scale = scale; - line._datasetIndex = me.index; - // Data - line._children = points; - line._loop = true; - // Model - line._model = me._resolveLineOptions(line); - - line.pivot(); - - // Update Points - for (i = 0, ilen = points.length; i < ilen; ++i) { - me.updateElement(points[i], i, reset); - } - - // Update bezier control points - me.updateBezierControlPoints(); - - // Now pivot the point for animation - for (i = 0, ilen = points.length; i < ilen; ++i) { - points[i].pivot(); - } - }, - - updateElement: function(point, index, reset) { - var me = this; - var custom = point.custom || {}; - var dataset = me.getDataset(); - var scale = me.chart.scale; - var pointPosition = scale.getPointPositionForValue(index, dataset.data[index]); - var options = me._resolvePointOptions(point, index); - var lineModel = me.getMeta().dataset._model; - var x = reset ? scale.xCenter : pointPosition.x; - var y = reset ? scale.yCenter : pointPosition.y; - - // Utility - point._scale = scale; - point._options = options; - point._datasetIndex = me.index; - point._index = index; - - // Desired view properties - point._model = { - x: x, // value not used in dataset scale, but we want a consistent API between scales - y: y, - skip: custom.skip || isNaN(x) || isNaN(y), - // Appearance - radius: options.radius, - pointStyle: options.pointStyle, - rotation: options.rotation, - backgroundColor: options.backgroundColor, - borderColor: options.borderColor, - borderWidth: options.borderWidth, - tension: valueOrDefault$6(custom.tension, lineModel ? lineModel.tension : 0), - - // Tooltip - hitRadius: options.hitRadius - }; - }, - - /** - * @private - */ - _resolvePointOptions: function(element, index) { - var me = this; - var chart = me.chart; - var dataset = chart.data.datasets[me.index]; - var custom = element.custom || {}; - var options = chart.options.elements.point; - var values = {}; - var i, ilen, key; - - // Scriptable options - var context = { - chart: chart, - dataIndex: index, - dataset: dataset, - datasetIndex: me.index - }; - - var ELEMENT_OPTIONS = { - backgroundColor: 'pointBackgroundColor', - borderColor: 'pointBorderColor', - borderWidth: 'pointBorderWidth', - hitRadius: 'pointHitRadius', - hoverBackgroundColor: 'pointHoverBackgroundColor', - hoverBorderColor: 'pointHoverBorderColor', - hoverBorderWidth: 'pointHoverBorderWidth', - hoverRadius: 'pointHoverRadius', - pointStyle: 'pointStyle', - radius: 'pointRadius', - rotation: 'pointRotation' - }; - var keys = Object.keys(ELEMENT_OPTIONS); - - for (i = 0, ilen = keys.length; i < ilen; ++i) { - key = keys[i]; - values[key] = resolve$6([ - custom[key], - dataset[ELEMENT_OPTIONS[key]], - dataset[key], - options[key] - ], context, index); - } - - return values; - }, - - /** - * @private - */ - _resolveLineOptions: function(element) { - var me = this; - var chart = me.chart; - var dataset = chart.data.datasets[me.index]; - var custom = element.custom || {}; - var options = chart.options.elements.line; - var values = {}; - var i, ilen, key; - - var keys = [ - 'backgroundColor', - 'borderWidth', - 'borderColor', - 'borderCapStyle', - 'borderDash', - 'borderDashOffset', - 'borderJoinStyle', - 'fill' - ]; - - for (i = 0, ilen = keys.length; i < ilen; ++i) { - key = keys[i]; - values[key] = resolve$6([ - custom[key], - dataset[key], - options[key] - ]); - } - - values.tension = valueOrDefault$6(dataset.lineTension, options.tension); - - return values; - }, - - updateBezierControlPoints: function() { - var me = this; - var meta = me.getMeta(); - var area = me.chart.chartArea; - var points = meta.data || []; - var i, ilen, model, controlPoints; - - function capControlPoint(pt, min, max) { - return Math.max(Math.min(pt, max), min); - } - - for (i = 0, ilen = points.length; i < ilen; ++i) { - model = points[i]._model; - controlPoints = helpers$1.splineCurve( - helpers$1.previousItem(points, i, true)._model, - model, - helpers$1.nextItem(points, i, true)._model, - model.tension - ); - - // Prevent the bezier going outside of the bounds of the graph - model.controlPointPreviousX = capControlPoint(controlPoints.previous.x, area.left, area.right); - model.controlPointPreviousY = capControlPoint(controlPoints.previous.y, area.top, area.bottom); - model.controlPointNextX = capControlPoint(controlPoints.next.x, area.left, area.right); - model.controlPointNextY = capControlPoint(controlPoints.next.y, area.top, area.bottom); - } - }, - - setHoverStyle: function(point) { - var model = point._model; - var options = point._options; - var getHoverColor = helpers$1.getHoverColor; - - point.$previousStyle = { - backgroundColor: model.backgroundColor, - borderColor: model.borderColor, - borderWidth: model.borderWidth, - radius: model.radius - }; - - model.backgroundColor = valueOrDefault$6(options.hoverBackgroundColor, getHoverColor(options.backgroundColor)); - model.borderColor = valueOrDefault$6(options.hoverBorderColor, getHoverColor(options.borderColor)); - model.borderWidth = valueOrDefault$6(options.hoverBorderWidth, options.borderWidth); - model.radius = valueOrDefault$6(options.hoverRadius, options.radius); - } -}); - -core_defaults._set('scatter', { - hover: { - mode: 'single' - }, - - scales: { - xAxes: [{ - id: 'x-axis-1', // need an ID so datasets can reference the scale - type: 'linear', // scatter should not use a category axis - position: 'bottom' - }], - yAxes: [{ - id: 'y-axis-1', - type: 'linear', - position: 'left' - }] - }, - - showLines: false, - - tooltips: { - callbacks: { - title: function() { - return ''; // doesn't make sense for scatter since data are formatted as a point - }, - label: function(item) { - return '(' + item.xLabel + ', ' + item.yLabel + ')'; - } - } - } -}); - -// Scatter charts use line controllers -var controller_scatter = controller_line; - -// NOTE export a map in which the key represents the controller type, not -// the class, and so must be CamelCase in order to be correctly retrieved -// by the controller in core.controller.js (`controllers[meta.type]`). - -var controllers = { - bar: controller_bar, - bubble: controller_bubble, - doughnut: controller_doughnut, - horizontalBar: controller_horizontalBar, - line: controller_line, - polarArea: controller_polarArea, - pie: controller_pie, - radar: controller_radar, - scatter: controller_scatter -}; - -/** - * Helper function to get relative position for an event - * @param {Event|IEvent} event - The event to get the position for - * @param {Chart} chart - The chart - * @returns {object} the event position - */ -function getRelativePosition(e, chart) { - if (e.native) { - return { - x: e.x, - y: e.y - }; - } - - return helpers$1.getRelativePosition(e, chart); -} - -/** - * Helper function to traverse all of the visible elements in the chart - * @param {Chart} chart - the chart - * @param {function} handler - the callback to execute for each visible item - */ -function parseVisibleItems(chart, handler) { - var datasets = chart.data.datasets; - var meta, i, j, ilen, jlen; - - for (i = 0, ilen = datasets.length; i < ilen; ++i) { - if (!chart.isDatasetVisible(i)) { - continue; - } - - meta = chart.getDatasetMeta(i); - for (j = 0, jlen = meta.data.length; j < jlen; ++j) { - var element = meta.data[j]; - if (!element._view.skip) { - handler(element); - } - } - } -} - -/** - * Helper function to get the items that intersect the event position - * @param {ChartElement[]} items - elements to filter - * @param {object} position - the point to be nearest to - * @return {ChartElement[]} the nearest items - */ -function getIntersectItems(chart, position) { - var elements = []; - - parseVisibleItems(chart, function(element) { - if (element.inRange(position.x, position.y)) { - elements.push(element); - } - }); - - return elements; -} - -/** - * Helper function to get the items nearest to the event position considering all visible items in teh chart - * @param {Chart} chart - the chart to look at elements from - * @param {object} position - the point to be nearest to - * @param {boolean} intersect - if true, only consider items that intersect the position - * @param {function} distanceMetric - function to provide the distance between points - * @return {ChartElement[]} the nearest items - */ -function getNearestItems(chart, position, intersect, distanceMetric) { - var minDistance = Number.POSITIVE_INFINITY; - var nearestItems = []; - - parseVisibleItems(chart, function(element) { - if (intersect && !element.inRange(position.x, position.y)) { - return; - } - - var center = element.getCenterPoint(); - var distance = distanceMetric(position, center); - if (distance < minDistance) { - nearestItems = [element]; - minDistance = distance; - } else if (distance === minDistance) { - // Can have multiple items at the same distance in which case we sort by size - nearestItems.push(element); - } - }); - - return nearestItems; -} - -/** - * Get a distance metric function for two points based on the - * axis mode setting - * @param {string} axis - the axis mode. x|y|xy - */ -function getDistanceMetricForAxis(axis) { - var useX = axis.indexOf('x') !== -1; - var useY = axis.indexOf('y') !== -1; - - return function(pt1, pt2) { - var deltaX = useX ? Math.abs(pt1.x - pt2.x) : 0; - var deltaY = useY ? Math.abs(pt1.y - pt2.y) : 0; - return Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2)); - }; -} - -function indexMode(chart, e, options) { - var position = getRelativePosition(e, chart); - // Default axis for index mode is 'x' to match old behaviour - options.axis = options.axis || 'x'; - var distanceMetric = getDistanceMetricForAxis(options.axis); - var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric); - var elements = []; - - if (!items.length) { - return []; - } - - chart.data.datasets.forEach(function(dataset, datasetIndex) { - if (chart.isDatasetVisible(datasetIndex)) { - var meta = chart.getDatasetMeta(datasetIndex); - var element = meta.data[items[0]._index]; - - // don't count items that are skipped (null data) - if (element && !element._view.skip) { - elements.push(element); - } - } - }); - - return elements; -} - -/** - * @interface IInteractionOptions - */ -/** - * If true, only consider items that intersect the point - * @name IInterfaceOptions#boolean - * @type Boolean - */ - -/** - * Contains interaction related functions - * @namespace Chart.Interaction - */ -var core_interaction = { - // Helper function for different modes - modes: { - single: function(chart, e) { - var position = getRelativePosition(e, chart); - var elements = []; - - parseVisibleItems(chart, function(element) { - if (element.inRange(position.x, position.y)) { - elements.push(element); - return elements; - } - }); - - return elements.slice(0, 1); - }, - - /** - * @function Chart.Interaction.modes.label - * @deprecated since version 2.4.0 - * @todo remove at version 3 - * @private - */ - label: indexMode, - - /** - * Returns items at the same index. If the options.intersect parameter is true, we only return items if we intersect something - * If the options.intersect mode is false, we find the nearest item and return the items at the same index as that item - * @function Chart.Interaction.modes.index - * @since v2.4.0 - * @param {Chart} chart - the chart we are returning items from - * @param {Event} e - the event we are find things at - * @param {IInteractionOptions} options - options to use during interaction - * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned - */ - index: indexMode, - - /** - * Returns items in the same dataset. If the options.intersect parameter is true, we only return items if we intersect something - * If the options.intersect is false, we find the nearest item and return the items in that dataset - * @function Chart.Interaction.modes.dataset - * @param {Chart} chart - the chart we are returning items from - * @param {Event} e - the event we are find things at - * @param {IInteractionOptions} options - options to use during interaction - * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned - */ - dataset: function(chart, e, options) { - var position = getRelativePosition(e, chart); - options.axis = options.axis || 'xy'; - var distanceMetric = getDistanceMetricForAxis(options.axis); - var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric); - - if (items.length > 0) { - items = chart.getDatasetMeta(items[0]._datasetIndex).data; - } - - return items; - }, - - /** - * @function Chart.Interaction.modes.x-axis - * @deprecated since version 2.4.0. Use index mode and intersect == true - * @todo remove at version 3 - * @private - */ - 'x-axis': function(chart, e) { - return indexMode(chart, e, {intersect: false}); - }, - - /** - * Point mode returns all elements that hit test based on the event position - * of the event - * @function Chart.Interaction.modes.intersect - * @param {Chart} chart - the chart we are returning items from - * @param {Event} e - the event we are find things at - * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned - */ - point: function(chart, e) { - var position = getRelativePosition(e, chart); - return getIntersectItems(chart, position); - }, - - /** - * nearest mode returns the element closest to the point - * @function Chart.Interaction.modes.intersect - * @param {Chart} chart - the chart we are returning items from - * @param {Event} e - the event we are find things at - * @param {IInteractionOptions} options - options to use - * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned - */ - nearest: function(chart, e, options) { - var position = getRelativePosition(e, chart); - options.axis = options.axis || 'xy'; - var distanceMetric = getDistanceMetricForAxis(options.axis); - return getNearestItems(chart, position, options.intersect, distanceMetric); - }, - - /** - * x mode returns the elements that hit-test at the current x coordinate - * @function Chart.Interaction.modes.x - * @param {Chart} chart - the chart we are returning items from - * @param {Event} e - the event we are find things at - * @param {IInteractionOptions} options - options to use - * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned - */ - x: function(chart, e, options) { - var position = getRelativePosition(e, chart); - var items = []; - var intersectsItem = false; - - parseVisibleItems(chart, function(element) { - if (element.inXRange(position.x)) { - items.push(element); - } - - if (element.inRange(position.x, position.y)) { - intersectsItem = true; - } - }); - - // If we want to trigger on an intersect and we don't have any items - // that intersect the position, return nothing - if (options.intersect && !intersectsItem) { - items = []; - } - return items; - }, - - /** - * y mode returns the elements that hit-test at the current y coordinate - * @function Chart.Interaction.modes.y - * @param {Chart} chart - the chart we are returning items from - * @param {Event} e - the event we are find things at - * @param {IInteractionOptions} options - options to use - * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned - */ - y: function(chart, e, options) { - var position = getRelativePosition(e, chart); - var items = []; - var intersectsItem = false; - - parseVisibleItems(chart, function(element) { - if (element.inYRange(position.y)) { - items.push(element); - } - - if (element.inRange(position.x, position.y)) { - intersectsItem = true; - } - }); - - // If we want to trigger on an intersect and we don't have any items - // that intersect the position, return nothing - if (options.intersect && !intersectsItem) { - items = []; - } - return items; - } - } -}; - -function filterByPosition(array, position) { - return helpers$1.where(array, function(v) { - return v.position === position; - }); -} - -function sortByWeight(array, reverse) { - array.forEach(function(v, i) { - v._tmpIndex_ = i; - return v; - }); - array.sort(function(a, b) { - var v0 = reverse ? b : a; - var v1 = reverse ? a : b; - return v0.weight === v1.weight ? - v0._tmpIndex_ - v1._tmpIndex_ : - v0.weight - v1.weight; - }); - array.forEach(function(v) { - delete v._tmpIndex_; - }); -} - -function findMaxPadding(boxes) { - var top = 0; - var left = 0; - var bottom = 0; - var right = 0; - helpers$1.each(boxes, function(box) { - if (box.getPadding) { - var boxPadding = box.getPadding(); - top = Math.max(top, boxPadding.top); - left = Math.max(left, boxPadding.left); - bottom = Math.max(bottom, boxPadding.bottom); - right = Math.max(right, boxPadding.right); - } - }); - return { - top: top, - left: left, - bottom: bottom, - right: right - }; -} - -function addSizeByPosition(boxes, size) { - helpers$1.each(boxes, function(box) { - size[box.position] += box.isHorizontal() ? box.height : box.width; - }); -} - -core_defaults._set('global', { - layout: { - padding: { - top: 0, - right: 0, - bottom: 0, - left: 0 - } - } -}); - -/** - * @interface ILayoutItem - * @prop {string} position - The position of the item in the chart layout. Possible values are - * 'left', 'top', 'right', 'bottom', and 'chartArea' - * @prop {number} weight - The weight used to sort the item. Higher weights are further away from the chart area - * @prop {boolean} fullWidth - if true, and the item is horizontal, then push vertical boxes down - * @prop {function} isHorizontal - returns true if the layout item is horizontal (ie. top or bottom) - * @prop {function} update - Takes two parameters: width and height. Returns size of item - * @prop {function} getPadding - Returns an object with padding on the edges - * @prop {number} width - Width of item. Must be valid after update() - * @prop {number} height - Height of item. Must be valid after update() - * @prop {number} left - Left edge of the item. Set by layout system and cannot be used in update - * @prop {number} top - Top edge of the item. Set by layout system and cannot be used in update - * @prop {number} right - Right edge of the item. Set by layout system and cannot be used in update - * @prop {number} bottom - Bottom edge of the item. Set by layout system and cannot be used in update - */ - -// The layout service is very self explanatory. It's responsible for the layout within a chart. -// Scales, Legends and Plugins all rely on the layout service and can easily register to be placed anywhere they need -// It is this service's responsibility of carrying out that layout. -var core_layouts = { - defaults: {}, - - /** - * Register a box to a chart. - * A box is simply a reference to an object that requires layout. eg. Scales, Legend, Title. - * @param {Chart} chart - the chart to use - * @param {ILayoutItem} item - the item to add to be layed out - */ - addBox: function(chart, item) { - if (!chart.boxes) { - chart.boxes = []; - } - - // initialize item with default values - item.fullWidth = item.fullWidth || false; - item.position = item.position || 'top'; - item.weight = item.weight || 0; - - chart.boxes.push(item); - }, - - /** - * Remove a layoutItem from a chart - * @param {Chart} chart - the chart to remove the box from - * @param {ILayoutItem} layoutItem - the item to remove from the layout - */ - removeBox: function(chart, layoutItem) { - var index = chart.boxes ? chart.boxes.indexOf(layoutItem) : -1; - if (index !== -1) { - chart.boxes.splice(index, 1); - } - }, - - /** - * Sets (or updates) options on the given `item`. - * @param {Chart} chart - the chart in which the item lives (or will be added to) - * @param {ILayoutItem} item - the item to configure with the given options - * @param {object} options - the new item options. - */ - configure: function(chart, item, options) { - var props = ['fullWidth', 'position', 'weight']; - var ilen = props.length; - var i = 0; - var prop; - - for (; i < ilen; ++i) { - prop = props[i]; - if (options.hasOwnProperty(prop)) { - item[prop] = options[prop]; - } - } - }, - - /** - * Fits boxes of the given chart into the given size by having each box measure itself - * then running a fitting algorithm - * @param {Chart} chart - the chart - * @param {number} width - the width to fit into - * @param {number} height - the height to fit into - */ - update: function(chart, width, height) { - if (!chart) { - return; - } - - var layoutOptions = chart.options.layout || {}; - var padding = helpers$1.options.toPadding(layoutOptions.padding); - var leftPadding = padding.left; - var rightPadding = padding.right; - var topPadding = padding.top; - var bottomPadding = padding.bottom; - - var leftBoxes = filterByPosition(chart.boxes, 'left'); - var rightBoxes = filterByPosition(chart.boxes, 'right'); - var topBoxes = filterByPosition(chart.boxes, 'top'); - var bottomBoxes = filterByPosition(chart.boxes, 'bottom'); - var chartAreaBoxes = filterByPosition(chart.boxes, 'chartArea'); - - // Sort boxes by weight. A higher weight is further away from the chart area - sortByWeight(leftBoxes, true); - sortByWeight(rightBoxes, false); - sortByWeight(topBoxes, true); - sortByWeight(bottomBoxes, false); - - var verticalBoxes = leftBoxes.concat(rightBoxes); - var horizontalBoxes = topBoxes.concat(bottomBoxes); - var outerBoxes = verticalBoxes.concat(horizontalBoxes); - - // Essentially we now have any number of boxes on each of the 4 sides. - // Our canvas looks like the following. - // The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and - // B1 is the bottom axis - // There are also 4 quadrant-like locations (left to right instead of clockwise) reserved for chart overlays - // These locations are single-box locations only, when trying to register a chartArea location that is already taken, - // an error will be thrown. - // - // |----------------------------------------------------| - // | T1 (Full Width) | - // |----------------------------------------------------| - // | | | T2 | | - // | |----|-------------------------------------|----| - // | | | C1 | | C2 | | - // | | |----| |----| | - // | | | | | - // | L1 | L2 | ChartArea (C0) | R1 | - // | | | | | - // | | |----| |----| | - // | | | C3 | | C4 | | - // | |----|-------------------------------------|----| - // | | | B1 | | - // |----------------------------------------------------| - // | B2 (Full Width) | - // |----------------------------------------------------| - // - // What we do to find the best sizing, we do the following - // 1. Determine the minimum size of the chart area. - // 2. Split the remaining width equally between each vertical axis - // 3. Split the remaining height equally between each horizontal axis - // 4. Give each layout the maximum size it can be. The layout will return it's minimum size - // 5. Adjust the sizes of each axis based on it's minimum reported size. - // 6. Refit each axis - // 7. Position each axis in the final location - // 8. Tell the chart the final location of the chart area - // 9. Tell any axes that overlay the chart area the positions of the chart area - - // Step 1 - var chartWidth = width - leftPadding - rightPadding; - var chartHeight = height - topPadding - bottomPadding; - var chartAreaWidth = chartWidth / 2; // min 50% - - // Step 2 - var verticalBoxWidth = (width - chartAreaWidth) / verticalBoxes.length; - - // Step 3 - // TODO re-limit horizontal axis height (this limit has affected only padding calculation since PR 1837) - // var horizontalBoxHeight = (height - chartAreaHeight) / horizontalBoxes.length; - - // Step 4 - var maxChartAreaWidth = chartWidth; - var maxChartAreaHeight = chartHeight; - var outerBoxSizes = {top: topPadding, left: leftPadding, bottom: bottomPadding, right: rightPadding}; - var minBoxSizes = []; - var maxPadding; - - function getMinimumBoxSize(box) { - var minSize; - var isHorizontal = box.isHorizontal(); - - if (isHorizontal) { - minSize = box.update(box.fullWidth ? chartWidth : maxChartAreaWidth, chartHeight / 2); - maxChartAreaHeight -= minSize.height; - } else { - minSize = box.update(verticalBoxWidth, maxChartAreaHeight); - maxChartAreaWidth -= minSize.width; - } - - minBoxSizes.push({ - horizontal: isHorizontal, - width: minSize.width, - box: box, - }); - } - - helpers$1.each(outerBoxes, getMinimumBoxSize); - - // If a horizontal box has padding, we move the left boxes over to avoid ugly charts (see issue #2478) - maxPadding = findMaxPadding(outerBoxes); - - // At this point, maxChartAreaHeight and maxChartAreaWidth are the size the chart area could - // be if the axes are drawn at their minimum sizes. - // Steps 5 & 6 - - // Function to fit a box - function fitBox(box) { - var minBoxSize = helpers$1.findNextWhere(minBoxSizes, function(minBox) { - return minBox.box === box; - }); - - if (minBoxSize) { - if (minBoxSize.horizontal) { - var scaleMargin = { - left: Math.max(outerBoxSizes.left, maxPadding.left), - right: Math.max(outerBoxSizes.right, maxPadding.right), - top: 0, - bottom: 0 - }; - - // Don't use min size here because of label rotation. When the labels are rotated, their rotation highly depends - // on the margin. Sometimes they need to increase in size slightly - box.update(box.fullWidth ? chartWidth : maxChartAreaWidth, chartHeight / 2, scaleMargin); - } else { - box.update(minBoxSize.width, maxChartAreaHeight); - } - } - } - - // Update, and calculate the left and right margins for the horizontal boxes - helpers$1.each(verticalBoxes, fitBox); - addSizeByPosition(verticalBoxes, outerBoxSizes); - - // Set the Left and Right margins for the horizontal boxes - helpers$1.each(horizontalBoxes, fitBox); - addSizeByPosition(horizontalBoxes, outerBoxSizes); - - function finalFitVerticalBox(box) { - var minBoxSize = helpers$1.findNextWhere(minBoxSizes, function(minSize) { - return minSize.box === box; - }); - - var scaleMargin = { - left: 0, - right: 0, - top: outerBoxSizes.top, - bottom: outerBoxSizes.bottom - }; - - if (minBoxSize) { - box.update(minBoxSize.width, maxChartAreaHeight, scaleMargin); - } - } - - // Let the left layout know the final margin - helpers$1.each(verticalBoxes, finalFitVerticalBox); - - // Recalculate because the size of each layout might have changed slightly due to the margins (label rotation for instance) - outerBoxSizes = {top: topPadding, left: leftPadding, bottom: bottomPadding, right: rightPadding}; - addSizeByPosition(outerBoxes, outerBoxSizes); - - // We may be adding some padding to account for rotated x axis labels - var leftPaddingAddition = Math.max(maxPadding.left - outerBoxSizes.left, 0); - outerBoxSizes.left += leftPaddingAddition; - outerBoxSizes.right += Math.max(maxPadding.right - outerBoxSizes.right, 0); - - var topPaddingAddition = Math.max(maxPadding.top - outerBoxSizes.top, 0); - outerBoxSizes.top += topPaddingAddition; - outerBoxSizes.bottom += Math.max(maxPadding.bottom - outerBoxSizes.bottom, 0); - - // Figure out if our chart area changed. This would occur if the dataset layout label rotation - // changed due to the application of the margins in step 6. Since we can only get bigger, this is safe to do - // without calling `fit` again - var newMaxChartAreaHeight = height - outerBoxSizes.top - outerBoxSizes.bottom; - var newMaxChartAreaWidth = width - outerBoxSizes.left - outerBoxSizes.right; - - if (newMaxChartAreaWidth !== maxChartAreaWidth || newMaxChartAreaHeight !== maxChartAreaHeight) { - helpers$1.each(verticalBoxes, function(box) { - box.height = newMaxChartAreaHeight; - }); - - helpers$1.each(horizontalBoxes, function(box) { - if (!box.fullWidth) { - box.width = newMaxChartAreaWidth; - } - }); - - maxChartAreaHeight = newMaxChartAreaHeight; - maxChartAreaWidth = newMaxChartAreaWidth; - } - - // Step 7 - Position the boxes - var left = leftPadding + leftPaddingAddition; - var top = topPadding + topPaddingAddition; - - function placeBox(box) { - if (box.isHorizontal()) { - box.left = box.fullWidth ? leftPadding : outerBoxSizes.left; - box.right = box.fullWidth ? width - rightPadding : outerBoxSizes.left + maxChartAreaWidth; - box.top = top; - box.bottom = top + box.height; - - // Move to next point - top = box.bottom; - - } else { - - box.left = left; - box.right = left + box.width; - box.top = outerBoxSizes.top; - box.bottom = outerBoxSizes.top + maxChartAreaHeight; - - // Move to next point - left = box.right; - } - } - - helpers$1.each(leftBoxes.concat(topBoxes), placeBox); - - // Account for chart width and height - left += maxChartAreaWidth; - top += maxChartAreaHeight; - - helpers$1.each(rightBoxes, placeBox); - helpers$1.each(bottomBoxes, placeBox); - - // Step 8 - chart.chartArea = { - left: outerBoxSizes.left, - top: outerBoxSizes.top, - right: outerBoxSizes.left + maxChartAreaWidth, - bottom: outerBoxSizes.top + maxChartAreaHeight - }; - - // Step 9 - helpers$1.each(chartAreaBoxes, function(box) { - box.left = chart.chartArea.left; - box.top = chart.chartArea.top; - box.right = chart.chartArea.right; - box.bottom = chart.chartArea.bottom; - - box.update(maxChartAreaWidth, maxChartAreaHeight); - }); - } -}; - -/** - * Platform fallback implementation (minimal). - * @see https://github.com/chartjs/Chart.js/pull/4591#issuecomment-319575939 - */ - -var platform_basic = { - acquireContext: function(item) { - if (item && item.canvas) { - // Support for any object associated to a canvas (including a context2d) - item = item.canvas; - } - - return item && item.getContext('2d') || null; - } -}; - -var platform_dom = "/*\n * DOM element rendering detection\n * https://davidwalsh.name/detect-node-insertion\n */\n@keyframes chartjs-render-animation {\n\tfrom { opacity: 0.99; }\n\tto { opacity: 1; }\n}\n\n.chartjs-render-monitor {\n\tanimation: chartjs-render-animation 0.001s;\n}\n\n/*\n * DOM element resizing detection\n * https://github.com/marcj/css-element-queries\n */\n.chartjs-size-monitor,\n.chartjs-size-monitor-expand,\n.chartjs-size-monitor-shrink {\n\tposition: absolute;\n\tdirection: ltr;\n\tleft: 0;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\toverflow: hidden;\n\tpointer-events: none;\n\tvisibility: hidden;\n\tz-index: -1;\n}\n\n.chartjs-size-monitor-expand > div {\n\tposition: absolute;\n\twidth: 1000000px;\n\theight: 1000000px;\n\tleft: 0;\n\ttop: 0;\n}\n\n.chartjs-size-monitor-shrink > div {\n\tposition: absolute;\n\twidth: 200%;\n\theight: 200%;\n\tleft: 0;\n\ttop: 0;\n}\n"; - -var platform_dom$1 = /*#__PURE__*/Object.freeze({ -default: platform_dom -}); - -var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - -function commonjsRequire () { - throw new Error('Dynamic requires are not currently supported by rollup-plugin-commonjs'); -} - -function createCommonjsModule(fn, module) { - return module = { exports: {} }, fn(module, module.exports), module.exports; -} - -function getCjsExportFromNamespace (n) { - return n && n.default || n; -} - -var stylesheet = getCjsExportFromNamespace(platform_dom$1); - -var EXPANDO_KEY = '$chartjs'; -var CSS_PREFIX = 'chartjs-'; -var CSS_SIZE_MONITOR = CSS_PREFIX + 'size-monitor'; -var CSS_RENDER_MONITOR = CSS_PREFIX + 'render-monitor'; -var CSS_RENDER_ANIMATION = CSS_PREFIX + 'render-animation'; -var ANIMATION_START_EVENTS = ['animationstart', 'webkitAnimationStart']; - -/** - * DOM event types -> Chart.js event types. - * Note: only events with different types are mapped. - * @see https://developer.mozilla.org/en-US/docs/Web/Events - */ -var EVENT_TYPES = { - touchstart: 'mousedown', - touchmove: 'mousemove', - touchend: 'mouseup', - pointerenter: 'mouseenter', - pointerdown: 'mousedown', - pointermove: 'mousemove', - pointerup: 'mouseup', - pointerleave: 'mouseout', - pointerout: 'mouseout' -}; - -/** - * The "used" size is the final value of a dimension property after all calculations have - * been performed. This method uses the computed style of `element` but returns undefined - * if the computed style is not expressed in pixels. That can happen in some cases where - * `element` has a size relative to its parent and this last one is not yet displayed, - * for example because of `display: none` on a parent node. - * @see https://developer.mozilla.org/en-US/docs/Web/CSS/used_value - * @returns {number} Size in pixels or undefined if unknown. - */ -function readUsedSize(element, property) { - var value = helpers$1.getStyle(element, property); - var matches = value && value.match(/^(\d+)(\.\d+)?px$/); - return matches ? Number(matches[1]) : undefined; -} - -/** - * Initializes the canvas style and render size without modifying the canvas display size, - * since responsiveness is handled by the controller.resize() method. The config is used - * to determine the aspect ratio to apply in case no explicit height has been specified. - */ -function initCanvas(canvas, config) { - var style = canvas.style; - - // NOTE(SB) canvas.getAttribute('width') !== canvas.width: in the first case it - // returns null or '' if no explicit value has been set to the canvas attribute. - var renderHeight = canvas.getAttribute('height'); - var renderWidth = canvas.getAttribute('width'); - - // Chart.js modifies some canvas values that we want to restore on destroy - canvas[EXPANDO_KEY] = { - initial: { - height: renderHeight, - width: renderWidth, - style: { - display: style.display, - height: style.height, - width: style.width - } - } - }; - - // Force canvas to display as block to avoid extra space caused by inline - // elements, which would interfere with the responsive resize process. - // https://github.com/chartjs/Chart.js/issues/2538 - style.display = style.display || 'block'; - - if (renderWidth === null || renderWidth === '') { - var displayWidth = readUsedSize(canvas, 'width'); - if (displayWidth !== undefined) { - canvas.width = displayWidth; - } - } - - if (renderHeight === null || renderHeight === '') { - if (canvas.style.height === '') { - // If no explicit render height and style height, let's apply the aspect ratio, - // which one can be specified by the user but also by charts as default option - // (i.e. options.aspectRatio). If not specified, use canvas aspect ratio of 2. - canvas.height = canvas.width / (config.options.aspectRatio || 2); - } else { - var displayHeight = readUsedSize(canvas, 'height'); - if (displayWidth !== undefined) { - canvas.height = displayHeight; - } - } - } - - return canvas; -} - -/** - * Detects support for options object argument in addEventListener. - * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support - * @private - */ -var supportsEventListenerOptions = (function() { - var supports = false; - try { - var options = Object.defineProperty({}, 'passive', { - // eslint-disable-next-line getter-return - get: function() { - supports = true; - } - }); - window.addEventListener('e', null, options); - } catch (e) { - // continue regardless of error - } - return supports; -}()); - -// Default passive to true as expected by Chrome for 'touchstart' and 'touchend' events. -// https://github.com/chartjs/Chart.js/issues/4287 -var eventListenerOptions = supportsEventListenerOptions ? {passive: true} : false; - -function addListener(node, type, listener) { - node.addEventListener(type, listener, eventListenerOptions); -} - -function removeListener(node, type, listener) { - node.removeEventListener(type, listener, eventListenerOptions); -} - -function createEvent(type, chart, x, y, nativeEvent) { - return { - type: type, - chart: chart, - native: nativeEvent || null, - x: x !== undefined ? x : null, - y: y !== undefined ? y : null, - }; -} - -function fromNativeEvent(event, chart) { - var type = EVENT_TYPES[event.type] || event.type; - var pos = helpers$1.getRelativePosition(event, chart); - return createEvent(type, chart, pos.x, pos.y, event); -} - -function throttled(fn, thisArg) { - var ticking = false; - var args = []; - - return function() { - args = Array.prototype.slice.call(arguments); - thisArg = thisArg || this; - - if (!ticking) { - ticking = true; - helpers$1.requestAnimFrame.call(window, function() { - ticking = false; - fn.apply(thisArg, args); - }); - } - }; -} - -function createDiv(cls) { - var el = document.createElement('div'); - el.className = cls || ''; - return el; -} - -// Implementation based on https://github.com/marcj/css-element-queries -function createResizer(handler) { - var maxSize = 1000000; - - // NOTE(SB) Don't use innerHTML because it could be considered unsafe. - // https://github.com/chartjs/Chart.js/issues/5902 - var resizer = createDiv(CSS_SIZE_MONITOR); - var expand = createDiv(CSS_SIZE_MONITOR + '-expand'); - var shrink = createDiv(CSS_SIZE_MONITOR + '-shrink'); - - expand.appendChild(createDiv()); - shrink.appendChild(createDiv()); - - resizer.appendChild(expand); - resizer.appendChild(shrink); - resizer._reset = function() { - expand.scrollLeft = maxSize; - expand.scrollTop = maxSize; - shrink.scrollLeft = maxSize; - shrink.scrollTop = maxSize; - }; - - var onScroll = function() { - resizer._reset(); - handler(); - }; - - addListener(expand, 'scroll', onScroll.bind(expand, 'expand')); - addListener(shrink, 'scroll', onScroll.bind(shrink, 'shrink')); - - return resizer; -} - -// https://davidwalsh.name/detect-node-insertion -function watchForRender(node, handler) { - var expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {}); - var proxy = expando.renderProxy = function(e) { - if (e.animationName === CSS_RENDER_ANIMATION) { - handler(); - } - }; - - helpers$1.each(ANIMATION_START_EVENTS, function(type) { - addListener(node, type, proxy); - }); - - // #4737: Chrome might skip the CSS animation when the CSS_RENDER_MONITOR class - // is removed then added back immediately (same animation frame?). Accessing the - // `offsetParent` property will force a reflow and re-evaluate the CSS animation. - // https://gist.github.com/paulirish/5d52fb081b3570c81e3a#box-metrics - // https://github.com/chartjs/Chart.js/issues/4737 - expando.reflow = !!node.offsetParent; - - node.classList.add(CSS_RENDER_MONITOR); -} - -function unwatchForRender(node) { - var expando = node[EXPANDO_KEY] || {}; - var proxy = expando.renderProxy; - - if (proxy) { - helpers$1.each(ANIMATION_START_EVENTS, function(type) { - removeListener(node, type, proxy); - }); - - delete expando.renderProxy; - } - - node.classList.remove(CSS_RENDER_MONITOR); -} - -function addResizeListener(node, listener, chart) { - var expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {}); - - // Let's keep track of this added resizer and thus avoid DOM query when removing it. - var resizer = expando.resizer = createResizer(throttled(function() { - if (expando.resizer) { - var container = chart.options.maintainAspectRatio && node.parentNode; - var w = container ? container.clientWidth : 0; - listener(createEvent('resize', chart)); - if (container && container.clientWidth < w && chart.canvas) { - // If the container size shrank during chart resize, let's assume - // scrollbar appeared. So we resize again with the scrollbar visible - - // effectively making chart smaller and the scrollbar hidden again. - // Because we are inside `throttled`, and currently `ticking`, scroll - // events are ignored during this whole 2 resize process. - // If we assumed wrong and something else happened, we are resizing - // twice in a frame (potential performance issue) - listener(createEvent('resize', chart)); - } - } - })); - - // The resizer needs to be attached to the node parent, so we first need to be - // sure that `node` is attached to the DOM before injecting the resizer element. - watchForRender(node, function() { - if (expando.resizer) { - var container = node.parentNode; - if (container && container !== resizer.parentNode) { - container.insertBefore(resizer, container.firstChild); - } - - // The container size might have changed, let's reset the resizer state. - resizer._reset(); - } - }); -} - -function removeResizeListener(node) { - var expando = node[EXPANDO_KEY] || {}; - var resizer = expando.resizer; - - delete expando.resizer; - unwatchForRender(node); - - if (resizer && resizer.parentNode) { - resizer.parentNode.removeChild(resizer); - } -} - -function injectCSS(platform, css) { - // https://stackoverflow.com/q/3922139 - var style = platform._style || document.createElement('style'); - if (!platform._style) { - platform._style = style; - css = '/* Chart.js */\n' + css; - style.setAttribute('type', 'text/css'); - document.getElementsByTagName('head')[0].appendChild(style); - } - - style.appendChild(document.createTextNode(css)); -} - -var platform_dom$2 = { - /** - * When `true`, prevents the automatic injection of the stylesheet required to - * correctly detect when the chart is added to the DOM and then resized. This - * switch has been added to allow external stylesheet (`dist/Chart(.min)?.js`) - * to be manually imported to make this library compatible with any CSP. - * See https://github.com/chartjs/Chart.js/issues/5208 - */ - disableCSSInjection: false, - - /** - * This property holds whether this platform is enabled for the current environment. - * Currently used by platform.js to select the proper implementation. - * @private - */ - _enabled: typeof window !== 'undefined' && typeof document !== 'undefined', - - /** - * @private - */ - _ensureLoaded: function() { - if (this._loaded) { - return; - } - - this._loaded = true; - - // https://github.com/chartjs/Chart.js/issues/5208 - if (!this.disableCSSInjection) { - injectCSS(this, stylesheet); - } - }, - - acquireContext: function(item, config) { - if (typeof item === 'string') { - item = document.getElementById(item); - } else if (item.length) { - // Support for array based queries (such as jQuery) - item = item[0]; - } - - if (item && item.canvas) { - // Support for any object associated to a canvas (including a context2d) - item = item.canvas; - } - - // To prevent canvas fingerprinting, some add-ons undefine the getContext - // method, for example: https://github.com/kkapsner/CanvasBlocker - // https://github.com/chartjs/Chart.js/issues/2807 - var context = item && item.getContext && item.getContext('2d'); - - // Load platform resources on first chart creation, to make possible to change - // platform options after importing the library (e.g. `disableCSSInjection`). - this._ensureLoaded(); - - // `instanceof HTMLCanvasElement/CanvasRenderingContext2D` fails when the item is - // inside an iframe or when running in a protected environment. We could guess the - // types from their toString() value but let's keep things flexible and assume it's - // a sufficient condition if the item has a context2D which has item as `canvas`. - // https://github.com/chartjs/Chart.js/issues/3887 - // https://github.com/chartjs/Chart.js/issues/4102 - // https://github.com/chartjs/Chart.js/issues/4152 - if (context && context.canvas === item) { - initCanvas(item, config); - return context; - } - - return null; - }, - - releaseContext: function(context) { - var canvas = context.canvas; - if (!canvas[EXPANDO_KEY]) { - return; - } - - var initial = canvas[EXPANDO_KEY].initial; - ['height', 'width'].forEach(function(prop) { - var value = initial[prop]; - if (helpers$1.isNullOrUndef(value)) { - canvas.removeAttribute(prop); - } else { - canvas.setAttribute(prop, value); - } - }); - - helpers$1.each(initial.style || {}, function(value, key) { - canvas.style[key] = value; - }); - - // The canvas render size might have been changed (and thus the state stack discarded), - // we can't use save() and restore() to restore the initial state. So make sure that at - // least the canvas context is reset to the default state by setting the canvas width. - // https://www.w3.org/TR/2011/WD-html5-20110525/the-canvas-element.html - // eslint-disable-next-line no-self-assign - canvas.width = canvas.width; - - delete canvas[EXPANDO_KEY]; - }, - - addEventListener: function(chart, type, listener) { - var canvas = chart.canvas; - if (type === 'resize') { - // Note: the resize event is not supported on all browsers. - addResizeListener(canvas, listener, chart); - return; - } - - var expando = listener[EXPANDO_KEY] || (listener[EXPANDO_KEY] = {}); - var proxies = expando.proxies || (expando.proxies = {}); - var proxy = proxies[chart.id + '_' + type] = function(event) { - listener(fromNativeEvent(event, chart)); - }; - - addListener(canvas, type, proxy); - }, - - removeEventListener: function(chart, type, listener) { - var canvas = chart.canvas; - if (type === 'resize') { - // Note: the resize event is not supported on all browsers. - removeResizeListener(canvas); - return; - } - - var expando = listener[EXPANDO_KEY] || {}; - var proxies = expando.proxies || {}; - var proxy = proxies[chart.id + '_' + type]; - if (!proxy) { - return; - } - - removeListener(canvas, type, proxy); - } -}; - -// DEPRECATIONS - -/** - * Provided for backward compatibility, use EventTarget.addEventListener instead. - * EventTarget.addEventListener compatibility: Chrome, Opera 7, Safari, FF1.5+, IE9+ - * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener - * @function Chart.helpers.addEvent - * @deprecated since version 2.7.0 - * @todo remove at version 3 - * @private - */ -helpers$1.addEvent = addListener; - -/** - * Provided for backward compatibility, use EventTarget.removeEventListener instead. - * EventTarget.removeEventListener compatibility: Chrome, Opera 7, Safari, FF1.5+, IE9+ - * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener - * @function Chart.helpers.removeEvent - * @deprecated since version 2.7.0 - * @todo remove at version 3 - * @private - */ -helpers$1.removeEvent = removeListener; - -// @TODO Make possible to select another platform at build time. -var implementation = platform_dom$2._enabled ? platform_dom$2 : platform_basic; - -/** - * @namespace Chart.platform - * @see https://chartjs.gitbooks.io/proposals/content/Platform.html - * @since 2.4.0 - */ -var platform = helpers$1.extend({ - /** - * @since 2.7.0 - */ - initialize: function() {}, - - /** - * Called at chart construction time, returns a context2d instance implementing - * the [W3C Canvas 2D Context API standard]{@link https://www.w3.org/TR/2dcontext/}. - * @param {*} item - The native item from which to acquire context (platform specific) - * @param {object} options - The chart options - * @returns {CanvasRenderingContext2D} context2d instance - */ - acquireContext: function() {}, - - /** - * Called at chart destruction time, releases any resources associated to the context - * previously returned by the acquireContext() method. - * @param {CanvasRenderingContext2D} context - The context2d instance - * @returns {boolean} true if the method succeeded, else false - */ - releaseContext: function() {}, - - /** - * Registers the specified listener on the given chart. - * @param {Chart} chart - Chart from which to listen for event - * @param {string} type - The ({@link IEvent}) type to listen for - * @param {function} listener - Receives a notification (an object that implements - * the {@link IEvent} interface) when an event of the specified type occurs. - */ - addEventListener: function() {}, - - /** - * Removes the specified listener previously registered with addEventListener. - * @param {Chart} chart - Chart from which to remove the listener - * @param {string} type - The ({@link IEvent}) type to remove - * @param {function} listener - The listener function to remove from the event target. - */ - removeEventListener: function() {} - -}, implementation); - -core_defaults._set('global', { - plugins: {} -}); - -/** - * The plugin service singleton - * @namespace Chart.plugins - * @since 2.1.0 - */ -var core_plugins = { - /** - * Globally registered plugins. - * @private - */ - _plugins: [], - - /** - * This identifier is used to invalidate the descriptors cache attached to each chart - * when a global plugin is registered or unregistered. In this case, the cache ID is - * incremented and descriptors are regenerated during following API calls. - * @private - */ - _cacheId: 0, - - /** - * Registers the given plugin(s) if not already registered. - * @param {IPlugin[]|IPlugin} plugins plugin instance(s). - */ - register: function(plugins) { - var p = this._plugins; - ([]).concat(plugins).forEach(function(plugin) { - if (p.indexOf(plugin) === -1) { - p.push(plugin); - } - }); - - this._cacheId++; - }, - - /** - * Unregisters the given plugin(s) only if registered. - * @param {IPlugin[]|IPlugin} plugins plugin instance(s). - */ - unregister: function(plugins) { - var p = this._plugins; - ([]).concat(plugins).forEach(function(plugin) { - var idx = p.indexOf(plugin); - if (idx !== -1) { - p.splice(idx, 1); - } - }); - - this._cacheId++; - }, - - /** - * Remove all registered plugins. - * @since 2.1.5 - */ - clear: function() { - this._plugins = []; - this._cacheId++; - }, - - /** - * Returns the number of registered plugins? - * @returns {number} - * @since 2.1.5 - */ - count: function() { - return this._plugins.length; - }, - - /** - * Returns all registered plugin instances. - * @returns {IPlugin[]} array of plugin objects. - * @since 2.1.5 - */ - getAll: function() { - return this._plugins; - }, - - /** - * Calls enabled plugins for `chart` on the specified hook and with the given args. - * This method immediately returns as soon as a plugin explicitly returns false. The - * returned value can be used, for instance, to interrupt the current action. - * @param {Chart} chart - The chart instance for which plugins should be called. - * @param {string} hook - The name of the plugin method to call (e.g. 'beforeUpdate'). - * @param {Array} [args] - Extra arguments to apply to the hook call. - * @returns {boolean} false if any of the plugins return false, else returns true. - */ - notify: function(chart, hook, args) { - var descriptors = this.descriptors(chart); - var ilen = descriptors.length; - var i, descriptor, plugin, params, method; - - for (i = 0; i < ilen; ++i) { - descriptor = descriptors[i]; - plugin = descriptor.plugin; - method = plugin[hook]; - if (typeof method === 'function') { - params = [chart].concat(args || []); - params.push(descriptor.options); - if (method.apply(plugin, params) === false) { - return false; - } - } - } - - return true; - }, - - /** - * Returns descriptors of enabled plugins for the given chart. - * @returns {object[]} [{ plugin, options }] - * @private - */ - descriptors: function(chart) { - var cache = chart.$plugins || (chart.$plugins = {}); - if (cache.id === this._cacheId) { - return cache.descriptors; - } - - var plugins = []; - var descriptors = []; - var config = (chart && chart.config) || {}; - var options = (config.options && config.options.plugins) || {}; - - this._plugins.concat(config.plugins || []).forEach(function(plugin) { - var idx = plugins.indexOf(plugin); - if (idx !== -1) { - return; - } - - var id = plugin.id; - var opts = options[id]; - if (opts === false) { - return; - } - - if (opts === true) { - opts = helpers$1.clone(core_defaults.global.plugins[id]); - } - - plugins.push(plugin); - descriptors.push({ - plugin: plugin, - options: opts || {} - }); - }); - - cache.descriptors = descriptors; - cache.id = this._cacheId; - return descriptors; - }, - - /** - * Invalidates cache for the given chart: descriptors hold a reference on plugin option, - * but in some cases, this reference can be changed by the user when updating options. - * https://github.com/chartjs/Chart.js/issues/5111#issuecomment-355934167 - * @private - */ - _invalidate: function(chart) { - delete chart.$plugins; - } -}; - -var core_scaleService = { - // Scale registration object. Extensions can register new scale types (such as log or DB scales) and then - // use the new chart options to grab the correct scale - constructors: {}, - // Use a registration function so that we can move to an ES6 map when we no longer need to support - // old browsers - - // Scale config defaults - defaults: {}, - registerScaleType: function(type, scaleConstructor, scaleDefaults) { - this.constructors[type] = scaleConstructor; - this.defaults[type] = helpers$1.clone(scaleDefaults); - }, - getScaleConstructor: function(type) { - return this.constructors.hasOwnProperty(type) ? this.constructors[type] : undefined; - }, - getScaleDefaults: function(type) { - // Return the scale defaults merged with the global settings so that we always use the latest ones - return this.defaults.hasOwnProperty(type) ? helpers$1.merge({}, [core_defaults.scale, this.defaults[type]]) : {}; - }, - updateScaleDefaults: function(type, additions) { - var me = this; - if (me.defaults.hasOwnProperty(type)) { - me.defaults[type] = helpers$1.extend(me.defaults[type], additions); - } - }, - addScalesToLayout: function(chart) { - // Adds each scale to the chart.boxes array to be sized accordingly - helpers$1.each(chart.scales, function(scale) { - // Set ILayoutItem parameters for backwards compatibility - scale.fullWidth = scale.options.fullWidth; - scale.position = scale.options.position; - scale.weight = scale.options.weight; - core_layouts.addBox(chart, scale); - }); - } -}; - -var valueOrDefault$7 = helpers$1.valueOrDefault; - -core_defaults._set('global', { - tooltips: { - enabled: true, - custom: null, - mode: 'nearest', - position: 'average', - intersect: true, - backgroundColor: 'rgba(0,0,0,0.8)', - titleFontStyle: 'bold', - titleSpacing: 2, - titleMarginBottom: 6, - titleFontColor: '#fff', - titleAlign: 'left', - bodySpacing: 2, - bodyFontColor: '#fff', - bodyAlign: 'left', - footerFontStyle: 'bold', - footerSpacing: 2, - footerMarginTop: 6, - footerFontColor: '#fff', - footerAlign: 'left', - yPadding: 6, - xPadding: 6, - caretPadding: 2, - caretSize: 5, - cornerRadius: 6, - multiKeyBackground: '#fff', - displayColors: true, - borderColor: 'rgba(0,0,0,0)', - borderWidth: 0, - callbacks: { - // Args are: (tooltipItems, data) - beforeTitle: helpers$1.noop, - title: function(tooltipItems, data) { - var title = ''; - var labels = data.labels; - var labelCount = labels ? labels.length : 0; - - if (tooltipItems.length > 0) { - var item = tooltipItems[0]; - if (item.label) { - title = item.label; - } else if (item.xLabel) { - title = item.xLabel; - } else if (labelCount > 0 && item.index < labelCount) { - title = labels[item.index]; - } - } - - return title; - }, - afterTitle: helpers$1.noop, - - // Args are: (tooltipItems, data) - beforeBody: helpers$1.noop, - - // Args are: (tooltipItem, data) - beforeLabel: helpers$1.noop, - label: function(tooltipItem, data) { - var label = data.datasets[tooltipItem.datasetIndex].label || ''; - - if (label) { - label += ': '; - } - if (!helpers$1.isNullOrUndef(tooltipItem.value)) { - label += tooltipItem.value; - } else { - label += tooltipItem.yLabel; - } - return label; - }, - labelColor: function(tooltipItem, chart) { - var meta = chart.getDatasetMeta(tooltipItem.datasetIndex); - var activeElement = meta.data[tooltipItem.index]; - var view = activeElement._view; - return { - borderColor: view.borderColor, - backgroundColor: view.backgroundColor - }; - }, - labelTextColor: function() { - return this._options.bodyFontColor; - }, - afterLabel: helpers$1.noop, - - // Args are: (tooltipItems, data) - afterBody: helpers$1.noop, - - // Args are: (tooltipItems, data) - beforeFooter: helpers$1.noop, - footer: helpers$1.noop, - afterFooter: helpers$1.noop - } - } -}); - -var positioners = { - /** - * Average mode places the tooltip at the average position of the elements shown - * @function Chart.Tooltip.positioners.average - * @param elements {ChartElement[]} the elements being displayed in the tooltip - * @returns {object} tooltip position - */ - average: function(elements) { - if (!elements.length) { - return false; - } - - var i, len; - var x = 0; - var y = 0; - var count = 0; - - for (i = 0, len = elements.length; i < len; ++i) { - var el = elements[i]; - if (el && el.hasValue()) { - var pos = el.tooltipPosition(); - x += pos.x; - y += pos.y; - ++count; - } - } - - return { - x: x / count, - y: y / count - }; - }, - - /** - * Gets the tooltip position nearest of the item nearest to the event position - * @function Chart.Tooltip.positioners.nearest - * @param elements {Chart.Element[]} the tooltip elements - * @param eventPosition {object} the position of the event in canvas coordinates - * @returns {object} the tooltip position - */ - nearest: function(elements, eventPosition) { - var x = eventPosition.x; - var y = eventPosition.y; - var minDistance = Number.POSITIVE_INFINITY; - var i, len, nearestElement; - - for (i = 0, len = elements.length; i < len; ++i) { - var el = elements[i]; - if (el && el.hasValue()) { - var center = el.getCenterPoint(); - var d = helpers$1.distanceBetweenPoints(eventPosition, center); - - if (d < minDistance) { - minDistance = d; - nearestElement = el; - } - } - } - - if (nearestElement) { - var tp = nearestElement.tooltipPosition(); - x = tp.x; - y = tp.y; - } - - return { - x: x, - y: y - }; - } -}; - -// Helper to push or concat based on if the 2nd parameter is an array or not -function pushOrConcat(base, toPush) { - if (toPush) { - if (helpers$1.isArray(toPush)) { - // base = base.concat(toPush); - Array.prototype.push.apply(base, toPush); - } else { - base.push(toPush); - } - } - - return base; -} - -/** - * Returns array of strings split by newline - * @param {string} value - The value to split by newline. - * @returns {string[]} value if newline present - Returned from String split() method - * @function - */ -function splitNewlines(str) { - if ((typeof str === 'string' || str instanceof String) && str.indexOf('\n') > -1) { - return str.split('\n'); - } - return str; -} - - -/** - * Private helper to create a tooltip item model - * @param element - the chart element (point, arc, bar) to create the tooltip item for - * @return new tooltip item - */ -function createTooltipItem(element) { - var xScale = element._xScale; - var yScale = element._yScale || element._scale; // handle radar || polarArea charts - var index = element._index; - var datasetIndex = element._datasetIndex; - var controller = element._chart.getDatasetMeta(datasetIndex).controller; - var indexScale = controller._getIndexScale(); - var valueScale = controller._getValueScale(); - - return { - xLabel: xScale ? xScale.getLabelForIndex(index, datasetIndex) : '', - yLabel: yScale ? yScale.getLabelForIndex(index, datasetIndex) : '', - label: indexScale ? '' + indexScale.getLabelForIndex(index, datasetIndex) : '', - value: valueScale ? '' + valueScale.getLabelForIndex(index, datasetIndex) : '', - index: index, - datasetIndex: datasetIndex, - x: element._model.x, - y: element._model.y - }; -} - -/** - * Helper to get the reset model for the tooltip - * @param tooltipOpts {object} the tooltip options - */ -function getBaseModel(tooltipOpts) { - var globalDefaults = core_defaults.global; - - return { - // Positioning - xPadding: tooltipOpts.xPadding, - yPadding: tooltipOpts.yPadding, - xAlign: tooltipOpts.xAlign, - yAlign: tooltipOpts.yAlign, - - // Body - bodyFontColor: tooltipOpts.bodyFontColor, - _bodyFontFamily: valueOrDefault$7(tooltipOpts.bodyFontFamily, globalDefaults.defaultFontFamily), - _bodyFontStyle: valueOrDefault$7(tooltipOpts.bodyFontStyle, globalDefaults.defaultFontStyle), - _bodyAlign: tooltipOpts.bodyAlign, - bodyFontSize: valueOrDefault$7(tooltipOpts.bodyFontSize, globalDefaults.defaultFontSize), - bodySpacing: tooltipOpts.bodySpacing, - - // Title - titleFontColor: tooltipOpts.titleFontColor, - _titleFontFamily: valueOrDefault$7(tooltipOpts.titleFontFamily, globalDefaults.defaultFontFamily), - _titleFontStyle: valueOrDefault$7(tooltipOpts.titleFontStyle, globalDefaults.defaultFontStyle), - titleFontSize: valueOrDefault$7(tooltipOpts.titleFontSize, globalDefaults.defaultFontSize), - _titleAlign: tooltipOpts.titleAlign, - titleSpacing: tooltipOpts.titleSpacing, - titleMarginBottom: tooltipOpts.titleMarginBottom, - - // Footer - footerFontColor: tooltipOpts.footerFontColor, - _footerFontFamily: valueOrDefault$7(tooltipOpts.footerFontFamily, globalDefaults.defaultFontFamily), - _footerFontStyle: valueOrDefault$7(tooltipOpts.footerFontStyle, globalDefaults.defaultFontStyle), - footerFontSize: valueOrDefault$7(tooltipOpts.footerFontSize, globalDefaults.defaultFontSize), - _footerAlign: tooltipOpts.footerAlign, - footerSpacing: tooltipOpts.footerSpacing, - footerMarginTop: tooltipOpts.footerMarginTop, - - // Appearance - caretSize: tooltipOpts.caretSize, - cornerRadius: tooltipOpts.cornerRadius, - backgroundColor: tooltipOpts.backgroundColor, - opacity: 0, - legendColorBackground: tooltipOpts.multiKeyBackground, - displayColors: tooltipOpts.displayColors, - borderColor: tooltipOpts.borderColor, - borderWidth: tooltipOpts.borderWidth - }; -} - -/** - * Get the size of the tooltip - */ -function getTooltipSize(tooltip, model) { - var ctx = tooltip._chart.ctx; - - var height = model.yPadding * 2; // Tooltip Padding - var width = 0; - - // Count of all lines in the body - var body = model.body; - var combinedBodyLength = body.reduce(function(count, bodyItem) { - return count + bodyItem.before.length + bodyItem.lines.length + bodyItem.after.length; - }, 0); - combinedBodyLength += model.beforeBody.length + model.afterBody.length; - - var titleLineCount = model.title.length; - var footerLineCount = model.footer.length; - var titleFontSize = model.titleFontSize; - var bodyFontSize = model.bodyFontSize; - var footerFontSize = model.footerFontSize; - - height += titleLineCount * titleFontSize; // Title Lines - height += titleLineCount ? (titleLineCount - 1) * model.titleSpacing : 0; // Title Line Spacing - height += titleLineCount ? model.titleMarginBottom : 0; // Title's bottom Margin - height += combinedBodyLength * bodyFontSize; // Body Lines - height += combinedBodyLength ? (combinedBodyLength - 1) * model.bodySpacing : 0; // Body Line Spacing - height += footerLineCount ? model.footerMarginTop : 0; // Footer Margin - height += footerLineCount * (footerFontSize); // Footer Lines - height += footerLineCount ? (footerLineCount - 1) * model.footerSpacing : 0; // Footer Line Spacing - - // Title width - var widthPadding = 0; - var maxLineWidth = function(line) { - width = Math.max(width, ctx.measureText(line).width + widthPadding); - }; - - ctx.font = helpers$1.fontString(titleFontSize, model._titleFontStyle, model._titleFontFamily); - helpers$1.each(model.title, maxLineWidth); - - // Body width - ctx.font = helpers$1.fontString(bodyFontSize, model._bodyFontStyle, model._bodyFontFamily); - helpers$1.each(model.beforeBody.concat(model.afterBody), maxLineWidth); - - // Body lines may include some extra width due to the color box - widthPadding = model.displayColors ? (bodyFontSize + 2) : 0; - helpers$1.each(body, function(bodyItem) { - helpers$1.each(bodyItem.before, maxLineWidth); - helpers$1.each(bodyItem.lines, maxLineWidth); - helpers$1.each(bodyItem.after, maxLineWidth); - }); - - // Reset back to 0 - widthPadding = 0; - - // Footer width - ctx.font = helpers$1.fontString(footerFontSize, model._footerFontStyle, model._footerFontFamily); - helpers$1.each(model.footer, maxLineWidth); - - // Add padding - width += 2 * model.xPadding; - - return { - width: width, - height: height - }; -} - -/** - * Helper to get the alignment of a tooltip given the size - */ -function determineAlignment(tooltip, size) { - var model = tooltip._model; - var chart = tooltip._chart; - var chartArea = tooltip._chart.chartArea; - var xAlign = 'center'; - var yAlign = 'center'; - - if (model.y < size.height) { - yAlign = 'top'; - } else if (model.y > (chart.height - size.height)) { - yAlign = 'bottom'; - } - - var lf, rf; // functions to determine left, right alignment - var olf, orf; // functions to determine if left/right alignment causes tooltip to go outside chart - var yf; // function to get the y alignment if the tooltip goes outside of the left or right edges - var midX = (chartArea.left + chartArea.right) / 2; - var midY = (chartArea.top + chartArea.bottom) / 2; - - if (yAlign === 'center') { - lf = function(x) { - return x <= midX; - }; - rf = function(x) { - return x > midX; - }; - } else { - lf = function(x) { - return x <= (size.width / 2); - }; - rf = function(x) { - return x >= (chart.width - (size.width / 2)); - }; - } - - olf = function(x) { - return x + size.width + model.caretSize + model.caretPadding > chart.width; - }; - orf = function(x) { - return x - size.width - model.caretSize - model.caretPadding < 0; - }; - yf = function(y) { - return y <= midY ? 'top' : 'bottom'; - }; - - if (lf(model.x)) { - xAlign = 'left'; - - // Is tooltip too wide and goes over the right side of the chart.? - if (olf(model.x)) { - xAlign = 'center'; - yAlign = yf(model.y); - } - } else if (rf(model.x)) { - xAlign = 'right'; - - // Is tooltip too wide and goes outside left edge of canvas? - if (orf(model.x)) { - xAlign = 'center'; - yAlign = yf(model.y); - } - } - - var opts = tooltip._options; - return { - xAlign: opts.xAlign ? opts.xAlign : xAlign, - yAlign: opts.yAlign ? opts.yAlign : yAlign - }; -} - -/** - * Helper to get the location a tooltip needs to be placed at given the initial position (via the vm) and the size and alignment - */ -function getBackgroundPoint(vm, size, alignment, chart) { - // Background Position - var x = vm.x; - var y = vm.y; - - var caretSize = vm.caretSize; - var caretPadding = vm.caretPadding; - var cornerRadius = vm.cornerRadius; - var xAlign = alignment.xAlign; - var yAlign = alignment.yAlign; - var paddingAndSize = caretSize + caretPadding; - var radiusAndPadding = cornerRadius + caretPadding; - - if (xAlign === 'right') { - x -= size.width; - } else if (xAlign === 'center') { - x -= (size.width / 2); - if (x + size.width > chart.width) { - x = chart.width - size.width; - } - if (x < 0) { - x = 0; - } - } - - if (yAlign === 'top') { - y += paddingAndSize; - } else if (yAlign === 'bottom') { - y -= size.height + paddingAndSize; - } else { - y -= (size.height / 2); - } - - if (yAlign === 'center') { - if (xAlign === 'left') { - x += paddingAndSize; - } else if (xAlign === 'right') { - x -= paddingAndSize; - } - } else if (xAlign === 'left') { - x -= radiusAndPadding; - } else if (xAlign === 'right') { - x += radiusAndPadding; - } - - return { - x: x, - y: y - }; -} - -function getAlignedX(vm, align) { - return align === 'center' - ? vm.x + vm.width / 2 - : align === 'right' - ? vm.x + vm.width - vm.xPadding - : vm.x + vm.xPadding; -} - -/** - * Helper to build before and after body lines - */ -function getBeforeAfterBodyLines(callback) { - return pushOrConcat([], splitNewlines(callback)); -} - -var exports$3 = core_element.extend({ - initialize: function() { - this._model = getBaseModel(this._options); - this._lastActive = []; - }, - - // Get the title - // Args are: (tooltipItem, data) - getTitle: function() { - var me = this; - var opts = me._options; - var callbacks = opts.callbacks; - - var beforeTitle = callbacks.beforeTitle.apply(me, arguments); - var title = callbacks.title.apply(me, arguments); - var afterTitle = callbacks.afterTitle.apply(me, arguments); - - var lines = []; - lines = pushOrConcat(lines, splitNewlines(beforeTitle)); - lines = pushOrConcat(lines, splitNewlines(title)); - lines = pushOrConcat(lines, splitNewlines(afterTitle)); - - return lines; - }, - - // Args are: (tooltipItem, data) - getBeforeBody: function() { - return getBeforeAfterBodyLines(this._options.callbacks.beforeBody.apply(this, arguments)); - }, - - // Args are: (tooltipItem, data) - getBody: function(tooltipItems, data) { - var me = this; - var callbacks = me._options.callbacks; - var bodyItems = []; - - helpers$1.each(tooltipItems, function(tooltipItem) { - var bodyItem = { - before: [], - lines: [], - after: [] - }; - pushOrConcat(bodyItem.before, splitNewlines(callbacks.beforeLabel.call(me, tooltipItem, data))); - pushOrConcat(bodyItem.lines, callbacks.label.call(me, tooltipItem, data)); - pushOrConcat(bodyItem.after, splitNewlines(callbacks.afterLabel.call(me, tooltipItem, data))); - - bodyItems.push(bodyItem); - }); - - return bodyItems; - }, - - // Args are: (tooltipItem, data) - getAfterBody: function() { - return getBeforeAfterBodyLines(this._options.callbacks.afterBody.apply(this, arguments)); - }, - - // Get the footer and beforeFooter and afterFooter lines - // Args are: (tooltipItem, data) - getFooter: function() { - var me = this; - var callbacks = me._options.callbacks; - - var beforeFooter = callbacks.beforeFooter.apply(me, arguments); - var footer = callbacks.footer.apply(me, arguments); - var afterFooter = callbacks.afterFooter.apply(me, arguments); - - var lines = []; - lines = pushOrConcat(lines, splitNewlines(beforeFooter)); - lines = pushOrConcat(lines, splitNewlines(footer)); - lines = pushOrConcat(lines, splitNewlines(afterFooter)); - - return lines; - }, - - update: function(changed) { - var me = this; - var opts = me._options; - - // Need to regenerate the model because its faster than using extend and it is necessary due to the optimization in Chart.Element.transition - // that does _view = _model if ease === 1. This causes the 2nd tooltip update to set properties in both the view and model at the same time - // which breaks any animations. - var existingModel = me._model; - var model = me._model = getBaseModel(opts); - var active = me._active; - - var data = me._data; - - // In the case where active.length === 0 we need to keep these at existing values for good animations - var alignment = { - xAlign: existingModel.xAlign, - yAlign: existingModel.yAlign - }; - var backgroundPoint = { - x: existingModel.x, - y: existingModel.y - }; - var tooltipSize = { - width: existingModel.width, - height: existingModel.height - }; - var tooltipPosition = { - x: existingModel.caretX, - y: existingModel.caretY - }; - - var i, len; - - if (active.length) { - model.opacity = 1; - - var labelColors = []; - var labelTextColors = []; - tooltipPosition = positioners[opts.position].call(me, active, me._eventPosition); - - var tooltipItems = []; - for (i = 0, len = active.length; i < len; ++i) { - tooltipItems.push(createTooltipItem(active[i])); - } - - // If the user provided a filter function, use it to modify the tooltip items - if (opts.filter) { - tooltipItems = tooltipItems.filter(function(a) { - return opts.filter(a, data); - }); - } - - // If the user provided a sorting function, use it to modify the tooltip items - if (opts.itemSort) { - tooltipItems = tooltipItems.sort(function(a, b) { - return opts.itemSort(a, b, data); - }); - } - - // Determine colors for boxes - helpers$1.each(tooltipItems, function(tooltipItem) { - labelColors.push(opts.callbacks.labelColor.call(me, tooltipItem, me._chart)); - labelTextColors.push(opts.callbacks.labelTextColor.call(me, tooltipItem, me._chart)); - }); - - - // Build the Text Lines - model.title = me.getTitle(tooltipItems, data); - model.beforeBody = me.getBeforeBody(tooltipItems, data); - model.body = me.getBody(tooltipItems, data); - model.afterBody = me.getAfterBody(tooltipItems, data); - model.footer = me.getFooter(tooltipItems, data); - - // Initial positioning and colors - model.x = tooltipPosition.x; - model.y = tooltipPosition.y; - model.caretPadding = opts.caretPadding; - model.labelColors = labelColors; - model.labelTextColors = labelTextColors; - - // data points - model.dataPoints = tooltipItems; - - // We need to determine alignment of the tooltip - tooltipSize = getTooltipSize(this, model); - alignment = determineAlignment(this, tooltipSize); - // Final Size and Position - backgroundPoint = getBackgroundPoint(model, tooltipSize, alignment, me._chart); - } else { - model.opacity = 0; - } - - model.xAlign = alignment.xAlign; - model.yAlign = alignment.yAlign; - model.x = backgroundPoint.x; - model.y = backgroundPoint.y; - model.width = tooltipSize.width; - model.height = tooltipSize.height; - - // Point where the caret on the tooltip points to - model.caretX = tooltipPosition.x; - model.caretY = tooltipPosition.y; - - me._model = model; - - if (changed && opts.custom) { - opts.custom.call(me, model); - } - - return me; - }, - - drawCaret: function(tooltipPoint, size) { - var ctx = this._chart.ctx; - var vm = this._view; - var caretPosition = this.getCaretPosition(tooltipPoint, size, vm); - - ctx.lineTo(caretPosition.x1, caretPosition.y1); - ctx.lineTo(caretPosition.x2, caretPosition.y2); - ctx.lineTo(caretPosition.x3, caretPosition.y3); - }, - getCaretPosition: function(tooltipPoint, size, vm) { - var x1, x2, x3, y1, y2, y3; - var caretSize = vm.caretSize; - var cornerRadius = vm.cornerRadius; - var xAlign = vm.xAlign; - var yAlign = vm.yAlign; - var ptX = tooltipPoint.x; - var ptY = tooltipPoint.y; - var width = size.width; - var height = size.height; - - if (yAlign === 'center') { - y2 = ptY + (height / 2); - - if (xAlign === 'left') { - x1 = ptX; - x2 = x1 - caretSize; - x3 = x1; - - y1 = y2 + caretSize; - y3 = y2 - caretSize; - } else { - x1 = ptX + width; - x2 = x1 + caretSize; - x3 = x1; - - y1 = y2 - caretSize; - y3 = y2 + caretSize; - } - } else { - if (xAlign === 'left') { - x2 = ptX + cornerRadius + (caretSize); - x1 = x2 - caretSize; - x3 = x2 + caretSize; - } else if (xAlign === 'right') { - x2 = ptX + width - cornerRadius - caretSize; - x1 = x2 - caretSize; - x3 = x2 + caretSize; - } else { - x2 = vm.caretX; - x1 = x2 - caretSize; - x3 = x2 + caretSize; - } - if (yAlign === 'top') { - y1 = ptY; - y2 = y1 - caretSize; - y3 = y1; - } else { - y1 = ptY + height; - y2 = y1 + caretSize; - y3 = y1; - // invert drawing order - var tmp = x3; - x3 = x1; - x1 = tmp; - } - } - return {x1: x1, x2: x2, x3: x3, y1: y1, y2: y2, y3: y3}; - }, - - drawTitle: function(pt, vm, ctx) { - var title = vm.title; - - if (title.length) { - pt.x = getAlignedX(vm, vm._titleAlign); - - ctx.textAlign = vm._titleAlign; - ctx.textBaseline = 'top'; - - var titleFontSize = vm.titleFontSize; - var titleSpacing = vm.titleSpacing; - - ctx.fillStyle = vm.titleFontColor; - ctx.font = helpers$1.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily); - - var i, len; - for (i = 0, len = title.length; i < len; ++i) { - ctx.fillText(title[i], pt.x, pt.y); - pt.y += titleFontSize + titleSpacing; // Line Height and spacing - - if (i + 1 === title.length) { - pt.y += vm.titleMarginBottom - titleSpacing; // If Last, add margin, remove spacing - } - } - } - }, - - drawBody: function(pt, vm, ctx) { - var bodyFontSize = vm.bodyFontSize; - var bodySpacing = vm.bodySpacing; - var bodyAlign = vm._bodyAlign; - var body = vm.body; - var drawColorBoxes = vm.displayColors; - var labelColors = vm.labelColors; - var xLinePadding = 0; - var colorX = drawColorBoxes ? getAlignedX(vm, 'left') : 0; - var textColor; - - ctx.textAlign = bodyAlign; - ctx.textBaseline = 'top'; - ctx.font = helpers$1.fontString(bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily); - - pt.x = getAlignedX(vm, bodyAlign); - - // Before Body - var fillLineOfText = function(line) { - ctx.fillText(line, pt.x + xLinePadding, pt.y); - pt.y += bodyFontSize + bodySpacing; - }; - - // Before body lines - ctx.fillStyle = vm.bodyFontColor; - helpers$1.each(vm.beforeBody, fillLineOfText); - - xLinePadding = drawColorBoxes && bodyAlign !== 'right' - ? bodyAlign === 'center' ? (bodyFontSize / 2 + 1) : (bodyFontSize + 2) - : 0; - - // Draw body lines now - helpers$1.each(body, function(bodyItem, i) { - textColor = vm.labelTextColors[i]; - ctx.fillStyle = textColor; - helpers$1.each(bodyItem.before, fillLineOfText); - - helpers$1.each(bodyItem.lines, function(line) { - // Draw Legend-like boxes if needed - if (drawColorBoxes) { - // Fill a white rect so that colours merge nicely if the opacity is < 1 - ctx.fillStyle = vm.legendColorBackground; - ctx.fillRect(colorX, pt.y, bodyFontSize, bodyFontSize); - - // Border - ctx.lineWidth = 1; - ctx.strokeStyle = labelColors[i].borderColor; - ctx.strokeRect(colorX, pt.y, bodyFontSize, bodyFontSize); - - // Inner square - ctx.fillStyle = labelColors[i].backgroundColor; - ctx.fillRect(colorX + 1, pt.y + 1, bodyFontSize - 2, bodyFontSize - 2); - ctx.fillStyle = textColor; - } - - fillLineOfText(line); - }); - - helpers$1.each(bodyItem.after, fillLineOfText); - }); - - // Reset back to 0 for after body - xLinePadding = 0; - - // After body lines - helpers$1.each(vm.afterBody, fillLineOfText); - pt.y -= bodySpacing; // Remove last body spacing - }, - - drawFooter: function(pt, vm, ctx) { - var footer = vm.footer; - - if (footer.length) { - pt.x = getAlignedX(vm, vm._footerAlign); - pt.y += vm.footerMarginTop; - - ctx.textAlign = vm._footerAlign; - ctx.textBaseline = 'top'; - - ctx.fillStyle = vm.footerFontColor; - ctx.font = helpers$1.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily); - - helpers$1.each(footer, function(line) { - ctx.fillText(line, pt.x, pt.y); - pt.y += vm.footerFontSize + vm.footerSpacing; - }); - } - }, - - drawBackground: function(pt, vm, ctx, tooltipSize) { - ctx.fillStyle = vm.backgroundColor; - ctx.strokeStyle = vm.borderColor; - ctx.lineWidth = vm.borderWidth; - var xAlign = vm.xAlign; - var yAlign = vm.yAlign; - var x = pt.x; - var y = pt.y; - var width = tooltipSize.width; - var height = tooltipSize.height; - var radius = vm.cornerRadius; - - ctx.beginPath(); - ctx.moveTo(x + radius, y); - if (yAlign === 'top') { - this.drawCaret(pt, tooltipSize); - } - ctx.lineTo(x + width - radius, y); - ctx.quadraticCurveTo(x + width, y, x + width, y + radius); - if (yAlign === 'center' && xAlign === 'right') { - this.drawCaret(pt, tooltipSize); - } - ctx.lineTo(x + width, y + height - radius); - ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); - if (yAlign === 'bottom') { - this.drawCaret(pt, tooltipSize); - } - ctx.lineTo(x + radius, y + height); - ctx.quadraticCurveTo(x, y + height, x, y + height - radius); - if (yAlign === 'center' && xAlign === 'left') { - this.drawCaret(pt, tooltipSize); - } - ctx.lineTo(x, y + radius); - ctx.quadraticCurveTo(x, y, x + radius, y); - ctx.closePath(); - - ctx.fill(); - - if (vm.borderWidth > 0) { - ctx.stroke(); - } - }, - - draw: function() { - var ctx = this._chart.ctx; - var vm = this._view; - - if (vm.opacity === 0) { - return; - } - - var tooltipSize = { - width: vm.width, - height: vm.height - }; - var pt = { - x: vm.x, - y: vm.y - }; - - // IE11/Edge does not like very small opacities, so snap to 0 - var opacity = Math.abs(vm.opacity < 1e-3) ? 0 : vm.opacity; - - // Truthy/falsey value for empty tooltip - var hasTooltipContent = vm.title.length || vm.beforeBody.length || vm.body.length || vm.afterBody.length || vm.footer.length; - - if (this._options.enabled && hasTooltipContent) { - ctx.save(); - ctx.globalAlpha = opacity; - - // Draw Background - this.drawBackground(pt, vm, ctx, tooltipSize); - - // Draw Title, Body, and Footer - pt.y += vm.yPadding; - - // Titles - this.drawTitle(pt, vm, ctx); - - // Body - this.drawBody(pt, vm, ctx); - - // Footer - this.drawFooter(pt, vm, ctx); - - ctx.restore(); - } - }, - - /** - * Handle an event - * @private - * @param {IEvent} event - The event to handle - * @returns {boolean} true if the tooltip changed - */ - handleEvent: function(e) { - var me = this; - var options = me._options; - var changed = false; - - me._lastActive = me._lastActive || []; - - // Find Active Elements for tooltips - if (e.type === 'mouseout') { - me._active = []; - } else { - me._active = me._chart.getElementsAtEventForMode(e, options.mode, options); - } - - // Remember Last Actives - changed = !helpers$1.arrayEquals(me._active, me._lastActive); - - // Only handle target event on tooltip change - if (changed) { - me._lastActive = me._active; - - if (options.enabled || options.custom) { - me._eventPosition = { - x: e.x, - y: e.y - }; - - me.update(true); - me.pivot(); - } - } - - return changed; - } -}); - -/** - * @namespace Chart.Tooltip.positioners - */ -var positioners_1 = positioners; - -var core_tooltip = exports$3; -core_tooltip.positioners = positioners_1; - -var valueOrDefault$8 = helpers$1.valueOrDefault; - -core_defaults._set('global', { - elements: {}, - events: [ - 'mousemove', - 'mouseout', - 'click', - 'touchstart', - 'touchmove' - ], - hover: { - onHover: null, - mode: 'nearest', - intersect: true, - animationDuration: 400 - }, - onClick: null, - maintainAspectRatio: true, - responsive: true, - responsiveAnimationDuration: 0 -}); - -/** - * Recursively merge the given config objects representing the `scales` option - * by incorporating scale defaults in `xAxes` and `yAxes` array items, then - * returns a deep copy of the result, thus doesn't alter inputs. - */ -function mergeScaleConfig(/* config objects ... */) { - return helpers$1.merge({}, [].slice.call(arguments), { - merger: function(key, target, source, options) { - if (key === 'xAxes' || key === 'yAxes') { - var slen = source[key].length; - var i, type, scale; - - if (!target[key]) { - target[key] = []; - } - - for (i = 0; i < slen; ++i) { - scale = source[key][i]; - type = valueOrDefault$8(scale.type, key === 'xAxes' ? 'category' : 'linear'); - - if (i >= target[key].length) { - target[key].push({}); - } - - if (!target[key][i].type || (scale.type && scale.type !== target[key][i].type)) { - // new/untyped scale or type changed: let's apply the new defaults - // then merge source scale to correctly overwrite the defaults. - helpers$1.merge(target[key][i], [core_scaleService.getScaleDefaults(type), scale]); - } else { - // scales type are the same - helpers$1.merge(target[key][i], scale); - } - } - } else { - helpers$1._merger(key, target, source, options); - } - } - }); -} - -/** - * Recursively merge the given config objects as the root options by handling - * default scale options for the `scales` and `scale` properties, then returns - * a deep copy of the result, thus doesn't alter inputs. - */ -function mergeConfig(/* config objects ... */) { - return helpers$1.merge({}, [].slice.call(arguments), { - merger: function(key, target, source, options) { - var tval = target[key] || {}; - var sval = source[key]; - - if (key === 'scales') { - // scale config merging is complex. Add our own function here for that - target[key] = mergeScaleConfig(tval, sval); - } else if (key === 'scale') { - // used in polar area & radar charts since there is only one scale - target[key] = helpers$1.merge(tval, [core_scaleService.getScaleDefaults(sval.type), sval]); - } else { - helpers$1._merger(key, target, source, options); - } - } - }); -} - -function initConfig(config) { - config = config || {}; - - // Do NOT use mergeConfig for the data object because this method merges arrays - // and so would change references to labels and datasets, preventing data updates. - var data = config.data = config.data || {}; - data.datasets = data.datasets || []; - data.labels = data.labels || []; - - config.options = mergeConfig( - core_defaults.global, - core_defaults[config.type], - config.options || {}); - - return config; -} - -function updateConfig(chart) { - var newOptions = chart.options; - - helpers$1.each(chart.scales, function(scale) { - core_layouts.removeBox(chart, scale); - }); - - newOptions = mergeConfig( - core_defaults.global, - core_defaults[chart.config.type], - newOptions); - - chart.options = chart.config.options = newOptions; - chart.ensureScalesHaveIDs(); - chart.buildOrUpdateScales(); - - // Tooltip - chart.tooltip._options = newOptions.tooltips; - chart.tooltip.initialize(); -} - -function positionIsHorizontal(position) { - return position === 'top' || position === 'bottom'; -} - -var Chart = function(item, config) { - this.construct(item, config); - return this; -}; - -helpers$1.extend(Chart.prototype, /** @lends Chart */ { - /** - * @private - */ - construct: function(item, config) { - var me = this; - - config = initConfig(config); - - var context = platform.acquireContext(item, config); - var canvas = context && context.canvas; - var height = canvas && canvas.height; - var width = canvas && canvas.width; - - me.id = helpers$1.uid(); - me.ctx = context; - me.canvas = canvas; - me.config = config; - me.width = width; - me.height = height; - me.aspectRatio = height ? width / height : null; - me.options = config.options; - me._bufferedRender = false; - - /** - * Provided for backward compatibility, Chart and Chart.Controller have been merged, - * the "instance" still need to be defined since it might be called from plugins. - * @prop Chart#chart - * @deprecated since version 2.6.0 - * @todo remove at version 3 - * @private - */ - me.chart = me; - me.controller = me; // chart.chart.controller #inception - - // Add the chart instance to the global namespace - Chart.instances[me.id] = me; - - // Define alias to the config data: `chart.data === chart.config.data` - Object.defineProperty(me, 'data', { - get: function() { - return me.config.data; - }, - set: function(value) { - me.config.data = value; - } - }); - - if (!context || !canvas) { - // The given item is not a compatible context2d element, let's return before finalizing - // the chart initialization but after setting basic chart / controller properties that - // can help to figure out that the chart is not valid (e.g chart.canvas !== null); - // https://github.com/chartjs/Chart.js/issues/2807 - console.error("Failed to create chart: can't acquire context from the given item"); - return; - } - - me.initialize(); - me.update(); - }, - - /** - * @private - */ - initialize: function() { - var me = this; - - // Before init plugin notification - core_plugins.notify(me, 'beforeInit'); - - helpers$1.retinaScale(me, me.options.devicePixelRatio); - - me.bindEvents(); - - if (me.options.responsive) { - // Initial resize before chart draws (must be silent to preserve initial animations). - me.resize(true); - } - - // Make sure scales have IDs and are built before we build any controllers. - me.ensureScalesHaveIDs(); - me.buildOrUpdateScales(); - me.initToolTip(); - - // After init plugin notification - core_plugins.notify(me, 'afterInit'); - - return me; - }, - - clear: function() { - helpers$1.canvas.clear(this); - return this; - }, - - stop: function() { - // Stops any current animation loop occurring - core_animations.cancelAnimation(this); - return this; - }, - - resize: function(silent) { - var me = this; - var options = me.options; - var canvas = me.canvas; - var aspectRatio = (options.maintainAspectRatio && me.aspectRatio) || null; - - // the canvas render width and height will be casted to integers so make sure that - // the canvas display style uses the same integer values to avoid blurring effect. - - // Set to 0 instead of canvas.size because the size defaults to 300x150 if the element is collapsed - var newWidth = Math.max(0, Math.floor(helpers$1.getMaximumWidth(canvas))); - var newHeight = Math.max(0, Math.floor(aspectRatio ? newWidth / aspectRatio : helpers$1.getMaximumHeight(canvas))); - - if (me.width === newWidth && me.height === newHeight) { - return; - } - - canvas.width = me.width = newWidth; - canvas.height = me.height = newHeight; - canvas.style.width = newWidth + 'px'; - canvas.style.height = newHeight + 'px'; - - helpers$1.retinaScale(me, options.devicePixelRatio); - - if (!silent) { - // Notify any plugins about the resize - var newSize = {width: newWidth, height: newHeight}; - core_plugins.notify(me, 'resize', [newSize]); - - // Notify of resize - if (options.onResize) { - options.onResize(me, newSize); - } - - me.stop(); - me.update({ - duration: options.responsiveAnimationDuration - }); - } - }, - - ensureScalesHaveIDs: function() { - var options = this.options; - var scalesOptions = options.scales || {}; - var scaleOptions = options.scale; - - helpers$1.each(scalesOptions.xAxes, function(xAxisOptions, index) { - xAxisOptions.id = xAxisOptions.id || ('x-axis-' + index); - }); - - helpers$1.each(scalesOptions.yAxes, function(yAxisOptions, index) { - yAxisOptions.id = yAxisOptions.id || ('y-axis-' + index); - }); - - if (scaleOptions) { - scaleOptions.id = scaleOptions.id || 'scale'; - } - }, - - /** - * Builds a map of scale ID to scale object for future lookup. - */ - buildOrUpdateScales: function() { - var me = this; - var options = me.options; - var scales = me.scales || {}; - var items = []; - var updated = Object.keys(scales).reduce(function(obj, id) { - obj[id] = false; - return obj; - }, {}); - - if (options.scales) { - items = items.concat( - (options.scales.xAxes || []).map(function(xAxisOptions) { - return {options: xAxisOptions, dtype: 'category', dposition: 'bottom'}; - }), - (options.scales.yAxes || []).map(function(yAxisOptions) { - return {options: yAxisOptions, dtype: 'linear', dposition: 'left'}; - }) - ); - } - - if (options.scale) { - items.push({ - options: options.scale, - dtype: 'radialLinear', - isDefault: true, - dposition: 'chartArea' - }); - } - - helpers$1.each(items, function(item) { - var scaleOptions = item.options; - var id = scaleOptions.id; - var scaleType = valueOrDefault$8(scaleOptions.type, item.dtype); - - if (positionIsHorizontal(scaleOptions.position) !== positionIsHorizontal(item.dposition)) { - scaleOptions.position = item.dposition; - } - - updated[id] = true; - var scale = null; - if (id in scales && scales[id].type === scaleType) { - scale = scales[id]; - scale.options = scaleOptions; - scale.ctx = me.ctx; - scale.chart = me; - } else { - var scaleClass = core_scaleService.getScaleConstructor(scaleType); - if (!scaleClass) { - return; - } - scale = new scaleClass({ - id: id, - type: scaleType, - options: scaleOptions, - ctx: me.ctx, - chart: me - }); - scales[scale.id] = scale; - } - - scale.mergeTicksOptions(); - - // TODO(SB): I think we should be able to remove this custom case (options.scale) - // and consider it as a regular scale part of the "scales"" map only! This would - // make the logic easier and remove some useless? custom code. - if (item.isDefault) { - me.scale = scale; - } - }); - // clear up discarded scales - helpers$1.each(updated, function(hasUpdated, id) { - if (!hasUpdated) { - delete scales[id]; - } - }); - - me.scales = scales; - - core_scaleService.addScalesToLayout(this); - }, - - buildOrUpdateControllers: function() { - var me = this; - var newControllers = []; - - helpers$1.each(me.data.datasets, function(dataset, datasetIndex) { - var meta = me.getDatasetMeta(datasetIndex); - var type = dataset.type || me.config.type; - - if (meta.type && meta.type !== type) { - me.destroyDatasetMeta(datasetIndex); - meta = me.getDatasetMeta(datasetIndex); - } - meta.type = type; - - if (meta.controller) { - meta.controller.updateIndex(datasetIndex); - meta.controller.linkScales(); - } else { - var ControllerClass = controllers[meta.type]; - if (ControllerClass === undefined) { - throw new Error('"' + meta.type + '" is not a chart type.'); - } - - meta.controller = new ControllerClass(me, datasetIndex); - newControllers.push(meta.controller); - } - }, me); - - return newControllers; - }, - - /** - * Reset the elements of all datasets - * @private - */ - resetElements: function() { - var me = this; - helpers$1.each(me.data.datasets, function(dataset, datasetIndex) { - me.getDatasetMeta(datasetIndex).controller.reset(); - }, me); - }, - - /** - * Resets the chart back to it's state before the initial animation - */ - reset: function() { - this.resetElements(); - this.tooltip.initialize(); - }, - - update: function(config) { - var me = this; - - if (!config || typeof config !== 'object') { - // backwards compatibility - config = { - duration: config, - lazy: arguments[1] - }; - } - - updateConfig(me); - - // plugins options references might have change, let's invalidate the cache - // https://github.com/chartjs/Chart.js/issues/5111#issuecomment-355934167 - core_plugins._invalidate(me); - - if (core_plugins.notify(me, 'beforeUpdate') === false) { - return; - } - - // In case the entire data object changed - me.tooltip._data = me.data; - - // Make sure dataset controllers are updated and new controllers are reset - var newControllers = me.buildOrUpdateControllers(); - - // Make sure all dataset controllers have correct meta data counts - helpers$1.each(me.data.datasets, function(dataset, datasetIndex) { - me.getDatasetMeta(datasetIndex).controller.buildOrUpdateElements(); - }, me); - - me.updateLayout(); - - // Can only reset the new controllers after the scales have been updated - if (me.options.animation && me.options.animation.duration) { - helpers$1.each(newControllers, function(controller) { - controller.reset(); - }); - } - - me.updateDatasets(); - - // Need to reset tooltip in case it is displayed with elements that are removed - // after update. - me.tooltip.initialize(); - - // Last active contains items that were previously in the tooltip. - // When we reset the tooltip, we need to clear it - me.lastActive = []; - - // Do this before render so that any plugins that need final scale updates can use it - core_plugins.notify(me, 'afterUpdate'); - - if (me._bufferedRender) { - me._bufferedRequest = { - duration: config.duration, - easing: config.easing, - lazy: config.lazy - }; - } else { - me.render(config); - } - }, - - /** - * Updates the chart layout unless a plugin returns `false` to the `beforeLayout` - * hook, in which case, plugins will not be called on `afterLayout`. - * @private - */ - updateLayout: function() { - var me = this; - - if (core_plugins.notify(me, 'beforeLayout') === false) { - return; - } - - core_layouts.update(this, this.width, this.height); - - /** - * Provided for backward compatibility, use `afterLayout` instead. - * @method IPlugin#afterScaleUpdate - * @deprecated since version 2.5.0 - * @todo remove at version 3 - * @private - */ - core_plugins.notify(me, 'afterScaleUpdate'); - core_plugins.notify(me, 'afterLayout'); - }, - - /** - * Updates all datasets unless a plugin returns `false` to the `beforeDatasetsUpdate` - * hook, in which case, plugins will not be called on `afterDatasetsUpdate`. - * @private - */ - updateDatasets: function() { - var me = this; - - if (core_plugins.notify(me, 'beforeDatasetsUpdate') === false) { - return; - } - - for (var i = 0, ilen = me.data.datasets.length; i < ilen; ++i) { - me.updateDataset(i); - } - - core_plugins.notify(me, 'afterDatasetsUpdate'); - }, - - /** - * Updates dataset at index unless a plugin returns `false` to the `beforeDatasetUpdate` - * hook, in which case, plugins will not be called on `afterDatasetUpdate`. - * @private - */ - updateDataset: function(index) { - var me = this; - var meta = me.getDatasetMeta(index); - var args = { - meta: meta, - index: index - }; - - if (core_plugins.notify(me, 'beforeDatasetUpdate', [args]) === false) { - return; - } - - meta.controller.update(); - - core_plugins.notify(me, 'afterDatasetUpdate', [args]); - }, - - render: function(config) { - var me = this; - - if (!config || typeof config !== 'object') { - // backwards compatibility - config = { - duration: config, - lazy: arguments[1] - }; - } - - var animationOptions = me.options.animation; - var duration = valueOrDefault$8(config.duration, animationOptions && animationOptions.duration); - var lazy = config.lazy; - - if (core_plugins.notify(me, 'beforeRender') === false) { - return; - } - - var onComplete = function(animation) { - core_plugins.notify(me, 'afterRender'); - helpers$1.callback(animationOptions && animationOptions.onComplete, [animation], me); - }; - - if (animationOptions && duration) { - var animation = new core_animation({ - numSteps: duration / 16.66, // 60 fps - easing: config.easing || animationOptions.easing, - - render: function(chart, animationObject) { - var easingFunction = helpers$1.easing.effects[animationObject.easing]; - var currentStep = animationObject.currentStep; - var stepDecimal = currentStep / animationObject.numSteps; - - chart.draw(easingFunction(stepDecimal), stepDecimal, currentStep); - }, - - onAnimationProgress: animationOptions.onProgress, - onAnimationComplete: onComplete - }); - - core_animations.addAnimation(me, animation, duration, lazy); - } else { - me.draw(); - - // See https://github.com/chartjs/Chart.js/issues/3781 - onComplete(new core_animation({numSteps: 0, chart: me})); - } - - return me; - }, - - draw: function(easingValue) { - var me = this; - - me.clear(); - - if (helpers$1.isNullOrUndef(easingValue)) { - easingValue = 1; - } - - me.transition(easingValue); - - if (me.width <= 0 || me.height <= 0) { - return; - } - - if (core_plugins.notify(me, 'beforeDraw', [easingValue]) === false) { - return; - } - - // Draw all the scales - helpers$1.each(me.boxes, function(box) { - box.draw(me.chartArea); - }, me); - - me.drawDatasets(easingValue); - me._drawTooltip(easingValue); - - core_plugins.notify(me, 'afterDraw', [easingValue]); - }, - - /** - * @private - */ - transition: function(easingValue) { - var me = this; - - for (var i = 0, ilen = (me.data.datasets || []).length; i < ilen; ++i) { - if (me.isDatasetVisible(i)) { - me.getDatasetMeta(i).controller.transition(easingValue); - } - } - - me.tooltip.transition(easingValue); - }, - - /** - * Draws all datasets unless a plugin returns `false` to the `beforeDatasetsDraw` - * hook, in which case, plugins will not be called on `afterDatasetsDraw`. - * @private - */ - drawDatasets: function(easingValue) { - var me = this; - - if (core_plugins.notify(me, 'beforeDatasetsDraw', [easingValue]) === false) { - return; - } - - // Draw datasets reversed to support proper line stacking - for (var i = (me.data.datasets || []).length - 1; i >= 0; --i) { - if (me.isDatasetVisible(i)) { - me.drawDataset(i, easingValue); - } - } - - core_plugins.notify(me, 'afterDatasetsDraw', [easingValue]); - }, - - /** - * Draws dataset at index unless a plugin returns `false` to the `beforeDatasetDraw` - * hook, in which case, plugins will not be called on `afterDatasetDraw`. - * @private - */ - drawDataset: function(index, easingValue) { - var me = this; - var meta = me.getDatasetMeta(index); - var args = { - meta: meta, - index: index, - easingValue: easingValue - }; - - if (core_plugins.notify(me, 'beforeDatasetDraw', [args]) === false) { - return; - } - - meta.controller.draw(easingValue); - - core_plugins.notify(me, 'afterDatasetDraw', [args]); - }, - - /** - * Draws tooltip unless a plugin returns `false` to the `beforeTooltipDraw` - * hook, in which case, plugins will not be called on `afterTooltipDraw`. - * @private - */ - _drawTooltip: function(easingValue) { - var me = this; - var tooltip = me.tooltip; - var args = { - tooltip: tooltip, - easingValue: easingValue - }; - - if (core_plugins.notify(me, 'beforeTooltipDraw', [args]) === false) { - return; - } - - tooltip.draw(); - - core_plugins.notify(me, 'afterTooltipDraw', [args]); - }, - - /** - * Get the single element that was clicked on - * @return An object containing the dataset index and element index of the matching element. Also contains the rectangle that was draw - */ - getElementAtEvent: function(e) { - return core_interaction.modes.single(this, e); - }, - - getElementsAtEvent: function(e) { - return core_interaction.modes.label(this, e, {intersect: true}); - }, - - getElementsAtXAxis: function(e) { - return core_interaction.modes['x-axis'](this, e, {intersect: true}); - }, - - getElementsAtEventForMode: function(e, mode, options) { - var method = core_interaction.modes[mode]; - if (typeof method === 'function') { - return method(this, e, options); - } - - return []; - }, - - getDatasetAtEvent: function(e) { - return core_interaction.modes.dataset(this, e, {intersect: true}); - }, - - getDatasetMeta: function(datasetIndex) { - var me = this; - var dataset = me.data.datasets[datasetIndex]; - if (!dataset._meta) { - dataset._meta = {}; - } - - var meta = dataset._meta[me.id]; - if (!meta) { - meta = dataset._meta[me.id] = { - type: null, - data: [], - dataset: null, - controller: null, - hidden: null, // See isDatasetVisible() comment - xAxisID: null, - yAxisID: null - }; - } - - return meta; - }, - - getVisibleDatasetCount: function() { - var count = 0; - for (var i = 0, ilen = this.data.datasets.length; i < ilen; ++i) { - if (this.isDatasetVisible(i)) { - count++; - } - } - return count; - }, - - isDatasetVisible: function(datasetIndex) { - var meta = this.getDatasetMeta(datasetIndex); - - // meta.hidden is a per chart dataset hidden flag override with 3 states: if true or false, - // the dataset.hidden value is ignored, else if null, the dataset hidden state is returned. - return typeof meta.hidden === 'boolean' ? !meta.hidden : !this.data.datasets[datasetIndex].hidden; - }, - - generateLegend: function() { - return this.options.legendCallback(this); - }, - - /** - * @private - */ - destroyDatasetMeta: function(datasetIndex) { - var id = this.id; - var dataset = this.data.datasets[datasetIndex]; - var meta = dataset._meta && dataset._meta[id]; - - if (meta) { - meta.controller.destroy(); - delete dataset._meta[id]; - } - }, - - destroy: function() { - var me = this; - var canvas = me.canvas; - var i, ilen; - - me.stop(); - - // dataset controllers need to cleanup associated data - for (i = 0, ilen = me.data.datasets.length; i < ilen; ++i) { - me.destroyDatasetMeta(i); - } - - if (canvas) { - me.unbindEvents(); - helpers$1.canvas.clear(me); - platform.releaseContext(me.ctx); - me.canvas = null; - me.ctx = null; - } - - core_plugins.notify(me, 'destroy'); - - delete Chart.instances[me.id]; - }, - - toBase64Image: function() { - return this.canvas.toDataURL.apply(this.canvas, arguments); - }, - - initToolTip: function() { - var me = this; - me.tooltip = new core_tooltip({ - _chart: me, - _chartInstance: me, // deprecated, backward compatibility - _data: me.data, - _options: me.options.tooltips - }, me); - }, - - /** - * @private - */ - bindEvents: function() { - var me = this; - var listeners = me._listeners = {}; - var listener = function() { - me.eventHandler.apply(me, arguments); - }; - - helpers$1.each(me.options.events, function(type) { - platform.addEventListener(me, type, listener); - listeners[type] = listener; - }); - - // Elements used to detect size change should not be injected for non responsive charts. - // See https://github.com/chartjs/Chart.js/issues/2210 - if (me.options.responsive) { - listener = function() { - me.resize(); - }; - - platform.addEventListener(me, 'resize', listener); - listeners.resize = listener; - } - }, - - /** - * @private - */ - unbindEvents: function() { - var me = this; - var listeners = me._listeners; - if (!listeners) { - return; - } - - delete me._listeners; - helpers$1.each(listeners, function(listener, type) { - platform.removeEventListener(me, type, listener); - }); - }, - - updateHoverStyle: function(elements, mode, enabled) { - var method = enabled ? 'setHoverStyle' : 'removeHoverStyle'; - var element, i, ilen; - - for (i = 0, ilen = elements.length; i < ilen; ++i) { - element = elements[i]; - if (element) { - this.getDatasetMeta(element._datasetIndex).controller[method](element); - } - } - }, - - /** - * @private - */ - eventHandler: function(e) { - var me = this; - var tooltip = me.tooltip; - - if (core_plugins.notify(me, 'beforeEvent', [e]) === false) { - return; - } - - // Buffer any update calls so that renders do not occur - me._bufferedRender = true; - me._bufferedRequest = null; - - var changed = me.handleEvent(e); - // for smooth tooltip animations issue #4989 - // the tooltip should be the source of change - // Animation check workaround: - // tooltip._start will be null when tooltip isn't animating - if (tooltip) { - changed = tooltip._start - ? tooltip.handleEvent(e) - : changed | tooltip.handleEvent(e); - } - - core_plugins.notify(me, 'afterEvent', [e]); - - var bufferedRequest = me._bufferedRequest; - if (bufferedRequest) { - // If we have an update that was triggered, we need to do a normal render - me.render(bufferedRequest); - } else if (changed && !me.animating) { - // If entering, leaving, or changing elements, animate the change via pivot - me.stop(); - - // We only need to render at this point. Updating will cause scales to be - // recomputed generating flicker & using more memory than necessary. - me.render({ - duration: me.options.hover.animationDuration, - lazy: true - }); - } - - me._bufferedRender = false; - me._bufferedRequest = null; - - return me; - }, - - /** - * Handle an event - * @private - * @param {IEvent} event the event to handle - * @return {boolean} true if the chart needs to re-render - */ - handleEvent: function(e) { - var me = this; - var options = me.options || {}; - var hoverOptions = options.hover; - var changed = false; - - me.lastActive = me.lastActive || []; - - // Find Active Elements for hover and tooltips - if (e.type === 'mouseout') { - me.active = []; - } else { - me.active = me.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions); - } - - // Invoke onHover hook - // Need to call with native event here to not break backwards compatibility - helpers$1.callback(options.onHover || options.hover.onHover, [e.native, me.active], me); - - if (e.type === 'mouseup' || e.type === 'click') { - if (options.onClick) { - // Use e.native here for backwards compatibility - options.onClick.call(me, e.native, me.active); - } - } - - // Remove styling for last active (even if it may still be active) - if (me.lastActive.length) { - me.updateHoverStyle(me.lastActive, hoverOptions.mode, false); - } - - // Built in hover styling - if (me.active.length && hoverOptions.mode) { - me.updateHoverStyle(me.active, hoverOptions.mode, true); - } - - changed = !helpers$1.arrayEquals(me.active, me.lastActive); - - // Remember Last Actives - me.lastActive = me.active; - - return changed; - } -}); - -/** - * NOTE(SB) We actually don't use this container anymore but we need to keep it - * for backward compatibility. Though, it can still be useful for plugins that - * would need to work on multiple charts?! - */ -Chart.instances = {}; - -var core_controller = Chart; - -// DEPRECATIONS - -/** - * Provided for backward compatibility, use Chart instead. - * @class Chart.Controller - * @deprecated since version 2.6 - * @todo remove at version 3 - * @private - */ -Chart.Controller = Chart; - -/** - * Provided for backward compatibility, not available anymore. - * @namespace Chart - * @deprecated since version 2.8 - * @todo remove at version 3 - * @private - */ -Chart.types = {}; - -/** - * Provided for backward compatibility, not available anymore. - * @namespace Chart.helpers.configMerge - * @deprecated since version 2.8.0 - * @todo remove at version 3 - * @private - */ -helpers$1.configMerge = mergeConfig; - -/** - * Provided for backward compatibility, not available anymore. - * @namespace Chart.helpers.scaleMerge - * @deprecated since version 2.8.0 - * @todo remove at version 3 - * @private - */ -helpers$1.scaleMerge = mergeScaleConfig; - -var core_helpers = function() { - - // -- Basic js utility methods - - helpers$1.where = function(collection, filterCallback) { - if (helpers$1.isArray(collection) && Array.prototype.filter) { - return collection.filter(filterCallback); - } - var filtered = []; - - helpers$1.each(collection, function(item) { - if (filterCallback(item)) { - filtered.push(item); - } - }); - - return filtered; - }; - helpers$1.findIndex = Array.prototype.findIndex ? - function(array, callback, scope) { - return array.findIndex(callback, scope); - } : - function(array, callback, scope) { - scope = scope === undefined ? array : scope; - for (var i = 0, ilen = array.length; i < ilen; ++i) { - if (callback.call(scope, array[i], i, array)) { - return i; - } - } - return -1; - }; - helpers$1.findNextWhere = function(arrayToSearch, filterCallback, startIndex) { - // Default to start of the array - if (helpers$1.isNullOrUndef(startIndex)) { - startIndex = -1; - } - for (var i = startIndex + 1; i < arrayToSearch.length; i++) { - var currentItem = arrayToSearch[i]; - if (filterCallback(currentItem)) { - return currentItem; - } - } - }; - helpers$1.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex) { - // Default to end of the array - if (helpers$1.isNullOrUndef(startIndex)) { - startIndex = arrayToSearch.length; - } - for (var i = startIndex - 1; i >= 0; i--) { - var currentItem = arrayToSearch[i]; - if (filterCallback(currentItem)) { - return currentItem; - } - } - }; - - // -- Math methods - helpers$1.isNumber = function(n) { - return !isNaN(parseFloat(n)) && isFinite(n); - }; - helpers$1.almostEquals = function(x, y, epsilon) { - return Math.abs(x - y) < epsilon; - }; - helpers$1.almostWhole = function(x, epsilon) { - var rounded = Math.round(x); - return (((rounded - epsilon) < x) && ((rounded + epsilon) > x)); - }; - helpers$1.max = function(array) { - return array.reduce(function(max, value) { - if (!isNaN(value)) { - return Math.max(max, value); - } - return max; - }, Number.NEGATIVE_INFINITY); - }; - helpers$1.min = function(array) { - return array.reduce(function(min, value) { - if (!isNaN(value)) { - return Math.min(min, value); - } - return min; - }, Number.POSITIVE_INFINITY); - }; - helpers$1.sign = Math.sign ? - function(x) { - return Math.sign(x); - } : - function(x) { - x = +x; // convert to a number - if (x === 0 || isNaN(x)) { - return x; - } - return x > 0 ? 1 : -1; - }; - helpers$1.log10 = Math.log10 ? - function(x) { - return Math.log10(x); - } : - function(x) { - var exponent = Math.log(x) * Math.LOG10E; // Math.LOG10E = 1 / Math.LN10. - // Check for whole powers of 10, - // which due to floating point rounding error should be corrected. - var powerOf10 = Math.round(exponent); - var isPowerOf10 = x === Math.pow(10, powerOf10); - - return isPowerOf10 ? powerOf10 : exponent; - }; - helpers$1.toRadians = function(degrees) { - return degrees * (Math.PI / 180); - }; - helpers$1.toDegrees = function(radians) { - return radians * (180 / Math.PI); - }; - - /** - * Returns the number of decimal places - * i.e. the number of digits after the decimal point, of the value of this Number. - * @param {number} x - A number. - * @returns {number} The number of decimal places. - * @private - */ - helpers$1._decimalPlaces = function(x) { - if (!helpers$1.isFinite(x)) { - return; - } - var e = 1; - var p = 0; - while (Math.round(x * e) / e !== x) { - e *= 10; - p++; - } - return p; - }; - - // Gets the angle from vertical upright to the point about a centre. - helpers$1.getAngleFromPoint = function(centrePoint, anglePoint) { - var distanceFromXCenter = anglePoint.x - centrePoint.x; - var distanceFromYCenter = anglePoint.y - centrePoint.y; - var radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter); - - var angle = Math.atan2(distanceFromYCenter, distanceFromXCenter); - - if (angle < (-0.5 * Math.PI)) { - angle += 2.0 * Math.PI; // make sure the returned angle is in the range of (-PI/2, 3PI/2] - } - - return { - angle: angle, - distance: radialDistanceFromCenter - }; - }; - helpers$1.distanceBetweenPoints = function(pt1, pt2) { - return Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2)); - }; - - /** - * Provided for backward compatibility, not available anymore - * @function Chart.helpers.aliasPixel - * @deprecated since version 2.8.0 - * @todo remove at version 3 - */ - helpers$1.aliasPixel = function(pixelWidth) { - return (pixelWidth % 2 === 0) ? 0 : 0.5; - }; - - /** - * Returns the aligned pixel value to avoid anti-aliasing blur - * @param {Chart} chart - The chart instance. - * @param {number} pixel - A pixel value. - * @param {number} width - The width of the element. - * @returns {number} The aligned pixel value. - * @private - */ - helpers$1._alignPixel = function(chart, pixel, width) { - var devicePixelRatio = chart.currentDevicePixelRatio; - var halfWidth = width / 2; - return Math.round((pixel - halfWidth) * devicePixelRatio) / devicePixelRatio + halfWidth; - }; - - helpers$1.splineCurve = function(firstPoint, middlePoint, afterPoint, t) { - // Props to Rob Spencer at scaled innovation for his post on splining between points - // http://scaledinnovation.com/analytics/splines/aboutSplines.html - - // This function must also respect "skipped" points - - var previous = firstPoint.skip ? middlePoint : firstPoint; - var current = middlePoint; - var next = afterPoint.skip ? middlePoint : afterPoint; - - var d01 = Math.sqrt(Math.pow(current.x - previous.x, 2) + Math.pow(current.y - previous.y, 2)); - var d12 = Math.sqrt(Math.pow(next.x - current.x, 2) + Math.pow(next.y - current.y, 2)); - - var s01 = d01 / (d01 + d12); - var s12 = d12 / (d01 + d12); - - // If all points are the same, s01 & s02 will be inf - s01 = isNaN(s01) ? 0 : s01; - s12 = isNaN(s12) ? 0 : s12; - - var fa = t * s01; // scaling factor for triangle Ta - var fb = t * s12; - - return { - previous: { - x: current.x - fa * (next.x - previous.x), - y: current.y - fa * (next.y - previous.y) - }, - next: { - x: current.x + fb * (next.x - previous.x), - y: current.y + fb * (next.y - previous.y) - } - }; - }; - helpers$1.EPSILON = Number.EPSILON || 1e-14; - helpers$1.splineCurveMonotone = function(points) { - // This function calculates Bézier control points in a similar way than |splineCurve|, - // but preserves monotonicity of the provided data and ensures no local extremums are added - // between the dataset discrete points due to the interpolation. - // See : https://en.wikipedia.org/wiki/Monotone_cubic_interpolation - - var pointsWithTangents = (points || []).map(function(point) { - return { - model: point._model, - deltaK: 0, - mK: 0 - }; - }); - - // Calculate slopes (deltaK) and initialize tangents (mK) - var pointsLen = pointsWithTangents.length; - var i, pointBefore, pointCurrent, pointAfter; - for (i = 0; i < pointsLen; ++i) { - pointCurrent = pointsWithTangents[i]; - if (pointCurrent.model.skip) { - continue; - } - - pointBefore = i > 0 ? pointsWithTangents[i - 1] : null; - pointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null; - if (pointAfter && !pointAfter.model.skip) { - var slopeDeltaX = (pointAfter.model.x - pointCurrent.model.x); - - // In the case of two points that appear at the same x pixel, slopeDeltaX is 0 - pointCurrent.deltaK = slopeDeltaX !== 0 ? (pointAfter.model.y - pointCurrent.model.y) / slopeDeltaX : 0; - } - - if (!pointBefore || pointBefore.model.skip) { - pointCurrent.mK = pointCurrent.deltaK; - } else if (!pointAfter || pointAfter.model.skip) { - pointCurrent.mK = pointBefore.deltaK; - } else if (this.sign(pointBefore.deltaK) !== this.sign(pointCurrent.deltaK)) { - pointCurrent.mK = 0; - } else { - pointCurrent.mK = (pointBefore.deltaK + pointCurrent.deltaK) / 2; - } - } - - // Adjust tangents to ensure monotonic properties - var alphaK, betaK, tauK, squaredMagnitude; - for (i = 0; i < pointsLen - 1; ++i) { - pointCurrent = pointsWithTangents[i]; - pointAfter = pointsWithTangents[i + 1]; - if (pointCurrent.model.skip || pointAfter.model.skip) { - continue; - } - - if (helpers$1.almostEquals(pointCurrent.deltaK, 0, this.EPSILON)) { - pointCurrent.mK = pointAfter.mK = 0; - continue; - } - - alphaK = pointCurrent.mK / pointCurrent.deltaK; - betaK = pointAfter.mK / pointCurrent.deltaK; - squaredMagnitude = Math.pow(alphaK, 2) + Math.pow(betaK, 2); - if (squaredMagnitude <= 9) { - continue; - } - - tauK = 3 / Math.sqrt(squaredMagnitude); - pointCurrent.mK = alphaK * tauK * pointCurrent.deltaK; - pointAfter.mK = betaK * tauK * pointCurrent.deltaK; - } - - // Compute control points - var deltaX; - for (i = 0; i < pointsLen; ++i) { - pointCurrent = pointsWithTangents[i]; - if (pointCurrent.model.skip) { - continue; - } - - pointBefore = i > 0 ? pointsWithTangents[i - 1] : null; - pointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null; - if (pointBefore && !pointBefore.model.skip) { - deltaX = (pointCurrent.model.x - pointBefore.model.x) / 3; - pointCurrent.model.controlPointPreviousX = pointCurrent.model.x - deltaX; - pointCurrent.model.controlPointPreviousY = pointCurrent.model.y - deltaX * pointCurrent.mK; - } - if (pointAfter && !pointAfter.model.skip) { - deltaX = (pointAfter.model.x - pointCurrent.model.x) / 3; - pointCurrent.model.controlPointNextX = pointCurrent.model.x + deltaX; - pointCurrent.model.controlPointNextY = pointCurrent.model.y + deltaX * pointCurrent.mK; - } - } - }; - helpers$1.nextItem = function(collection, index, loop) { - if (loop) { - return index >= collection.length - 1 ? collection[0] : collection[index + 1]; - } - return index >= collection.length - 1 ? collection[collection.length - 1] : collection[index + 1]; - }; - helpers$1.previousItem = function(collection, index, loop) { - if (loop) { - return index <= 0 ? collection[collection.length - 1] : collection[index - 1]; - } - return index <= 0 ? collection[0] : collection[index - 1]; - }; - // Implementation of the nice number algorithm used in determining where axis labels will go - helpers$1.niceNum = function(range, round) { - var exponent = Math.floor(helpers$1.log10(range)); - var fraction = range / Math.pow(10, exponent); - var niceFraction; - - if (round) { - if (fraction < 1.5) { - niceFraction = 1; - } else if (fraction < 3) { - niceFraction = 2; - } else if (fraction < 7) { - niceFraction = 5; - } else { - niceFraction = 10; - } - } else if (fraction <= 1.0) { - niceFraction = 1; - } else if (fraction <= 2) { - niceFraction = 2; - } else if (fraction <= 5) { - niceFraction = 5; - } else { - niceFraction = 10; - } - - return niceFraction * Math.pow(10, exponent); - }; - // Request animation polyfill - https://www.paulirish.com/2011/requestanimationframe-for-smart-animating/ - helpers$1.requestAnimFrame = (function() { - if (typeof window === 'undefined') { - return function(callback) { - callback(); - }; - } - return window.requestAnimationFrame || - window.webkitRequestAnimationFrame || - window.mozRequestAnimationFrame || - window.oRequestAnimationFrame || - window.msRequestAnimationFrame || - function(callback) { - return window.setTimeout(callback, 1000 / 60); - }; - }()); - // -- DOM methods - helpers$1.getRelativePosition = function(evt, chart) { - var mouseX, mouseY; - var e = evt.originalEvent || evt; - var canvas = evt.target || evt.srcElement; - var boundingRect = canvas.getBoundingClientRect(); - - var touches = e.touches; - if (touches && touches.length > 0) { - mouseX = touches[0].clientX; - mouseY = touches[0].clientY; - - } else { - mouseX = e.clientX; - mouseY = e.clientY; - } - - // Scale mouse coordinates into canvas coordinates - // by following the pattern laid out by 'jerryj' in the comments of - // https://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/ - var paddingLeft = parseFloat(helpers$1.getStyle(canvas, 'padding-left')); - var paddingTop = parseFloat(helpers$1.getStyle(canvas, 'padding-top')); - var paddingRight = parseFloat(helpers$1.getStyle(canvas, 'padding-right')); - var paddingBottom = parseFloat(helpers$1.getStyle(canvas, 'padding-bottom')); - var width = boundingRect.right - boundingRect.left - paddingLeft - paddingRight; - var height = boundingRect.bottom - boundingRect.top - paddingTop - paddingBottom; - - // We divide by the current device pixel ratio, because the canvas is scaled up by that amount in each direction. However - // the backend model is in unscaled coordinates. Since we are going to deal with our model coordinates, we go back here - mouseX = Math.round((mouseX - boundingRect.left - paddingLeft) / (width) * canvas.width / chart.currentDevicePixelRatio); - mouseY = Math.round((mouseY - boundingRect.top - paddingTop) / (height) * canvas.height / chart.currentDevicePixelRatio); - - return { - x: mouseX, - y: mouseY - }; - - }; - - // Private helper function to convert max-width/max-height values that may be percentages into a number - function parseMaxStyle(styleValue, node, parentProperty) { - var valueInPixels; - if (typeof styleValue === 'string') { - valueInPixels = parseInt(styleValue, 10); - - if (styleValue.indexOf('%') !== -1) { - // percentage * size in dimension - valueInPixels = valueInPixels / 100 * node.parentNode[parentProperty]; - } - } else { - valueInPixels = styleValue; - } - - return valueInPixels; - } - - /** - * Returns if the given value contains an effective constraint. - * @private - */ - function isConstrainedValue(value) { - return value !== undefined && value !== null && value !== 'none'; - } - - /** - * Returns the max width or height of the given DOM node in a cross-browser compatible fashion - * @param {HTMLElement} domNode - the node to check the constraint on - * @param {string} maxStyle - the style that defines the maximum for the direction we are using ('max-width' / 'max-height') - * @param {string} percentageProperty - property of parent to use when calculating width as a percentage - * @see {@link https://www.nathanaeljones.com/blog/2013/reading-max-width-cross-browser} - */ - function getConstraintDimension(domNode, maxStyle, percentageProperty) { - var view = document.defaultView; - var parentNode = helpers$1._getParentNode(domNode); - var constrainedNode = view.getComputedStyle(domNode)[maxStyle]; - var constrainedContainer = view.getComputedStyle(parentNode)[maxStyle]; - var hasCNode = isConstrainedValue(constrainedNode); - var hasCContainer = isConstrainedValue(constrainedContainer); - var infinity = Number.POSITIVE_INFINITY; - - if (hasCNode || hasCContainer) { - return Math.min( - hasCNode ? parseMaxStyle(constrainedNode, domNode, percentageProperty) : infinity, - hasCContainer ? parseMaxStyle(constrainedContainer, parentNode, percentageProperty) : infinity); - } - - return 'none'; - } - // returns Number or undefined if no constraint - helpers$1.getConstraintWidth = function(domNode) { - return getConstraintDimension(domNode, 'max-width', 'clientWidth'); - }; - // returns Number or undefined if no constraint - helpers$1.getConstraintHeight = function(domNode) { - return getConstraintDimension(domNode, 'max-height', 'clientHeight'); - }; - /** - * @private - */ - helpers$1._calculatePadding = function(container, padding, parentDimension) { - padding = helpers$1.getStyle(container, padding); - - return padding.indexOf('%') > -1 ? parentDimension * parseInt(padding, 10) / 100 : parseInt(padding, 10); - }; - /** - * @private - */ - helpers$1._getParentNode = function(domNode) { - var parent = domNode.parentNode; - if (parent && parent.toString() === '[object ShadowRoot]') { - parent = parent.host; - } - return parent; - }; - helpers$1.getMaximumWidth = function(domNode) { - var container = helpers$1._getParentNode(domNode); - if (!container) { - return domNode.clientWidth; - } - - var clientWidth = container.clientWidth; - var paddingLeft = helpers$1._calculatePadding(container, 'padding-left', clientWidth); - var paddingRight = helpers$1._calculatePadding(container, 'padding-right', clientWidth); - - var w = clientWidth - paddingLeft - paddingRight; - var cw = helpers$1.getConstraintWidth(domNode); - return isNaN(cw) ? w : Math.min(w, cw); - }; - helpers$1.getMaximumHeight = function(domNode) { - var container = helpers$1._getParentNode(domNode); - if (!container) { - return domNode.clientHeight; - } - - var clientHeight = container.clientHeight; - var paddingTop = helpers$1._calculatePadding(container, 'padding-top', clientHeight); - var paddingBottom = helpers$1._calculatePadding(container, 'padding-bottom', clientHeight); - - var h = clientHeight - paddingTop - paddingBottom; - var ch = helpers$1.getConstraintHeight(domNode); - return isNaN(ch) ? h : Math.min(h, ch); - }; - helpers$1.getStyle = function(el, property) { - return el.currentStyle ? - el.currentStyle[property] : - document.defaultView.getComputedStyle(el, null).getPropertyValue(property); - }; - helpers$1.retinaScale = function(chart, forceRatio) { - var pixelRatio = chart.currentDevicePixelRatio = forceRatio || (typeof window !== 'undefined' && window.devicePixelRatio) || 1; - if (pixelRatio === 1) { - return; - } - - var canvas = chart.canvas; - var height = chart.height; - var width = chart.width; - - canvas.height = height * pixelRatio; - canvas.width = width * pixelRatio; - chart.ctx.scale(pixelRatio, pixelRatio); - - // If no style has been set on the canvas, the render size is used as display size, - // making the chart visually bigger, so let's enforce it to the "correct" values. - // See https://github.com/chartjs/Chart.js/issues/3575 - if (!canvas.style.height && !canvas.style.width) { - canvas.style.height = height + 'px'; - canvas.style.width = width + 'px'; - } - }; - // -- Canvas methods - helpers$1.fontString = function(pixelSize, fontStyle, fontFamily) { - return fontStyle + ' ' + pixelSize + 'px ' + fontFamily; - }; - helpers$1.longestText = function(ctx, font, arrayOfThings, cache) { - cache = cache || {}; - var data = cache.data = cache.data || {}; - var gc = cache.garbageCollect = cache.garbageCollect || []; - - if (cache.font !== font) { - data = cache.data = {}; - gc = cache.garbageCollect = []; - cache.font = font; - } - - ctx.font = font; - var longest = 0; - helpers$1.each(arrayOfThings, function(thing) { - // Undefined strings and arrays should not be measured - if (thing !== undefined && thing !== null && helpers$1.isArray(thing) !== true) { - longest = helpers$1.measureText(ctx, data, gc, longest, thing); - } else if (helpers$1.isArray(thing)) { - // if it is an array lets measure each element - // to do maybe simplify this function a bit so we can do this more recursively? - helpers$1.each(thing, function(nestedThing) { - // Undefined strings and arrays should not be measured - if (nestedThing !== undefined && nestedThing !== null && !helpers$1.isArray(nestedThing)) { - longest = helpers$1.measureText(ctx, data, gc, longest, nestedThing); - } - }); - } - }); - - var gcLen = gc.length / 2; - if (gcLen > arrayOfThings.length) { - for (var i = 0; i < gcLen; i++) { - delete data[gc[i]]; - } - gc.splice(0, gcLen); - } - return longest; - }; - helpers$1.measureText = function(ctx, data, gc, longest, string) { - var textWidth = data[string]; - if (!textWidth) { - textWidth = data[string] = ctx.measureText(string).width; - gc.push(string); - } - if (textWidth > longest) { - longest = textWidth; - } - return longest; - }; - helpers$1.numberOfLabelLines = function(arrayOfThings) { - var numberOfLines = 1; - helpers$1.each(arrayOfThings, function(thing) { - if (helpers$1.isArray(thing)) { - if (thing.length > numberOfLines) { - numberOfLines = thing.length; - } - } - }); - return numberOfLines; - }; - - helpers$1.color = !chartjsColor ? - function(value) { - console.error('Color.js not found!'); - return value; - } : - function(value) { - /* global CanvasGradient */ - if (value instanceof CanvasGradient) { - value = core_defaults.global.defaultColor; - } - - return chartjsColor(value); - }; - - helpers$1.getHoverColor = function(colorValue) { - /* global CanvasPattern */ - return (colorValue instanceof CanvasPattern || colorValue instanceof CanvasGradient) ? - colorValue : - helpers$1.color(colorValue).saturate(0.5).darken(0.1).rgbString(); - }; -}; - -function abstract() { - throw new Error( - 'This method is not implemented: either no adapter can ' + - 'be found or an incomplete integration was provided.' - ); -} - -/** - * Date adapter (current used by the time scale) - * @namespace Chart._adapters._date - * @memberof Chart._adapters - * @private - */ - -/** - * Currently supported unit string values. - * @typedef {('millisecond'|'second'|'minute'|'hour'|'day'|'week'|'month'|'quarter'|'year')} - * @memberof Chart._adapters._date - * @name Unit - */ - -/** - * @class - */ -function DateAdapter(options) { - this.options = options || {}; -} - -helpers$1.extend(DateAdapter.prototype, /** @lends DateAdapter */ { - /** - * Returns a map of time formats for the supported formatting units defined - * in Unit as well as 'datetime' representing a detailed date/time string. - * @returns {{string: string}} - */ - formats: abstract, - - /** - * Parses the given `value` and return the associated timestamp. - * @param {any} value - the value to parse (usually comes from the data) - * @param {string} [format] - the expected data format - * @returns {(number|null)} - * @function - */ - parse: abstract, - - /** - * Returns the formatted date in the specified `format` for a given `timestamp`. - * @param {number} timestamp - the timestamp to format - * @param {string} format - the date/time token - * @return {string} - * @function - */ - format: abstract, - - /** - * Adds the specified `amount` of `unit` to the given `timestamp`. - * @param {number} timestamp - the input timestamp - * @param {number} amount - the amount to add - * @param {Unit} unit - the unit as string - * @return {number} - * @function - */ - add: abstract, - - /** - * Returns the number of `unit` between the given timestamps. - * @param {number} max - the input timestamp (reference) - * @param {number} min - the timestamp to substract - * @param {Unit} unit - the unit as string - * @return {number} - * @function - */ - diff: abstract, - - /** - * Returns start of `unit` for the given `timestamp`. - * @param {number} timestamp - the input timestamp - * @param {Unit} unit - the unit as string - * @param {number} [weekday] - the ISO day of the week with 1 being Monday - * and 7 being Sunday (only needed if param *unit* is `isoWeek`). - * @function - */ - startOf: abstract, - - /** - * Returns end of `unit` for the given `timestamp`. - * @param {number} timestamp - the input timestamp - * @param {Unit} unit - the unit as string - * @function - */ - endOf: abstract, - - // DEPRECATIONS - - /** - * Provided for backward compatibility for scale.getValueForPixel(), - * this method should be overridden only by the moment adapter. - * @deprecated since version 2.8.0 - * @todo remove at version 3 - * @private - */ - _create: function(value) { - return value; - } -}); - -DateAdapter.override = function(members) { - helpers$1.extend(DateAdapter.prototype, members); -}; - -var _date = DateAdapter; - -var core_adapters = { - _date: _date -}; - -/** - * Namespace to hold static tick generation functions - * @namespace Chart.Ticks - */ -var core_ticks = { - /** - * Namespace to hold formatters for different types of ticks - * @namespace Chart.Ticks.formatters - */ - formatters: { - /** - * Formatter for value labels - * @method Chart.Ticks.formatters.values - * @param value the value to display - * @return {string|string[]} the label to display - */ - values: function(value) { - return helpers$1.isArray(value) ? value : '' + value; - }, - - /** - * Formatter for linear numeric ticks - * @method Chart.Ticks.formatters.linear - * @param tickValue {number} the value to be formatted - * @param index {number} the position of the tickValue parameter in the ticks array - * @param ticks {number[]} the list of ticks being converted - * @return {string} string representation of the tickValue parameter - */ - linear: function(tickValue, index, ticks) { - // If we have lots of ticks, don't use the ones - var delta = ticks.length > 3 ? ticks[2] - ticks[1] : ticks[1] - ticks[0]; - - // If we have a number like 2.5 as the delta, figure out how many decimal places we need - if (Math.abs(delta) > 1) { - if (tickValue !== Math.floor(tickValue)) { - // not an integer - delta = tickValue - Math.floor(tickValue); - } - } - - var logDelta = helpers$1.log10(Math.abs(delta)); - var tickString = ''; - - if (tickValue !== 0) { - var maxTick = Math.max(Math.abs(ticks[0]), Math.abs(ticks[ticks.length - 1])); - if (maxTick < 1e-4) { // all ticks are small numbers; use scientific notation - var logTick = helpers$1.log10(Math.abs(tickValue)); - tickString = tickValue.toExponential(Math.floor(logTick) - Math.floor(logDelta)); - } else { - var numDecimal = -1 * Math.floor(logDelta); - numDecimal = Math.max(Math.min(numDecimal, 20), 0); // toFixed has a max of 20 decimal places - tickString = tickValue.toFixed(numDecimal); - } - } else { - tickString = '0'; // never show decimal places for 0 - } - - return tickString; - }, - - logarithmic: function(tickValue, index, ticks) { - var remain = tickValue / (Math.pow(10, Math.floor(helpers$1.log10(tickValue)))); - - if (tickValue === 0) { - return '0'; - } else if (remain === 1 || remain === 2 || remain === 5 || index === 0 || index === ticks.length - 1) { - return tickValue.toExponential(); - } - return ''; - } - } -}; - -var valueOrDefault$9 = helpers$1.valueOrDefault; -var valueAtIndexOrDefault = helpers$1.valueAtIndexOrDefault; - -core_defaults._set('scale', { - display: true, - position: 'left', - offset: false, - - // grid line settings - gridLines: { - display: true, - color: 'rgba(0, 0, 0, 0.1)', - lineWidth: 1, - drawBorder: true, - drawOnChartArea: true, - drawTicks: true, - tickMarkLength: 10, - zeroLineWidth: 1, - zeroLineColor: 'rgba(0,0,0,0.25)', - zeroLineBorderDash: [], - zeroLineBorderDashOffset: 0.0, - offsetGridLines: false, - borderDash: [], - borderDashOffset: 0.0 - }, - - // scale label - scaleLabel: { - // display property - display: false, - - // actual label - labelString: '', - - // top/bottom padding - padding: { - top: 4, - bottom: 4 - } - }, - - // label settings - ticks: { - beginAtZero: false, - minRotation: 0, - maxRotation: 50, - mirror: false, - padding: 0, - reverse: false, - display: true, - autoSkip: true, - autoSkipPadding: 0, - labelOffset: 0, - // We pass through arrays to be rendered as multiline labels, we convert Others to strings here. - callback: core_ticks.formatters.values, - minor: {}, - major: {} - } -}); - -function labelsFromTicks(ticks) { - var labels = []; - var i, ilen; - - for (i = 0, ilen = ticks.length; i < ilen; ++i) { - labels.push(ticks[i].label); - } - - return labels; -} - -function getPixelForGridLine(scale, index, offsetGridLines) { - var lineValue = scale.getPixelForTick(index); - - if (offsetGridLines) { - if (scale.getTicks().length === 1) { - lineValue -= scale.isHorizontal() ? - Math.max(lineValue - scale.left, scale.right - lineValue) : - Math.max(lineValue - scale.top, scale.bottom - lineValue); - } else if (index === 0) { - lineValue -= (scale.getPixelForTick(1) - lineValue) / 2; - } else { - lineValue -= (lineValue - scale.getPixelForTick(index - 1)) / 2; - } - } - return lineValue; -} - -function computeTextSize(context, tick, font) { - return helpers$1.isArray(tick) ? - helpers$1.longestText(context, font, tick) : - context.measureText(tick).width; -} - -var core_scale = core_element.extend({ - /** - * Get the padding needed for the scale - * @method getPadding - * @private - * @returns {Padding} the necessary padding - */ - getPadding: function() { - var me = this; - return { - left: me.paddingLeft || 0, - top: me.paddingTop || 0, - right: me.paddingRight || 0, - bottom: me.paddingBottom || 0 - }; - }, - - /** - * Returns the scale tick objects ({label, major}) - * @since 2.7 - */ - getTicks: function() { - return this._ticks; - }, - - // These methods are ordered by lifecyle. Utilities then follow. - // Any function defined here is inherited by all scale types. - // Any function can be extended by the scale type - - mergeTicksOptions: function() { - var ticks = this.options.ticks; - if (ticks.minor === false) { - ticks.minor = { - display: false - }; - } - if (ticks.major === false) { - ticks.major = { - display: false - }; - } - for (var key in ticks) { - if (key !== 'major' && key !== 'minor') { - if (typeof ticks.minor[key] === 'undefined') { - ticks.minor[key] = ticks[key]; - } - if (typeof ticks.major[key] === 'undefined') { - ticks.major[key] = ticks[key]; - } - } - } - }, - beforeUpdate: function() { - helpers$1.callback(this.options.beforeUpdate, [this]); - }, - - update: function(maxWidth, maxHeight, margins) { - var me = this; - var i, ilen, labels, label, ticks, tick; - - // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;) - me.beforeUpdate(); - - // Absorb the master measurements - me.maxWidth = maxWidth; - me.maxHeight = maxHeight; - me.margins = helpers$1.extend({ - left: 0, - right: 0, - top: 0, - bottom: 0 - }, margins); - - me._maxLabelLines = 0; - me.longestLabelWidth = 0; - me.longestTextCache = me.longestTextCache || {}; - - // Dimensions - me.beforeSetDimensions(); - me.setDimensions(); - me.afterSetDimensions(); - - // Data min/max - me.beforeDataLimits(); - me.determineDataLimits(); - me.afterDataLimits(); - - // Ticks - `this.ticks` is now DEPRECATED! - // Internal ticks are now stored as objects in the PRIVATE `this._ticks` member - // and must not be accessed directly from outside this class. `this.ticks` being - // around for long time and not marked as private, we can't change its structure - // without unexpected breaking changes. If you need to access the scale ticks, - // use scale.getTicks() instead. - - me.beforeBuildTicks(); - - // New implementations should return an array of objects but for BACKWARD COMPAT, - // we still support no return (`this.ticks` internally set by calling this method). - ticks = me.buildTicks() || []; - - // Allow modification of ticks in callback. - ticks = me.afterBuildTicks(ticks) || ticks; - - me.beforeTickToLabelConversion(); - - // New implementations should return the formatted tick labels but for BACKWARD - // COMPAT, we still support no return (`this.ticks` internally changed by calling - // this method and supposed to contain only string values). - labels = me.convertTicksToLabels(ticks) || me.ticks; - - me.afterTickToLabelConversion(); - - me.ticks = labels; // BACKWARD COMPATIBILITY - - // IMPORTANT: from this point, we consider that `this.ticks` will NEVER change! - - // BACKWARD COMPAT: synchronize `_ticks` with labels (so potentially `this.ticks`) - for (i = 0, ilen = labels.length; i < ilen; ++i) { - label = labels[i]; - tick = ticks[i]; - if (!tick) { - ticks.push(tick = { - label: label, - major: false - }); - } else { - tick.label = label; - } - } - - me._ticks = ticks; - - // Tick Rotation - me.beforeCalculateTickRotation(); - me.calculateTickRotation(); - me.afterCalculateTickRotation(); - // Fit - me.beforeFit(); - me.fit(); - me.afterFit(); - // - me.afterUpdate(); - - return me.minSize; - - }, - afterUpdate: function() { - helpers$1.callback(this.options.afterUpdate, [this]); - }, - - // - - beforeSetDimensions: function() { - helpers$1.callback(this.options.beforeSetDimensions, [this]); - }, - setDimensions: function() { - var me = this; - // Set the unconstrained dimension before label rotation - if (me.isHorizontal()) { - // Reset position before calculating rotation - me.width = me.maxWidth; - me.left = 0; - me.right = me.width; - } else { - me.height = me.maxHeight; - - // Reset position before calculating rotation - me.top = 0; - me.bottom = me.height; - } - - // Reset padding - me.paddingLeft = 0; - me.paddingTop = 0; - me.paddingRight = 0; - me.paddingBottom = 0; - }, - afterSetDimensions: function() { - helpers$1.callback(this.options.afterSetDimensions, [this]); - }, - - // Data limits - beforeDataLimits: function() { - helpers$1.callback(this.options.beforeDataLimits, [this]); - }, - determineDataLimits: helpers$1.noop, - afterDataLimits: function() { - helpers$1.callback(this.options.afterDataLimits, [this]); - }, - - // - beforeBuildTicks: function() { - helpers$1.callback(this.options.beforeBuildTicks, [this]); - }, - buildTicks: helpers$1.noop, - afterBuildTicks: function(ticks) { - var me = this; - // ticks is empty for old axis implementations here - if (helpers$1.isArray(ticks) && ticks.length) { - return helpers$1.callback(me.options.afterBuildTicks, [me, ticks]); - } - // Support old implementations (that modified `this.ticks` directly in buildTicks) - me.ticks = helpers$1.callback(me.options.afterBuildTicks, [me, me.ticks]) || me.ticks; - return ticks; - }, - - beforeTickToLabelConversion: function() { - helpers$1.callback(this.options.beforeTickToLabelConversion, [this]); - }, - convertTicksToLabels: function() { - var me = this; - // Convert ticks to strings - var tickOpts = me.options.ticks; - me.ticks = me.ticks.map(tickOpts.userCallback || tickOpts.callback, this); - }, - afterTickToLabelConversion: function() { - helpers$1.callback(this.options.afterTickToLabelConversion, [this]); - }, - - // - - beforeCalculateTickRotation: function() { - helpers$1.callback(this.options.beforeCalculateTickRotation, [this]); - }, - calculateTickRotation: function() { - var me = this; - var context = me.ctx; - var tickOpts = me.options.ticks; - var labels = labelsFromTicks(me._ticks); - - // Get the width of each grid by calculating the difference - // between x offsets between 0 and 1. - var tickFont = helpers$1.options._parseFont(tickOpts); - context.font = tickFont.string; - - var labelRotation = tickOpts.minRotation || 0; - - if (labels.length && me.options.display && me.isHorizontal()) { - var originalLabelWidth = helpers$1.longestText(context, tickFont.string, labels, me.longestTextCache); - var labelWidth = originalLabelWidth; - var cosRotation, sinRotation; - - // Allow 3 pixels x2 padding either side for label readability - var tickWidth = me.getPixelForTick(1) - me.getPixelForTick(0) - 6; - - // Max label rotation can be set or default to 90 - also act as a loop counter - while (labelWidth > tickWidth && labelRotation < tickOpts.maxRotation) { - var angleRadians = helpers$1.toRadians(labelRotation); - cosRotation = Math.cos(angleRadians); - sinRotation = Math.sin(angleRadians); - - if (sinRotation * originalLabelWidth > me.maxHeight) { - // go back one step - labelRotation--; - break; - } - - labelRotation++; - labelWidth = cosRotation * originalLabelWidth; - } - } - - me.labelRotation = labelRotation; - }, - afterCalculateTickRotation: function() { - helpers$1.callback(this.options.afterCalculateTickRotation, [this]); - }, - - // - - beforeFit: function() { - helpers$1.callback(this.options.beforeFit, [this]); - }, - fit: function() { - var me = this; - // Reset - var minSize = me.minSize = { - width: 0, - height: 0 - }; - - var labels = labelsFromTicks(me._ticks); - - var opts = me.options; - var tickOpts = opts.ticks; - var scaleLabelOpts = opts.scaleLabel; - var gridLineOpts = opts.gridLines; - var display = me._isVisible(); - var position = opts.position; - var isHorizontal = me.isHorizontal(); - - var parseFont = helpers$1.options._parseFont; - var tickFont = parseFont(tickOpts); - var tickMarkLength = opts.gridLines.tickMarkLength; - - // Width - if (isHorizontal) { - // subtract the margins to line up with the chartArea if we are a full width scale - minSize.width = me.isFullWidth() ? me.maxWidth - me.margins.left - me.margins.right : me.maxWidth; - } else { - minSize.width = display && gridLineOpts.drawTicks ? tickMarkLength : 0; - } - - // height - if (isHorizontal) { - minSize.height = display && gridLineOpts.drawTicks ? tickMarkLength : 0; - } else { - minSize.height = me.maxHeight; // fill all the height - } - - // Are we showing a title for the scale? - if (scaleLabelOpts.display && display) { - var scaleLabelFont = parseFont(scaleLabelOpts); - var scaleLabelPadding = helpers$1.options.toPadding(scaleLabelOpts.padding); - var deltaHeight = scaleLabelFont.lineHeight + scaleLabelPadding.height; - - if (isHorizontal) { - minSize.height += deltaHeight; - } else { - minSize.width += deltaHeight; - } - } - - // Don't bother fitting the ticks if we are not showing the labels - if (tickOpts.display && display) { - var largestTextWidth = helpers$1.longestText(me.ctx, tickFont.string, labels, me.longestTextCache); - var tallestLabelHeightInLines = helpers$1.numberOfLabelLines(labels); - var lineSpace = tickFont.size * 0.5; - var tickPadding = me.options.ticks.padding; - - // Store max number of lines and widest label for _autoSkip - me._maxLabelLines = tallestLabelHeightInLines; - me.longestLabelWidth = largestTextWidth; - - if (isHorizontal) { - var angleRadians = helpers$1.toRadians(me.labelRotation); - var cosRotation = Math.cos(angleRadians); - var sinRotation = Math.sin(angleRadians); - - // TODO - improve this calculation - var labelHeight = (sinRotation * largestTextWidth) - + (tickFont.lineHeight * tallestLabelHeightInLines) - + lineSpace; // padding - - minSize.height = Math.min(me.maxHeight, minSize.height + labelHeight + tickPadding); - - me.ctx.font = tickFont.string; - var firstLabelWidth = computeTextSize(me.ctx, labels[0], tickFont.string); - var lastLabelWidth = computeTextSize(me.ctx, labels[labels.length - 1], tickFont.string); - var offsetLeft = me.getPixelForTick(0) - me.left; - var offsetRight = me.right - me.getPixelForTick(labels.length - 1); - var paddingLeft, paddingRight; - - // Ensure that our ticks are always inside the canvas. When rotated, ticks are right aligned - // which means that the right padding is dominated by the font height - if (me.labelRotation !== 0) { - paddingLeft = position === 'bottom' ? (cosRotation * firstLabelWidth) : (cosRotation * lineSpace); - paddingRight = position === 'bottom' ? (cosRotation * lineSpace) : (cosRotation * lastLabelWidth); - } else { - paddingLeft = firstLabelWidth / 2; - paddingRight = lastLabelWidth / 2; - } - me.paddingLeft = Math.max(paddingLeft - offsetLeft, 0) + 3; // add 3 px to move away from canvas edges - me.paddingRight = Math.max(paddingRight - offsetRight, 0) + 3; - } else { - // A vertical axis is more constrained by the width. Labels are the - // dominant factor here, so get that length first and account for padding - if (tickOpts.mirror) { - largestTextWidth = 0; - } else { - // use lineSpace for consistency with horizontal axis - // tickPadding is not implemented for horizontal - largestTextWidth += tickPadding + lineSpace; - } - - minSize.width = Math.min(me.maxWidth, minSize.width + largestTextWidth); - - me.paddingTop = tickFont.size / 2; - me.paddingBottom = tickFont.size / 2; - } - } - - me.handleMargins(); - - me.width = minSize.width; - me.height = minSize.height; - }, - - /** - * Handle margins and padding interactions - * @private - */ - handleMargins: function() { - var me = this; - if (me.margins) { - me.paddingLeft = Math.max(me.paddingLeft - me.margins.left, 0); - me.paddingTop = Math.max(me.paddingTop - me.margins.top, 0); - me.paddingRight = Math.max(me.paddingRight - me.margins.right, 0); - me.paddingBottom = Math.max(me.paddingBottom - me.margins.bottom, 0); - } - }, - - afterFit: function() { - helpers$1.callback(this.options.afterFit, [this]); - }, - - // Shared Methods - isHorizontal: function() { - return this.options.position === 'top' || this.options.position === 'bottom'; - }, - isFullWidth: function() { - return (this.options.fullWidth); - }, - - // Get the correct value. NaN bad inputs, If the value type is object get the x or y based on whether we are horizontal or not - getRightValue: function(rawValue) { - // Null and undefined values first - if (helpers$1.isNullOrUndef(rawValue)) { - return NaN; - } - // isNaN(object) returns true, so make sure NaN is checking for a number; Discard Infinite values - if ((typeof rawValue === 'number' || rawValue instanceof Number) && !isFinite(rawValue)) { - return NaN; - } - // If it is in fact an object, dive in one more level - if (rawValue) { - if (this.isHorizontal()) { - if (rawValue.x !== undefined) { - return this.getRightValue(rawValue.x); - } - } else if (rawValue.y !== undefined) { - return this.getRightValue(rawValue.y); - } - } - - // Value is good, return it - return rawValue; - }, - - /** - * Used to get the value to display in the tooltip for the data at the given index - * @param index - * @param datasetIndex - */ - getLabelForIndex: helpers$1.noop, - - /** - * Returns the location of the given data point. Value can either be an index or a numerical value - * The coordinate (0, 0) is at the upper-left corner of the canvas - * @param value - * @param index - * @param datasetIndex - */ - getPixelForValue: helpers$1.noop, - - /** - * Used to get the data value from a given pixel. This is the inverse of getPixelForValue - * The coordinate (0, 0) is at the upper-left corner of the canvas - * @param pixel - */ - getValueForPixel: helpers$1.noop, - - /** - * Returns the location of the tick at the given index - * The coordinate (0, 0) is at the upper-left corner of the canvas - */ - getPixelForTick: function(index) { - var me = this; - var offset = me.options.offset; - if (me.isHorizontal()) { - var innerWidth = me.width - (me.paddingLeft + me.paddingRight); - var tickWidth = innerWidth / Math.max((me._ticks.length - (offset ? 0 : 1)), 1); - var pixel = (tickWidth * index) + me.paddingLeft; - - if (offset) { - pixel += tickWidth / 2; - } - - var finalVal = me.left + pixel; - finalVal += me.isFullWidth() ? me.margins.left : 0; - return finalVal; - } - var innerHeight = me.height - (me.paddingTop + me.paddingBottom); - return me.top + (index * (innerHeight / (me._ticks.length - 1))); - }, - - /** - * Utility for getting the pixel location of a percentage of scale - * The coordinate (0, 0) is at the upper-left corner of the canvas - */ - getPixelForDecimal: function(decimal) { - var me = this; - if (me.isHorizontal()) { - var innerWidth = me.width - (me.paddingLeft + me.paddingRight); - var valueOffset = (innerWidth * decimal) + me.paddingLeft; - - var finalVal = me.left + valueOffset; - finalVal += me.isFullWidth() ? me.margins.left : 0; - return finalVal; - } - return me.top + (decimal * me.height); - }, - - /** - * Returns the pixel for the minimum chart value - * The coordinate (0, 0) is at the upper-left corner of the canvas - */ - getBasePixel: function() { - return this.getPixelForValue(this.getBaseValue()); - }, - - getBaseValue: function() { - var me = this; - var min = me.min; - var max = me.max; - - return me.beginAtZero ? 0 : - min < 0 && max < 0 ? max : - min > 0 && max > 0 ? min : - 0; - }, - - /** - * Returns a subset of ticks to be plotted to avoid overlapping labels. - * @private - */ - _autoSkip: function(ticks) { - var me = this; - var isHorizontal = me.isHorizontal(); - var optionTicks = me.options.ticks.minor; - var tickCount = ticks.length; - var skipRatio = false; - var maxTicks = optionTicks.maxTicksLimit; - - // Total space needed to display all ticks. First and last ticks are - // drawn as their center at end of axis, so tickCount-1 - var ticksLength = me._tickSize() * (tickCount - 1); - - // Axis length - var axisLength = isHorizontal - ? me.width - (me.paddingLeft + me.paddingRight) - : me.height - (me.paddingTop + me.PaddingBottom); - - var result = []; - var i, tick; - - if (ticksLength > axisLength) { - skipRatio = 1 + Math.floor(ticksLength / axisLength); - } - - // if they defined a max number of optionTicks, - // increase skipRatio until that number is met - if (tickCount > maxTicks) { - skipRatio = Math.max(skipRatio, 1 + Math.floor(tickCount / maxTicks)); - } - - for (i = 0; i < tickCount; i++) { - tick = ticks[i]; - - if (skipRatio > 1 && i % skipRatio > 0) { - // leave tick in place but make sure it's not displayed (#4635) - delete tick.label; - } - result.push(tick); - } - return result; - }, - - /** - * @private - */ - _tickSize: function() { - var me = this; - var isHorizontal = me.isHorizontal(); - var optionTicks = me.options.ticks.minor; - - // Calculate space needed by label in axis direction. - var rot = helpers$1.toRadians(me.labelRotation); - var cos = Math.abs(Math.cos(rot)); - var sin = Math.abs(Math.sin(rot)); - - var padding = optionTicks.autoSkipPadding || 0; - var w = (me.longestLabelWidth + padding) || 0; - - var tickFont = helpers$1.options._parseFont(optionTicks); - var h = (me._maxLabelLines * tickFont.lineHeight + padding) || 0; - - // Calculate space needed for 1 tick in axis direction. - return isHorizontal - ? h * cos > w * sin ? w / cos : h / sin - : h * sin < w * cos ? h / cos : w / sin; - }, - - /** - * @private - */ - _isVisible: function() { - var me = this; - var chart = me.chart; - var display = me.options.display; - var i, ilen, meta; - - if (display !== 'auto') { - return !!display; - } - - // When 'auto', the scale is visible if at least one associated dataset is visible. - for (i = 0, ilen = chart.data.datasets.length; i < ilen; ++i) { - if (chart.isDatasetVisible(i)) { - meta = chart.getDatasetMeta(i); - if (meta.xAxisID === me.id || meta.yAxisID === me.id) { - return true; - } - } - } - - return false; - }, - - /** - * Actually draw the scale on the canvas - * @param {object} chartArea - the area of the chart to draw full grid lines on - */ - draw: function(chartArea) { - var me = this; - var options = me.options; - - if (!me._isVisible()) { - return; - } - - var chart = me.chart; - var context = me.ctx; - var globalDefaults = core_defaults.global; - var defaultFontColor = globalDefaults.defaultFontColor; - var optionTicks = options.ticks.minor; - var optionMajorTicks = options.ticks.major || optionTicks; - var gridLines = options.gridLines; - var scaleLabel = options.scaleLabel; - var position = options.position; - - var isRotated = me.labelRotation !== 0; - var isMirrored = optionTicks.mirror; - var isHorizontal = me.isHorizontal(); - - var parseFont = helpers$1.options._parseFont; - var ticks = optionTicks.display && optionTicks.autoSkip ? me._autoSkip(me.getTicks()) : me.getTicks(); - var tickFontColor = valueOrDefault$9(optionTicks.fontColor, defaultFontColor); - var tickFont = parseFont(optionTicks); - var lineHeight = tickFont.lineHeight; - var majorTickFontColor = valueOrDefault$9(optionMajorTicks.fontColor, defaultFontColor); - var majorTickFont = parseFont(optionMajorTicks); - var tickPadding = optionTicks.padding; - var labelOffset = optionTicks.labelOffset; - - var tl = gridLines.drawTicks ? gridLines.tickMarkLength : 0; - - var scaleLabelFontColor = valueOrDefault$9(scaleLabel.fontColor, defaultFontColor); - var scaleLabelFont = parseFont(scaleLabel); - var scaleLabelPadding = helpers$1.options.toPadding(scaleLabel.padding); - var labelRotationRadians = helpers$1.toRadians(me.labelRotation); - - var itemsToDraw = []; - - var axisWidth = gridLines.drawBorder ? valueAtIndexOrDefault(gridLines.lineWidth, 0, 0) : 0; - var alignPixel = helpers$1._alignPixel; - var borderValue, tickStart, tickEnd; - - if (position === 'top') { - borderValue = alignPixel(chart, me.bottom, axisWidth); - tickStart = me.bottom - tl; - tickEnd = borderValue - axisWidth / 2; - } else if (position === 'bottom') { - borderValue = alignPixel(chart, me.top, axisWidth); - tickStart = borderValue + axisWidth / 2; - tickEnd = me.top + tl; - } else if (position === 'left') { - borderValue = alignPixel(chart, me.right, axisWidth); - tickStart = me.right - tl; - tickEnd = borderValue - axisWidth / 2; - } else { - borderValue = alignPixel(chart, me.left, axisWidth); - tickStart = borderValue + axisWidth / 2; - tickEnd = me.left + tl; - } - - var epsilon = 0.0000001; // 0.0000001 is margin in pixels for Accumulated error. - - helpers$1.each(ticks, function(tick, index) { - // autoskipper skipped this tick (#4635) - if (helpers$1.isNullOrUndef(tick.label)) { - return; - } - - var label = tick.label; - var lineWidth, lineColor, borderDash, borderDashOffset; - if (index === me.zeroLineIndex && options.offset === gridLines.offsetGridLines) { - // Draw the first index specially - lineWidth = gridLines.zeroLineWidth; - lineColor = gridLines.zeroLineColor; - borderDash = gridLines.zeroLineBorderDash || []; - borderDashOffset = gridLines.zeroLineBorderDashOffset || 0.0; - } else { - lineWidth = valueAtIndexOrDefault(gridLines.lineWidth, index); - lineColor = valueAtIndexOrDefault(gridLines.color, index); - borderDash = gridLines.borderDash || []; - borderDashOffset = gridLines.borderDashOffset || 0.0; - } - - // Common properties - var tx1, ty1, tx2, ty2, x1, y1, x2, y2, labelX, labelY, textOffset, textAlign; - var labelCount = helpers$1.isArray(label) ? label.length : 1; - var lineValue = getPixelForGridLine(me, index, gridLines.offsetGridLines); - - if (isHorizontal) { - var labelYOffset = tl + tickPadding; - - if (lineValue < me.left - epsilon) { - lineColor = 'rgba(0,0,0,0)'; - } - - tx1 = tx2 = x1 = x2 = alignPixel(chart, lineValue, lineWidth); - ty1 = tickStart; - ty2 = tickEnd; - labelX = me.getPixelForTick(index) + labelOffset; // x values for optionTicks (need to consider offsetLabel option) - - if (position === 'top') { - y1 = alignPixel(chart, chartArea.top, axisWidth) + axisWidth / 2; - y2 = chartArea.bottom; - textOffset = ((!isRotated ? 0.5 : 1) - labelCount) * lineHeight; - textAlign = !isRotated ? 'center' : 'left'; - labelY = me.bottom - labelYOffset; - } else { - y1 = chartArea.top; - y2 = alignPixel(chart, chartArea.bottom, axisWidth) - axisWidth / 2; - textOffset = (!isRotated ? 0.5 : 0) * lineHeight; - textAlign = !isRotated ? 'center' : 'right'; - labelY = me.top + labelYOffset; - } - } else { - var labelXOffset = (isMirrored ? 0 : tl) + tickPadding; - - if (lineValue < me.top - epsilon) { - lineColor = 'rgba(0,0,0,0)'; - } - - tx1 = tickStart; - tx2 = tickEnd; - ty1 = ty2 = y1 = y2 = alignPixel(chart, lineValue, lineWidth); - labelY = me.getPixelForTick(index) + labelOffset; - textOffset = (1 - labelCount) * lineHeight / 2; - - if (position === 'left') { - x1 = alignPixel(chart, chartArea.left, axisWidth) + axisWidth / 2; - x2 = chartArea.right; - textAlign = isMirrored ? 'left' : 'right'; - labelX = me.right - labelXOffset; - } else { - x1 = chartArea.left; - x2 = alignPixel(chart, chartArea.right, axisWidth) - axisWidth / 2; - textAlign = isMirrored ? 'right' : 'left'; - labelX = me.left + labelXOffset; - } - } - - itemsToDraw.push({ - tx1: tx1, - ty1: ty1, - tx2: tx2, - ty2: ty2, - x1: x1, - y1: y1, - x2: x2, - y2: y2, - labelX: labelX, - labelY: labelY, - glWidth: lineWidth, - glColor: lineColor, - glBorderDash: borderDash, - glBorderDashOffset: borderDashOffset, - rotation: -1 * labelRotationRadians, - label: label, - major: tick.major, - textOffset: textOffset, - textAlign: textAlign - }); - }); - - // Draw all of the tick labels, tick marks, and grid lines at the correct places - helpers$1.each(itemsToDraw, function(itemToDraw) { - var glWidth = itemToDraw.glWidth; - var glColor = itemToDraw.glColor; - - if (gridLines.display && glWidth && glColor) { - context.save(); - context.lineWidth = glWidth; - context.strokeStyle = glColor; - if (context.setLineDash) { - context.setLineDash(itemToDraw.glBorderDash); - context.lineDashOffset = itemToDraw.glBorderDashOffset; - } - - context.beginPath(); - - if (gridLines.drawTicks) { - context.moveTo(itemToDraw.tx1, itemToDraw.ty1); - context.lineTo(itemToDraw.tx2, itemToDraw.ty2); - } - - if (gridLines.drawOnChartArea) { - context.moveTo(itemToDraw.x1, itemToDraw.y1); - context.lineTo(itemToDraw.x2, itemToDraw.y2); - } - - context.stroke(); - context.restore(); - } - - if (optionTicks.display) { - // Make sure we draw text in the correct color and font - context.save(); - context.translate(itemToDraw.labelX, itemToDraw.labelY); - context.rotate(itemToDraw.rotation); - context.font = itemToDraw.major ? majorTickFont.string : tickFont.string; - context.fillStyle = itemToDraw.major ? majorTickFontColor : tickFontColor; - context.textBaseline = 'middle'; - context.textAlign = itemToDraw.textAlign; - - var label = itemToDraw.label; - var y = itemToDraw.textOffset; - if (helpers$1.isArray(label)) { - for (var i = 0; i < label.length; ++i) { - // We just make sure the multiline element is a string here.. - context.fillText('' + label[i], 0, y); - y += lineHeight; - } - } else { - context.fillText(label, 0, y); - } - context.restore(); - } - }); - - if (scaleLabel.display) { - // Draw the scale label - var scaleLabelX; - var scaleLabelY; - var rotation = 0; - var halfLineHeight = scaleLabelFont.lineHeight / 2; - - if (isHorizontal) { - scaleLabelX = me.left + ((me.right - me.left) / 2); // midpoint of the width - scaleLabelY = position === 'bottom' - ? me.bottom - halfLineHeight - scaleLabelPadding.bottom - : me.top + halfLineHeight + scaleLabelPadding.top; - } else { - var isLeft = position === 'left'; - scaleLabelX = isLeft - ? me.left + halfLineHeight + scaleLabelPadding.top - : me.right - halfLineHeight - scaleLabelPadding.top; - scaleLabelY = me.top + ((me.bottom - me.top) / 2); - rotation = isLeft ? -0.5 * Math.PI : 0.5 * Math.PI; - } - - context.save(); - context.translate(scaleLabelX, scaleLabelY); - context.rotate(rotation); - context.textAlign = 'center'; - context.textBaseline = 'middle'; - context.fillStyle = scaleLabelFontColor; // render in correct colour - context.font = scaleLabelFont.string; - context.fillText(scaleLabel.labelString, 0, 0); - context.restore(); - } - - if (axisWidth) { - // Draw the line at the edge of the axis - var firstLineWidth = axisWidth; - var lastLineWidth = valueAtIndexOrDefault(gridLines.lineWidth, ticks.length - 1, 0); - var x1, x2, y1, y2; - - if (isHorizontal) { - x1 = alignPixel(chart, me.left, firstLineWidth) - firstLineWidth / 2; - x2 = alignPixel(chart, me.right, lastLineWidth) + lastLineWidth / 2; - y1 = y2 = borderValue; - } else { - y1 = alignPixel(chart, me.top, firstLineWidth) - firstLineWidth / 2; - y2 = alignPixel(chart, me.bottom, lastLineWidth) + lastLineWidth / 2; - x1 = x2 = borderValue; - } - - context.lineWidth = axisWidth; - context.strokeStyle = valueAtIndexOrDefault(gridLines.color, 0); - context.beginPath(); - context.moveTo(x1, y1); - context.lineTo(x2, y2); - context.stroke(); - } - } -}); - -var defaultConfig = { - position: 'bottom' -}; - -var scale_category = core_scale.extend({ - /** - * Internal function to get the correct labels. If data.xLabels or data.yLabels are defined, use those - * else fall back to data.labels - * @private - */ - getLabels: function() { - var data = this.chart.data; - return this.options.labels || (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels; - }, - - determineDataLimits: function() { - var me = this; - var labels = me.getLabels(); - me.minIndex = 0; - me.maxIndex = labels.length - 1; - var findIndex; - - if (me.options.ticks.min !== undefined) { - // user specified min value - findIndex = labels.indexOf(me.options.ticks.min); - me.minIndex = findIndex !== -1 ? findIndex : me.minIndex; - } - - if (me.options.ticks.max !== undefined) { - // user specified max value - findIndex = labels.indexOf(me.options.ticks.max); - me.maxIndex = findIndex !== -1 ? findIndex : me.maxIndex; - } - - me.min = labels[me.minIndex]; - me.max = labels[me.maxIndex]; - }, - - buildTicks: function() { - var me = this; - var labels = me.getLabels(); - // If we are viewing some subset of labels, slice the original array - me.ticks = (me.minIndex === 0 && me.maxIndex === labels.length - 1) ? labels : labels.slice(me.minIndex, me.maxIndex + 1); - }, - - getLabelForIndex: function(index, datasetIndex) { - var me = this; - var chart = me.chart; - - if (chart.getDatasetMeta(datasetIndex).controller._getValueScaleId() === me.id) { - return me.getRightValue(chart.data.datasets[datasetIndex].data[index]); - } - - return me.ticks[index - me.minIndex]; - }, - - // Used to get data value locations. Value can either be an index or a numerical value - getPixelForValue: function(value, index) { - var me = this; - var offset = me.options.offset; - // 1 is added because we need the length but we have the indexes - var offsetAmt = Math.max((me.maxIndex + 1 - me.minIndex - (offset ? 0 : 1)), 1); - - // If value is a data object, then index is the index in the data array, - // not the index of the scale. We need to change that. - var valueCategory; - if (value !== undefined && value !== null) { - valueCategory = me.isHorizontal() ? value.x : value.y; - } - if (valueCategory !== undefined || (value !== undefined && isNaN(index))) { - var labels = me.getLabels(); - value = valueCategory || value; - var idx = labels.indexOf(value); - index = idx !== -1 ? idx : index; - } - - if (me.isHorizontal()) { - var valueWidth = me.width / offsetAmt; - var widthOffset = (valueWidth * (index - me.minIndex)); - - if (offset) { - widthOffset += (valueWidth / 2); - } - - return me.left + widthOffset; - } - var valueHeight = me.height / offsetAmt; - var heightOffset = (valueHeight * (index - me.minIndex)); - - if (offset) { - heightOffset += (valueHeight / 2); - } - - return me.top + heightOffset; - }, - - getPixelForTick: function(index) { - return this.getPixelForValue(this.ticks[index], index + this.minIndex, null); - }, - - getValueForPixel: function(pixel) { - var me = this; - var offset = me.options.offset; - var value; - var offsetAmt = Math.max((me._ticks.length - (offset ? 0 : 1)), 1); - var horz = me.isHorizontal(); - var valueDimension = (horz ? me.width : me.height) / offsetAmt; - - pixel -= horz ? me.left : me.top; - - if (offset) { - pixel -= (valueDimension / 2); - } - - if (pixel <= 0) { - value = 0; - } else { - value = Math.round(pixel / valueDimension); - } - - return value + me.minIndex; - }, - - getBasePixel: function() { - return this.bottom; - } -}); - -// INTERNAL: static default options, registered in src/index.js -var _defaults = defaultConfig; -scale_category._defaults = _defaults; - -var noop = helpers$1.noop; -var isNullOrUndef = helpers$1.isNullOrUndef; - -/** - * Generate a set of linear ticks - * @param generationOptions the options used to generate the ticks - * @param dataRange the range of the data - * @returns {number[]} array of tick values - */ -function generateTicks(generationOptions, dataRange) { - var ticks = []; - // To get a "nice" value for the tick spacing, we will use the appropriately named - // "nice number" algorithm. See https://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks - // for details. - - var MIN_SPACING = 1e-14; - var stepSize = generationOptions.stepSize; - var unit = stepSize || 1; - var maxNumSpaces = generationOptions.maxTicks - 1; - var min = generationOptions.min; - var max = generationOptions.max; - var precision = generationOptions.precision; - var rmin = dataRange.min; - var rmax = dataRange.max; - var spacing = helpers$1.niceNum((rmax - rmin) / maxNumSpaces / unit) * unit; - var factor, niceMin, niceMax, numSpaces; - - // Beyond MIN_SPACING floating point numbers being to lose precision - // such that we can't do the math necessary to generate ticks - if (spacing < MIN_SPACING && isNullOrUndef(min) && isNullOrUndef(max)) { - return [rmin, rmax]; - } - - numSpaces = Math.ceil(rmax / spacing) - Math.floor(rmin / spacing); - if (numSpaces > maxNumSpaces) { - // If the calculated num of spaces exceeds maxNumSpaces, recalculate it - spacing = helpers$1.niceNum(numSpaces * spacing / maxNumSpaces / unit) * unit; - } - - if (stepSize || isNullOrUndef(precision)) { - // If a precision is not specified, calculate factor based on spacing - factor = Math.pow(10, helpers$1._decimalPlaces(spacing)); - } else { - // If the user specified a precision, round to that number of decimal places - factor = Math.pow(10, precision); - spacing = Math.ceil(spacing * factor) / factor; - } - - niceMin = Math.floor(rmin / spacing) * spacing; - niceMax = Math.ceil(rmax / spacing) * spacing; - - // If min, max and stepSize is set and they make an evenly spaced scale use it. - if (stepSize) { - // If very close to our whole number, use it. - if (!isNullOrUndef(min) && helpers$1.almostWhole(min / spacing, spacing / 1000)) { - niceMin = min; - } - if (!isNullOrUndef(max) && helpers$1.almostWhole(max / spacing, spacing / 1000)) { - niceMax = max; - } - } - - numSpaces = (niceMax - niceMin) / spacing; - // If very close to our rounded value, use it. - if (helpers$1.almostEquals(numSpaces, Math.round(numSpaces), spacing / 1000)) { - numSpaces = Math.round(numSpaces); - } else { - numSpaces = Math.ceil(numSpaces); - } - - niceMin = Math.round(niceMin * factor) / factor; - niceMax = Math.round(niceMax * factor) / factor; - ticks.push(isNullOrUndef(min) ? niceMin : min); - for (var j = 1; j < numSpaces; ++j) { - ticks.push(Math.round((niceMin + j * spacing) * factor) / factor); - } - ticks.push(isNullOrUndef(max) ? niceMax : max); - - return ticks; -} - -var scale_linearbase = core_scale.extend({ - getRightValue: function(value) { - if (typeof value === 'string') { - return +value; - } - return core_scale.prototype.getRightValue.call(this, value); - }, - - handleTickRangeOptions: function() { - var me = this; - var opts = me.options; - var tickOpts = opts.ticks; - - // If we are forcing it to begin at 0, but 0 will already be rendered on the chart, - // do nothing since that would make the chart weird. If the user really wants a weird chart - // axis, they can manually override it - if (tickOpts.beginAtZero) { - var minSign = helpers$1.sign(me.min); - var maxSign = helpers$1.sign(me.max); - - if (minSign < 0 && maxSign < 0) { - // move the top up to 0 - me.max = 0; - } else if (minSign > 0 && maxSign > 0) { - // move the bottom down to 0 - me.min = 0; - } - } - - var setMin = tickOpts.min !== undefined || tickOpts.suggestedMin !== undefined; - var setMax = tickOpts.max !== undefined || tickOpts.suggestedMax !== undefined; - - if (tickOpts.min !== undefined) { - me.min = tickOpts.min; - } else if (tickOpts.suggestedMin !== undefined) { - if (me.min === null) { - me.min = tickOpts.suggestedMin; - } else { - me.min = Math.min(me.min, tickOpts.suggestedMin); - } - } - - if (tickOpts.max !== undefined) { - me.max = tickOpts.max; - } else if (tickOpts.suggestedMax !== undefined) { - if (me.max === null) { - me.max = tickOpts.suggestedMax; - } else { - me.max = Math.max(me.max, tickOpts.suggestedMax); - } - } - - if (setMin !== setMax) { - // We set the min or the max but not both. - // So ensure that our range is good - // Inverted or 0 length range can happen when - // ticks.min is set, and no datasets are visible - if (me.min >= me.max) { - if (setMin) { - me.max = me.min + 1; - } else { - me.min = me.max - 1; - } - } - } - - if (me.min === me.max) { - me.max++; - - if (!tickOpts.beginAtZero) { - me.min--; - } - } - }, - - getTickLimit: function() { - var me = this; - var tickOpts = me.options.ticks; - var stepSize = tickOpts.stepSize; - var maxTicksLimit = tickOpts.maxTicksLimit; - var maxTicks; - - if (stepSize) { - maxTicks = Math.ceil(me.max / stepSize) - Math.floor(me.min / stepSize) + 1; - } else { - maxTicks = me._computeTickLimit(); - maxTicksLimit = maxTicksLimit || 11; - } - - if (maxTicksLimit) { - maxTicks = Math.min(maxTicksLimit, maxTicks); - } - - return maxTicks; - }, - - _computeTickLimit: function() { - return Number.POSITIVE_INFINITY; - }, - - handleDirectionalChanges: noop, - - buildTicks: function() { - var me = this; - var opts = me.options; - var tickOpts = opts.ticks; - - // Figure out what the max number of ticks we can support it is based on the size of - // the axis area. For now, we say that the minimum tick spacing in pixels must be 40 - // We also limit the maximum number of ticks to 11 which gives a nice 10 squares on - // the graph. Make sure we always have at least 2 ticks - var maxTicks = me.getTickLimit(); - maxTicks = Math.max(2, maxTicks); - - var numericGeneratorOptions = { - maxTicks: maxTicks, - min: tickOpts.min, - max: tickOpts.max, - precision: tickOpts.precision, - stepSize: helpers$1.valueOrDefault(tickOpts.fixedStepSize, tickOpts.stepSize) - }; - var ticks = me.ticks = generateTicks(numericGeneratorOptions, me); - - me.handleDirectionalChanges(); - - // At this point, we need to update our max and min given the tick values since we have expanded the - // range of the scale - me.max = helpers$1.max(ticks); - me.min = helpers$1.min(ticks); - - if (tickOpts.reverse) { - ticks.reverse(); - - me.start = me.max; - me.end = me.min; - } else { - me.start = me.min; - me.end = me.max; - } - }, - - convertTicksToLabels: function() { - var me = this; - me.ticksAsNumbers = me.ticks.slice(); - me.zeroLineIndex = me.ticks.indexOf(0); - - core_scale.prototype.convertTicksToLabels.call(me); - } -}); - -var defaultConfig$1 = { - position: 'left', - ticks: { - callback: core_ticks.formatters.linear - } -}; - -var scale_linear = scale_linearbase.extend({ - determineDataLimits: function() { - var me = this; - var opts = me.options; - var chart = me.chart; - var data = chart.data; - var datasets = data.datasets; - var isHorizontal = me.isHorizontal(); - var DEFAULT_MIN = 0; - var DEFAULT_MAX = 1; - - function IDMatches(meta) { - return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id; - } - - // First Calculate the range - me.min = null; - me.max = null; - - var hasStacks = opts.stacked; - if (hasStacks === undefined) { - helpers$1.each(datasets, function(dataset, datasetIndex) { - if (hasStacks) { - return; - } - - var meta = chart.getDatasetMeta(datasetIndex); - if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) && - meta.stack !== undefined) { - hasStacks = true; - } - }); - } - - if (opts.stacked || hasStacks) { - var valuesPerStack = {}; - - helpers$1.each(datasets, function(dataset, datasetIndex) { - var meta = chart.getDatasetMeta(datasetIndex); - var key = [ - meta.type, - // we have a separate stack for stack=undefined datasets when the opts.stacked is undefined - ((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''), - meta.stack - ].join('.'); - - if (valuesPerStack[key] === undefined) { - valuesPerStack[key] = { - positiveValues: [], - negativeValues: [] - }; - } - - // Store these per type - var positiveValues = valuesPerStack[key].positiveValues; - var negativeValues = valuesPerStack[key].negativeValues; - - if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) { - helpers$1.each(dataset.data, function(rawValue, index) { - var value = +me.getRightValue(rawValue); - if (isNaN(value) || meta.data[index].hidden) { - return; - } - - positiveValues[index] = positiveValues[index] || 0; - negativeValues[index] = negativeValues[index] || 0; - - if (opts.relativePoints) { - positiveValues[index] = 100; - } else if (value < 0) { - negativeValues[index] += value; - } else { - positiveValues[index] += value; - } - }); - } - }); - - helpers$1.each(valuesPerStack, function(valuesForType) { - var values = valuesForType.positiveValues.concat(valuesForType.negativeValues); - var minVal = helpers$1.min(values); - var maxVal = helpers$1.max(values); - me.min = me.min === null ? minVal : Math.min(me.min, minVal); - me.max = me.max === null ? maxVal : Math.max(me.max, maxVal); - }); - - } else { - helpers$1.each(datasets, function(dataset, datasetIndex) { - var meta = chart.getDatasetMeta(datasetIndex); - if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) { - helpers$1.each(dataset.data, function(rawValue, index) { - var value = +me.getRightValue(rawValue); - if (isNaN(value) || meta.data[index].hidden) { - return; - } - - if (me.min === null) { - me.min = value; - } else if (value < me.min) { - me.min = value; - } - - if (me.max === null) { - me.max = value; - } else if (value > me.max) { - me.max = value; - } - }); - } - }); - } - - me.min = isFinite(me.min) && !isNaN(me.min) ? me.min : DEFAULT_MIN; - me.max = isFinite(me.max) && !isNaN(me.max) ? me.max : DEFAULT_MAX; - - // Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero - this.handleTickRangeOptions(); - }, - - // Returns the maximum number of ticks based on the scale dimension - _computeTickLimit: function() { - var me = this; - var tickFont; - - if (me.isHorizontal()) { - return Math.ceil(me.width / 40); - } - tickFont = helpers$1.options._parseFont(me.options.ticks); - return Math.ceil(me.height / tickFont.lineHeight); - }, - - // Called after the ticks are built. We need - handleDirectionalChanges: function() { - if (!this.isHorizontal()) { - // We are in a vertical orientation. The top value is the highest. So reverse the array - this.ticks.reverse(); - } - }, - - getLabelForIndex: function(index, datasetIndex) { - return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]); - }, - - // Utils - getPixelForValue: function(value) { - // This must be called after fit has been run so that - // this.left, this.top, this.right, and this.bottom have been defined - var me = this; - var start = me.start; - - var rightValue = +me.getRightValue(value); - var pixel; - var range = me.end - start; - - if (me.isHorizontal()) { - pixel = me.left + (me.width / range * (rightValue - start)); - } else { - pixel = me.bottom - (me.height / range * (rightValue - start)); - } - return pixel; - }, - - getValueForPixel: function(pixel) { - var me = this; - var isHorizontal = me.isHorizontal(); - var innerDimension = isHorizontal ? me.width : me.height; - var offset = (isHorizontal ? pixel - me.left : me.bottom - pixel) / innerDimension; - return me.start + ((me.end - me.start) * offset); - }, - - getPixelForTick: function(index) { - return this.getPixelForValue(this.ticksAsNumbers[index]); - } -}); - -// INTERNAL: static default options, registered in src/index.js -var _defaults$1 = defaultConfig$1; -scale_linear._defaults = _defaults$1; - -var valueOrDefault$a = helpers$1.valueOrDefault; - -/** - * Generate a set of logarithmic ticks - * @param generationOptions the options used to generate the ticks - * @param dataRange the range of the data - * @returns {number[]} array of tick values - */ -function generateTicks$1(generationOptions, dataRange) { - var ticks = []; - - var tickVal = valueOrDefault$a(generationOptions.min, Math.pow(10, Math.floor(helpers$1.log10(dataRange.min)))); - - var endExp = Math.floor(helpers$1.log10(dataRange.max)); - var endSignificand = Math.ceil(dataRange.max / Math.pow(10, endExp)); - var exp, significand; - - if (tickVal === 0) { - exp = Math.floor(helpers$1.log10(dataRange.minNotZero)); - significand = Math.floor(dataRange.minNotZero / Math.pow(10, exp)); - - ticks.push(tickVal); - tickVal = significand * Math.pow(10, exp); - } else { - exp = Math.floor(helpers$1.log10(tickVal)); - significand = Math.floor(tickVal / Math.pow(10, exp)); - } - var precision = exp < 0 ? Math.pow(10, Math.abs(exp)) : 1; - - do { - ticks.push(tickVal); - - ++significand; - if (significand === 10) { - significand = 1; - ++exp; - precision = exp >= 0 ? 1 : precision; - } - - tickVal = Math.round(significand * Math.pow(10, exp) * precision) / precision; - } while (exp < endExp || (exp === endExp && significand < endSignificand)); - - var lastTick = valueOrDefault$a(generationOptions.max, tickVal); - ticks.push(lastTick); - - return ticks; -} - -var defaultConfig$2 = { - position: 'left', - - // label settings - ticks: { - callback: core_ticks.formatters.logarithmic - } -}; - -// TODO(v3): change this to positiveOrDefault -function nonNegativeOrDefault(value, defaultValue) { - return helpers$1.isFinite(value) && value >= 0 ? value : defaultValue; -} - -var scale_logarithmic = core_scale.extend({ - determineDataLimits: function() { - var me = this; - var opts = me.options; - var chart = me.chart; - var data = chart.data; - var datasets = data.datasets; - var isHorizontal = me.isHorizontal(); - function IDMatches(meta) { - return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id; - } - - // Calculate Range - me.min = null; - me.max = null; - me.minNotZero = null; - - var hasStacks = opts.stacked; - if (hasStacks === undefined) { - helpers$1.each(datasets, function(dataset, datasetIndex) { - if (hasStacks) { - return; - } - - var meta = chart.getDatasetMeta(datasetIndex); - if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) && - meta.stack !== undefined) { - hasStacks = true; - } - }); - } - - if (opts.stacked || hasStacks) { - var valuesPerStack = {}; - - helpers$1.each(datasets, function(dataset, datasetIndex) { - var meta = chart.getDatasetMeta(datasetIndex); - var key = [ - meta.type, - // we have a separate stack for stack=undefined datasets when the opts.stacked is undefined - ((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''), - meta.stack - ].join('.'); - - if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) { - if (valuesPerStack[key] === undefined) { - valuesPerStack[key] = []; - } - - helpers$1.each(dataset.data, function(rawValue, index) { - var values = valuesPerStack[key]; - var value = +me.getRightValue(rawValue); - // invalid, hidden and negative values are ignored - if (isNaN(value) || meta.data[index].hidden || value < 0) { - return; - } - values[index] = values[index] || 0; - values[index] += value; - }); - } - }); - - helpers$1.each(valuesPerStack, function(valuesForType) { - if (valuesForType.length > 0) { - var minVal = helpers$1.min(valuesForType); - var maxVal = helpers$1.max(valuesForType); - me.min = me.min === null ? minVal : Math.min(me.min, minVal); - me.max = me.max === null ? maxVal : Math.max(me.max, maxVal); - } - }); - - } else { - helpers$1.each(datasets, function(dataset, datasetIndex) { - var meta = chart.getDatasetMeta(datasetIndex); - if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) { - helpers$1.each(dataset.data, function(rawValue, index) { - var value = +me.getRightValue(rawValue); - // invalid, hidden and negative values are ignored - if (isNaN(value) || meta.data[index].hidden || value < 0) { - return; - } - - if (me.min === null) { - me.min = value; - } else if (value < me.min) { - me.min = value; - } - - if (me.max === null) { - me.max = value; - } else if (value > me.max) { - me.max = value; - } - - if (value !== 0 && (me.minNotZero === null || value < me.minNotZero)) { - me.minNotZero = value; - } - }); - } - }); - } - - // Common base implementation to handle ticks.min, ticks.max - this.handleTickRangeOptions(); - }, - - handleTickRangeOptions: function() { - var me = this; - var tickOpts = me.options.ticks; - var DEFAULT_MIN = 1; - var DEFAULT_MAX = 10; - - me.min = nonNegativeOrDefault(tickOpts.min, me.min); - me.max = nonNegativeOrDefault(tickOpts.max, me.max); - - if (me.min === me.max) { - if (me.min !== 0 && me.min !== null) { - me.min = Math.pow(10, Math.floor(helpers$1.log10(me.min)) - 1); - me.max = Math.pow(10, Math.floor(helpers$1.log10(me.max)) + 1); - } else { - me.min = DEFAULT_MIN; - me.max = DEFAULT_MAX; - } - } - if (me.min === null) { - me.min = Math.pow(10, Math.floor(helpers$1.log10(me.max)) - 1); - } - if (me.max === null) { - me.max = me.min !== 0 - ? Math.pow(10, Math.floor(helpers$1.log10(me.min)) + 1) - : DEFAULT_MAX; - } - if (me.minNotZero === null) { - if (me.min > 0) { - me.minNotZero = me.min; - } else if (me.max < 1) { - me.minNotZero = Math.pow(10, Math.floor(helpers$1.log10(me.max))); - } else { - me.minNotZero = DEFAULT_MIN; - } - } - }, - - buildTicks: function() { - var me = this; - var tickOpts = me.options.ticks; - var reverse = !me.isHorizontal(); - - var generationOptions = { - min: nonNegativeOrDefault(tickOpts.min), - max: nonNegativeOrDefault(tickOpts.max) - }; - var ticks = me.ticks = generateTicks$1(generationOptions, me); - - // At this point, we need to update our max and min given the tick values since we have expanded the - // range of the scale - me.max = helpers$1.max(ticks); - me.min = helpers$1.min(ticks); - - if (tickOpts.reverse) { - reverse = !reverse; - me.start = me.max; - me.end = me.min; - } else { - me.start = me.min; - me.end = me.max; - } - if (reverse) { - ticks.reverse(); - } - }, - - convertTicksToLabels: function() { - this.tickValues = this.ticks.slice(); - - core_scale.prototype.convertTicksToLabels.call(this); - }, - - // Get the correct tooltip label - getLabelForIndex: function(index, datasetIndex) { - return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]); - }, - - getPixelForTick: function(index) { - return this.getPixelForValue(this.tickValues[index]); - }, - - /** - * Returns the value of the first tick. - * @param {number} value - The minimum not zero value. - * @return {number} The first tick value. - * @private - */ - _getFirstTickValue: function(value) { - var exp = Math.floor(helpers$1.log10(value)); - var significand = Math.floor(value / Math.pow(10, exp)); - - return significand * Math.pow(10, exp); - }, - - getPixelForValue: function(value) { - var me = this; - var tickOpts = me.options.ticks; - var reverse = tickOpts.reverse; - var log10 = helpers$1.log10; - var firstTickValue = me._getFirstTickValue(me.minNotZero); - var offset = 0; - var innerDimension, pixel, start, end, sign; - - value = +me.getRightValue(value); - if (reverse) { - start = me.end; - end = me.start; - sign = -1; - } else { - start = me.start; - end = me.end; - sign = 1; - } - if (me.isHorizontal()) { - innerDimension = me.width; - pixel = reverse ? me.right : me.left; - } else { - innerDimension = me.height; - sign *= -1; // invert, since the upper-left corner of the canvas is at pixel (0, 0) - pixel = reverse ? me.top : me.bottom; - } - if (value !== start) { - if (start === 0) { // include zero tick - offset = valueOrDefault$a(tickOpts.fontSize, core_defaults.global.defaultFontSize); - innerDimension -= offset; - start = firstTickValue; - } - if (value !== 0) { - offset += innerDimension / (log10(end) - log10(start)) * (log10(value) - log10(start)); - } - pixel += sign * offset; - } - return pixel; - }, - - getValueForPixel: function(pixel) { - var me = this; - var tickOpts = me.options.ticks; - var reverse = tickOpts.reverse; - var log10 = helpers$1.log10; - var firstTickValue = me._getFirstTickValue(me.minNotZero); - var innerDimension, start, end, value; - - if (reverse) { - start = me.end; - end = me.start; - } else { - start = me.start; - end = me.end; - } - if (me.isHorizontal()) { - innerDimension = me.width; - value = reverse ? me.right - pixel : pixel - me.left; - } else { - innerDimension = me.height; - value = reverse ? pixel - me.top : me.bottom - pixel; - } - if (value !== start) { - if (start === 0) { // include zero tick - var offset = valueOrDefault$a(tickOpts.fontSize, core_defaults.global.defaultFontSize); - value -= offset; - innerDimension -= offset; - start = firstTickValue; - } - value *= log10(end) - log10(start); - value /= innerDimension; - value = Math.pow(10, log10(start) + value); - } - return value; - } -}); - -// INTERNAL: static default options, registered in src/index.js -var _defaults$2 = defaultConfig$2; -scale_logarithmic._defaults = _defaults$2; - -var valueOrDefault$b = helpers$1.valueOrDefault; -var valueAtIndexOrDefault$1 = helpers$1.valueAtIndexOrDefault; -var resolve$7 = helpers$1.options.resolve; - -var defaultConfig$3 = { - display: true, - - // Boolean - Whether to animate scaling the chart from the centre - animate: true, - position: 'chartArea', - - angleLines: { - display: true, - color: 'rgba(0, 0, 0, 0.1)', - lineWidth: 1, - borderDash: [], - borderDashOffset: 0.0 - }, - - gridLines: { - circular: false - }, - - // label settings - ticks: { - // Boolean - Show a backdrop to the scale label - showLabelBackdrop: true, - - // String - The colour of the label backdrop - backdropColor: 'rgba(255,255,255,0.75)', - - // Number - The backdrop padding above & below the label in pixels - backdropPaddingY: 2, - - // Number - The backdrop padding to the side of the label in pixels - backdropPaddingX: 2, - - callback: core_ticks.formatters.linear - }, - - pointLabels: { - // Boolean - if true, show point labels - display: true, - - // Number - Point label font size in pixels - fontSize: 10, - - // Function - Used to convert point labels - callback: function(label) { - return label; - } - } -}; - -function getValueCount(scale) { - var opts = scale.options; - return opts.angleLines.display || opts.pointLabels.display ? scale.chart.data.labels.length : 0; -} - -function getTickBackdropHeight(opts) { - var tickOpts = opts.ticks; - - if (tickOpts.display && opts.display) { - return valueOrDefault$b(tickOpts.fontSize, core_defaults.global.defaultFontSize) + tickOpts.backdropPaddingY * 2; - } - return 0; -} - -function measureLabelSize(ctx, lineHeight, label) { - if (helpers$1.isArray(label)) { - return { - w: helpers$1.longestText(ctx, ctx.font, label), - h: label.length * lineHeight - }; - } - - return { - w: ctx.measureText(label).width, - h: lineHeight - }; -} - -function determineLimits(angle, pos, size, min, max) { - if (angle === min || angle === max) { - return { - start: pos - (size / 2), - end: pos + (size / 2) - }; - } else if (angle < min || angle > max) { - return { - start: pos - size, - end: pos - }; - } - - return { - start: pos, - end: pos + size - }; -} - -/** - * Helper function to fit a radial linear scale with point labels - */ -function fitWithPointLabels(scale) { - - // Right, this is really confusing and there is a lot of maths going on here - // The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9 - // - // Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif - // - // Solution: - // - // We assume the radius of the polygon is half the size of the canvas at first - // at each index we check if the text overlaps. - // - // Where it does, we store that angle and that index. - // - // After finding the largest index and angle we calculate how much we need to remove - // from the shape radius to move the point inwards by that x. - // - // We average the left and right distances to get the maximum shape radius that can fit in the box - // along with labels. - // - // Once we have that, we can find the centre point for the chart, by taking the x text protrusion - // on each side, removing that from the size, halving it and adding the left x protrusion width. - // - // This will mean we have a shape fitted to the canvas, as large as it can be with the labels - // and position it in the most space efficient manner - // - // https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif - - var plFont = helpers$1.options._parseFont(scale.options.pointLabels); - - // Get maximum radius of the polygon. Either half the height (minus the text width) or half the width. - // Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points - var furthestLimits = { - l: 0, - r: scale.width, - t: 0, - b: scale.height - scale.paddingTop - }; - var furthestAngles = {}; - var i, textSize, pointPosition; - - scale.ctx.font = plFont.string; - scale._pointLabelSizes = []; - - var valueCount = getValueCount(scale); - for (i = 0; i < valueCount; i++) { - pointPosition = scale.getPointPosition(i, scale.drawingArea + 5); - textSize = measureLabelSize(scale.ctx, plFont.lineHeight, scale.pointLabels[i] || ''); - scale._pointLabelSizes[i] = textSize; - - // Add quarter circle to make degree 0 mean top of circle - var angleRadians = scale.getIndexAngle(i); - var angle = helpers$1.toDegrees(angleRadians) % 360; - var hLimits = determineLimits(angle, pointPosition.x, textSize.w, 0, 180); - var vLimits = determineLimits(angle, pointPosition.y, textSize.h, 90, 270); - - if (hLimits.start < furthestLimits.l) { - furthestLimits.l = hLimits.start; - furthestAngles.l = angleRadians; - } - - if (hLimits.end > furthestLimits.r) { - furthestLimits.r = hLimits.end; - furthestAngles.r = angleRadians; - } - - if (vLimits.start < furthestLimits.t) { - furthestLimits.t = vLimits.start; - furthestAngles.t = angleRadians; - } - - if (vLimits.end > furthestLimits.b) { - furthestLimits.b = vLimits.end; - furthestAngles.b = angleRadians; - } - } - - scale.setReductions(scale.drawingArea, furthestLimits, furthestAngles); -} - -function getTextAlignForAngle(angle) { - if (angle === 0 || angle === 180) { - return 'center'; - } else if (angle < 180) { - return 'left'; - } - - return 'right'; -} - -function fillText(ctx, text, position, lineHeight) { - var y = position.y + lineHeight / 2; - var i, ilen; - - if (helpers$1.isArray(text)) { - for (i = 0, ilen = text.length; i < ilen; ++i) { - ctx.fillText(text[i], position.x, y); - y += lineHeight; - } - } else { - ctx.fillText(text, position.x, y); - } -} - -function adjustPointPositionForLabelHeight(angle, textSize, position) { - if (angle === 90 || angle === 270) { - position.y -= (textSize.h / 2); - } else if (angle > 270 || angle < 90) { - position.y -= textSize.h; - } -} - -function drawPointLabels(scale) { - var ctx = scale.ctx; - var opts = scale.options; - var angleLineOpts = opts.angleLines; - var gridLineOpts = opts.gridLines; - var pointLabelOpts = opts.pointLabels; - var lineWidth = valueOrDefault$b(angleLineOpts.lineWidth, gridLineOpts.lineWidth); - var lineColor = valueOrDefault$b(angleLineOpts.color, gridLineOpts.color); - var tickBackdropHeight = getTickBackdropHeight(opts); - - ctx.save(); - ctx.lineWidth = lineWidth; - ctx.strokeStyle = lineColor; - if (ctx.setLineDash) { - ctx.setLineDash(resolve$7([angleLineOpts.borderDash, gridLineOpts.borderDash, []])); - ctx.lineDashOffset = resolve$7([angleLineOpts.borderDashOffset, gridLineOpts.borderDashOffset, 0.0]); - } - - var outerDistance = scale.getDistanceFromCenterForValue(opts.ticks.reverse ? scale.min : scale.max); - - // Point Label Font - var plFont = helpers$1.options._parseFont(pointLabelOpts); - - ctx.font = plFont.string; - ctx.textBaseline = 'middle'; - - for (var i = getValueCount(scale) - 1; i >= 0; i--) { - if (angleLineOpts.display && lineWidth && lineColor) { - var outerPosition = scale.getPointPosition(i, outerDistance); - ctx.beginPath(); - ctx.moveTo(scale.xCenter, scale.yCenter); - ctx.lineTo(outerPosition.x, outerPosition.y); - ctx.stroke(); - } - - if (pointLabelOpts.display) { - // Extra pixels out for some label spacing - var extra = (i === 0 ? tickBackdropHeight / 2 : 0); - var pointLabelPosition = scale.getPointPosition(i, outerDistance + extra + 5); - - // Keep this in loop since we may support array properties here - var pointLabelFontColor = valueAtIndexOrDefault$1(pointLabelOpts.fontColor, i, core_defaults.global.defaultFontColor); - ctx.fillStyle = pointLabelFontColor; - - var angleRadians = scale.getIndexAngle(i); - var angle = helpers$1.toDegrees(angleRadians); - ctx.textAlign = getTextAlignForAngle(angle); - adjustPointPositionForLabelHeight(angle, scale._pointLabelSizes[i], pointLabelPosition); - fillText(ctx, scale.pointLabels[i] || '', pointLabelPosition, plFont.lineHeight); - } - } - ctx.restore(); -} - -function drawRadiusLine(scale, gridLineOpts, radius, index) { - var ctx = scale.ctx; - var circular = gridLineOpts.circular; - var valueCount = getValueCount(scale); - var lineColor = valueAtIndexOrDefault$1(gridLineOpts.color, index - 1); - var lineWidth = valueAtIndexOrDefault$1(gridLineOpts.lineWidth, index - 1); - var pointPosition; - - if ((!circular && !valueCount) || !lineColor || !lineWidth) { - return; - } - - ctx.save(); - ctx.strokeStyle = lineColor; - ctx.lineWidth = lineWidth; - if (ctx.setLineDash) { - ctx.setLineDash(gridLineOpts.borderDash || []); - ctx.lineDashOffset = gridLineOpts.borderDashOffset || 0.0; - } - - ctx.beginPath(); - if (circular) { - // Draw circular arcs between the points - ctx.arc(scale.xCenter, scale.yCenter, radius, 0, Math.PI * 2); - } else { - // Draw straight lines connecting each index - pointPosition = scale.getPointPosition(0, radius); - ctx.moveTo(pointPosition.x, pointPosition.y); - - for (var i = 1; i < valueCount; i++) { - pointPosition = scale.getPointPosition(i, radius); - ctx.lineTo(pointPosition.x, pointPosition.y); - } - } - ctx.closePath(); - ctx.stroke(); - ctx.restore(); -} - -function numberOrZero(param) { - return helpers$1.isNumber(param) ? param : 0; -} - -var scale_radialLinear = scale_linearbase.extend({ - setDimensions: function() { - var me = this; - - // Set the unconstrained dimension before label rotation - me.width = me.maxWidth; - me.height = me.maxHeight; - me.paddingTop = getTickBackdropHeight(me.options) / 2; - me.xCenter = Math.floor(me.width / 2); - me.yCenter = Math.floor((me.height - me.paddingTop) / 2); - me.drawingArea = Math.min(me.height - me.paddingTop, me.width) / 2; - }, - - determineDataLimits: function() { - var me = this; - var chart = me.chart; - var min = Number.POSITIVE_INFINITY; - var max = Number.NEGATIVE_INFINITY; - - helpers$1.each(chart.data.datasets, function(dataset, datasetIndex) { - if (chart.isDatasetVisible(datasetIndex)) { - var meta = chart.getDatasetMeta(datasetIndex); - - helpers$1.each(dataset.data, function(rawValue, index) { - var value = +me.getRightValue(rawValue); - if (isNaN(value) || meta.data[index].hidden) { - return; - } - - min = Math.min(value, min); - max = Math.max(value, max); - }); - } - }); - - me.min = (min === Number.POSITIVE_INFINITY ? 0 : min); - me.max = (max === Number.NEGATIVE_INFINITY ? 0 : max); - - // Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero - me.handleTickRangeOptions(); - }, - - // Returns the maximum number of ticks based on the scale dimension - _computeTickLimit: function() { - return Math.ceil(this.drawingArea / getTickBackdropHeight(this.options)); - }, - - convertTicksToLabels: function() { - var me = this; - - scale_linearbase.prototype.convertTicksToLabels.call(me); - - // Point labels - me.pointLabels = me.chart.data.labels.map(me.options.pointLabels.callback, me); - }, - - getLabelForIndex: function(index, datasetIndex) { - return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]); - }, - - fit: function() { - var me = this; - var opts = me.options; - - if (opts.display && opts.pointLabels.display) { - fitWithPointLabels(me); - } else { - me.setCenterPoint(0, 0, 0, 0); - } - }, - - /** - * Set radius reductions and determine new radius and center point - * @private - */ - setReductions: function(largestPossibleRadius, furthestLimits, furthestAngles) { - var me = this; - var radiusReductionLeft = furthestLimits.l / Math.sin(furthestAngles.l); - var radiusReductionRight = Math.max(furthestLimits.r - me.width, 0) / Math.sin(furthestAngles.r); - var radiusReductionTop = -furthestLimits.t / Math.cos(furthestAngles.t); - var radiusReductionBottom = -Math.max(furthestLimits.b - (me.height - me.paddingTop), 0) / Math.cos(furthestAngles.b); - - radiusReductionLeft = numberOrZero(radiusReductionLeft); - radiusReductionRight = numberOrZero(radiusReductionRight); - radiusReductionTop = numberOrZero(radiusReductionTop); - radiusReductionBottom = numberOrZero(radiusReductionBottom); - - me.drawingArea = Math.min( - Math.floor(largestPossibleRadius - (radiusReductionLeft + radiusReductionRight) / 2), - Math.floor(largestPossibleRadius - (radiusReductionTop + radiusReductionBottom) / 2)); - me.setCenterPoint(radiusReductionLeft, radiusReductionRight, radiusReductionTop, radiusReductionBottom); - }, - - setCenterPoint: function(leftMovement, rightMovement, topMovement, bottomMovement) { - var me = this; - var maxRight = me.width - rightMovement - me.drawingArea; - var maxLeft = leftMovement + me.drawingArea; - var maxTop = topMovement + me.drawingArea; - var maxBottom = (me.height - me.paddingTop) - bottomMovement - me.drawingArea; - - me.xCenter = Math.floor(((maxLeft + maxRight) / 2) + me.left); - me.yCenter = Math.floor(((maxTop + maxBottom) / 2) + me.top + me.paddingTop); - }, - - getIndexAngle: function(index) { - var angleMultiplier = (Math.PI * 2) / getValueCount(this); - var startAngle = this.chart.options && this.chart.options.startAngle ? - this.chart.options.startAngle : - 0; - - var startAngleRadians = startAngle * Math.PI * 2 / 360; - - // Start from the top instead of right, so remove a quarter of the circle - return index * angleMultiplier + startAngleRadians; - }, - - getDistanceFromCenterForValue: function(value) { - var me = this; - - if (value === null) { - return 0; // null always in center - } - - // Take into account half font size + the yPadding of the top value - var scalingFactor = me.drawingArea / (me.max - me.min); - if (me.options.ticks.reverse) { - return (me.max - value) * scalingFactor; - } - return (value - me.min) * scalingFactor; - }, - - getPointPosition: function(index, distanceFromCenter) { - var me = this; - var thisAngle = me.getIndexAngle(index) - (Math.PI / 2); - return { - x: Math.cos(thisAngle) * distanceFromCenter + me.xCenter, - y: Math.sin(thisAngle) * distanceFromCenter + me.yCenter - }; - }, - - getPointPositionForValue: function(index, value) { - return this.getPointPosition(index, this.getDistanceFromCenterForValue(value)); - }, - - getBasePosition: function() { - var me = this; - var min = me.min; - var max = me.max; - - return me.getPointPositionForValue(0, - me.beginAtZero ? 0 : - min < 0 && max < 0 ? max : - min > 0 && max > 0 ? min : - 0); - }, - - draw: function() { - var me = this; - var opts = me.options; - var gridLineOpts = opts.gridLines; - var tickOpts = opts.ticks; - - if (opts.display) { - var ctx = me.ctx; - var startAngle = this.getIndexAngle(0); - var tickFont = helpers$1.options._parseFont(tickOpts); - - if (opts.angleLines.display || opts.pointLabels.display) { - drawPointLabels(me); - } - - helpers$1.each(me.ticks, function(label, index) { - // Don't draw a centre value (if it is minimum) - if (index > 0 || tickOpts.reverse) { - var yCenterOffset = me.getDistanceFromCenterForValue(me.ticksAsNumbers[index]); - - // Draw circular lines around the scale - if (gridLineOpts.display && index !== 0) { - drawRadiusLine(me, gridLineOpts, yCenterOffset, index); - } - - if (tickOpts.display) { - var tickFontColor = valueOrDefault$b(tickOpts.fontColor, core_defaults.global.defaultFontColor); - ctx.font = tickFont.string; - - ctx.save(); - ctx.translate(me.xCenter, me.yCenter); - ctx.rotate(startAngle); - - if (tickOpts.showLabelBackdrop) { - var labelWidth = ctx.measureText(label).width; - ctx.fillStyle = tickOpts.backdropColor; - ctx.fillRect( - -labelWidth / 2 - tickOpts.backdropPaddingX, - -yCenterOffset - tickFont.size / 2 - tickOpts.backdropPaddingY, - labelWidth + tickOpts.backdropPaddingX * 2, - tickFont.size + tickOpts.backdropPaddingY * 2 - ); - } - - ctx.textAlign = 'center'; - ctx.textBaseline = 'middle'; - ctx.fillStyle = tickFontColor; - ctx.fillText(label, 0, -yCenterOffset); - ctx.restore(); - } - } - }); - } - } -}); - -// INTERNAL: static default options, registered in src/index.js -var _defaults$3 = defaultConfig$3; -scale_radialLinear._defaults = _defaults$3; - -var valueOrDefault$c = helpers$1.valueOrDefault; - -// Integer constants are from the ES6 spec. -var MIN_INTEGER = Number.MIN_SAFE_INTEGER || -9007199254740991; -var MAX_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991; - -var INTERVALS = { - millisecond: { - common: true, - size: 1, - steps: [1, 2, 5, 10, 20, 50, 100, 250, 500] - }, - second: { - common: true, - size: 1000, - steps: [1, 2, 5, 10, 15, 30] - }, - minute: { - common: true, - size: 60000, - steps: [1, 2, 5, 10, 15, 30] - }, - hour: { - common: true, - size: 3600000, - steps: [1, 2, 3, 6, 12] - }, - day: { - common: true, - size: 86400000, - steps: [1, 2, 5] - }, - week: { - common: false, - size: 604800000, - steps: [1, 2, 3, 4] - }, - month: { - common: true, - size: 2.628e9, - steps: [1, 2, 3] - }, - quarter: { - common: false, - size: 7.884e9, - steps: [1, 2, 3, 4] - }, - year: { - common: true, - size: 3.154e10 - } -}; - -var UNITS = Object.keys(INTERVALS); - -function sorter(a, b) { - return a - b; -} - -function arrayUnique(items) { - var hash = {}; - var out = []; - var i, ilen, item; - - for (i = 0, ilen = items.length; i < ilen; ++i) { - item = items[i]; - if (!hash[item]) { - hash[item] = true; - out.push(item); - } - } - - return out; -} - -/** - * Returns an array of {time, pos} objects used to interpolate a specific `time` or position - * (`pos`) on the scale, by searching entries before and after the requested value. `pos` is - * a decimal between 0 and 1: 0 being the start of the scale (left or top) and 1 the other - * extremity (left + width or top + height). Note that it would be more optimized to directly - * store pre-computed pixels, but the scale dimensions are not guaranteed at the time we need - * to create the lookup table. The table ALWAYS contains at least two items: min and max. - * - * @param {number[]} timestamps - timestamps sorted from lowest to highest. - * @param {string} distribution - If 'linear', timestamps will be spread linearly along the min - * and max range, so basically, the table will contains only two items: {min, 0} and {max, 1}. - * If 'series', timestamps will be positioned at the same distance from each other. In this - * case, only timestamps that break the time linearity are registered, meaning that in the - * best case, all timestamps are linear, the table contains only min and max. - */ -function buildLookupTable(timestamps, min, max, distribution) { - if (distribution === 'linear' || !timestamps.length) { - return [ - {time: min, pos: 0}, - {time: max, pos: 1} - ]; - } - - var table = []; - var items = [min]; - var i, ilen, prev, curr, next; - - for (i = 0, ilen = timestamps.length; i < ilen; ++i) { - curr = timestamps[i]; - if (curr > min && curr < max) { - items.push(curr); - } - } - - items.push(max); - - for (i = 0, ilen = items.length; i < ilen; ++i) { - next = items[i + 1]; - prev = items[i - 1]; - curr = items[i]; - - // only add points that breaks the scale linearity - if (prev === undefined || next === undefined || Math.round((next + prev) / 2) !== curr) { - table.push({time: curr, pos: i / (ilen - 1)}); - } - } - - return table; -} - -// @see adapted from https://www.anujgakhar.com/2014/03/01/binary-search-in-javascript/ -function lookup(table, key, value) { - var lo = 0; - var hi = table.length - 1; - var mid, i0, i1; - - while (lo >= 0 && lo <= hi) { - mid = (lo + hi) >> 1; - i0 = table[mid - 1] || null; - i1 = table[mid]; - - if (!i0) { - // given value is outside table (before first item) - return {lo: null, hi: i1}; - } else if (i1[key] < value) { - lo = mid + 1; - } else if (i0[key] > value) { - hi = mid - 1; - } else { - return {lo: i0, hi: i1}; - } - } - - // given value is outside table (after last item) - return {lo: i1, hi: null}; -} - -/** - * Linearly interpolates the given source `value` using the table items `skey` values and - * returns the associated `tkey` value. For example, interpolate(table, 'time', 42, 'pos') - * returns the position for a timestamp equal to 42. If value is out of bounds, values at - * index [0, 1] or [n - 1, n] are used for the interpolation. - */ -function interpolate$1(table, skey, sval, tkey) { - var range = lookup(table, skey, sval); - - // Note: the lookup table ALWAYS contains at least 2 items (min and max) - var prev = !range.lo ? table[0] : !range.hi ? table[table.length - 2] : range.lo; - var next = !range.lo ? table[1] : !range.hi ? table[table.length - 1] : range.hi; - - var span = next[skey] - prev[skey]; - var ratio = span ? (sval - prev[skey]) / span : 0; - var offset = (next[tkey] - prev[tkey]) * ratio; - - return prev[tkey] + offset; -} - -function toTimestamp(scale, input) { - var adapter = scale._adapter; - var options = scale.options.time; - var parser = options.parser; - var format = parser || options.format; - var value = input; - - if (typeof parser === 'function') { - value = parser(value); - } - - // Only parse if its not a timestamp already - if (!helpers$1.isFinite(value)) { - value = typeof format === 'string' - ? adapter.parse(value, format) - : adapter.parse(value); - } - - if (value !== null) { - return +value; - } - - // Labels are in an incompatible format and no `parser` has been provided. - // The user might still use the deprecated `format` option for parsing. - if (!parser && typeof format === 'function') { - value = format(input); - - // `format` could return something else than a timestamp, if so, parse it - if (!helpers$1.isFinite(value)) { - value = adapter.parse(value); - } - } - - return value; -} - -function parse(scale, input) { - if (helpers$1.isNullOrUndef(input)) { - return null; - } - - var options = scale.options.time; - var value = toTimestamp(scale, scale.getRightValue(input)); - if (value === null) { - return value; - } - - if (options.round) { - value = +scale._adapter.startOf(value, options.round); - } - - return value; -} - -/** - * Returns the number of unit to skip to be able to display up to `capacity` number of ticks - * in `unit` for the given `min` / `max` range and respecting the interval steps constraints. - */ -function determineStepSize(min, max, unit, capacity) { - var range = max - min; - var interval = INTERVALS[unit]; - var milliseconds = interval.size; - var steps = interval.steps; - var i, ilen, factor; - - if (!steps) { - return Math.ceil(range / (capacity * milliseconds)); - } - - for (i = 0, ilen = steps.length; i < ilen; ++i) { - factor = steps[i]; - if (Math.ceil(range / (milliseconds * factor)) <= capacity) { - break; - } - } - - return factor; -} - -/** - * Figures out what unit results in an appropriate number of auto-generated ticks - */ -function determineUnitForAutoTicks(minUnit, min, max, capacity) { - var ilen = UNITS.length; - var i, interval, factor; - - for (i = UNITS.indexOf(minUnit); i < ilen - 1; ++i) { - interval = INTERVALS[UNITS[i]]; - factor = interval.steps ? interval.steps[interval.steps.length - 1] : MAX_INTEGER; - - if (interval.common && Math.ceil((max - min) / (factor * interval.size)) <= capacity) { - return UNITS[i]; - } - } - - return UNITS[ilen - 1]; -} - -/** - * Figures out what unit to format a set of ticks with - */ -function determineUnitForFormatting(scale, ticks, minUnit, min, max) { - var ilen = UNITS.length; - var i, unit; - - for (i = ilen - 1; i >= UNITS.indexOf(minUnit); i--) { - unit = UNITS[i]; - if (INTERVALS[unit].common && scale._adapter.diff(max, min, unit) >= ticks.length) { - return unit; - } - } - - return UNITS[minUnit ? UNITS.indexOf(minUnit) : 0]; -} - -function determineMajorUnit(unit) { - for (var i = UNITS.indexOf(unit) + 1, ilen = UNITS.length; i < ilen; ++i) { - if (INTERVALS[UNITS[i]].common) { - return UNITS[i]; - } - } -} - -/** - * Generates a maximum of `capacity` timestamps between min and max, rounded to the - * `minor` unit, aligned on the `major` unit and using the given scale time `options`. - * Important: this method can return ticks outside the min and max range, it's the - * responsibility of the calling code to clamp values if needed. - */ -function generate(scale, min, max, capacity) { - var adapter = scale._adapter; - var options = scale.options; - var timeOpts = options.time; - var minor = timeOpts.unit || determineUnitForAutoTicks(timeOpts.minUnit, min, max, capacity); - var major = determineMajorUnit(minor); - var stepSize = valueOrDefault$c(timeOpts.stepSize, timeOpts.unitStepSize); - var weekday = minor === 'week' ? timeOpts.isoWeekday : false; - var majorTicksEnabled = options.ticks.major.enabled; - var interval = INTERVALS[minor]; - var first = min; - var last = max; - var ticks = []; - var time; - - if (!stepSize) { - stepSize = determineStepSize(min, max, minor, capacity); - } - - // For 'week' unit, handle the first day of week option - if (weekday) { - first = +adapter.startOf(first, 'isoWeek', weekday); - last = +adapter.startOf(last, 'isoWeek', weekday); - } - - // Align first/last ticks on unit - first = +adapter.startOf(first, weekday ? 'day' : minor); - last = +adapter.startOf(last, weekday ? 'day' : minor); - - // Make sure that the last tick include max - if (last < max) { - last = +adapter.add(last, 1, minor); - } - - time = first; - - if (majorTicksEnabled && major && !weekday && !timeOpts.round) { - // Align the first tick on the previous `minor` unit aligned on the `major` unit: - // we first aligned time on the previous `major` unit then add the number of full - // stepSize there is between first and the previous major time. - time = +adapter.startOf(time, major); - time = +adapter.add(time, ~~((first - time) / (interval.size * stepSize)) * stepSize, minor); - } - - for (; time < last; time = +adapter.add(time, stepSize, minor)) { - ticks.push(+time); - } - - ticks.push(+time); - - return ticks; -} - -/** - * Returns the start and end offsets from edges in the form of {start, end} - * where each value is a relative width to the scale and ranges between 0 and 1. - * They add extra margins on the both sides by scaling down the original scale. - * Offsets are added when the `offset` option is true. - */ -function computeOffsets(table, ticks, min, max, options) { - var start = 0; - var end = 0; - var first, last; - - if (options.offset && ticks.length) { - if (!options.time.min) { - first = interpolate$1(table, 'time', ticks[0], 'pos'); - if (ticks.length === 1) { - start = 1 - first; - } else { - start = (interpolate$1(table, 'time', ticks[1], 'pos') - first) / 2; - } - } - if (!options.time.max) { - last = interpolate$1(table, 'time', ticks[ticks.length - 1], 'pos'); - if (ticks.length === 1) { - end = last; - } else { - end = (last - interpolate$1(table, 'time', ticks[ticks.length - 2], 'pos')) / 2; - } - } - } - - return {start: start, end: end}; -} - -function ticksFromTimestamps(scale, values, majorUnit) { - var ticks = []; - var i, ilen, value, major; - - for (i = 0, ilen = values.length; i < ilen; ++i) { - value = values[i]; - major = majorUnit ? value === +scale._adapter.startOf(value, majorUnit) : false; - - ticks.push({ - value: value, - major: major - }); - } - - return ticks; -} - -var defaultConfig$4 = { - position: 'bottom', - - /** - * Data distribution along the scale: - * - 'linear': data are spread according to their time (distances can vary), - * - 'series': data are spread at the same distance from each other. - * @see https://github.com/chartjs/Chart.js/pull/4507 - * @since 2.7.0 - */ - distribution: 'linear', - - /** - * Scale boundary strategy (bypassed by min/max time options) - * - `data`: make sure data are fully visible, ticks outside are removed - * - `ticks`: make sure ticks are fully visible, data outside are truncated - * @see https://github.com/chartjs/Chart.js/pull/4556 - * @since 2.7.0 - */ - bounds: 'data', - - adapters: {}, - time: { - parser: false, // false == a pattern string from https://momentjs.com/docs/#/parsing/string-format/ or a custom callback that converts its argument to a moment - format: false, // DEPRECATED false == date objects, moment object, callback or a pattern string from https://momentjs.com/docs/#/parsing/string-format/ - unit: false, // false == automatic or override with week, month, year, etc. - round: false, // none, or override with week, month, year, etc. - displayFormat: false, // DEPRECATED - isoWeekday: false, // override week start day - see https://momentjs.com/docs/#/get-set/iso-weekday/ - minUnit: 'millisecond', - displayFormats: {} - }, - ticks: { - autoSkip: false, - - /** - * Ticks generation input values: - * - 'auto': generates "optimal" ticks based on scale size and time options. - * - 'data': generates ticks from data (including labels from data {t|x|y} objects). - * - 'labels': generates ticks from user given `data.labels` values ONLY. - * @see https://github.com/chartjs/Chart.js/pull/4507 - * @since 2.7.0 - */ - source: 'auto', - - major: { - enabled: false - } - } -}; - -var scale_time = core_scale.extend({ - initialize: function() { - this.mergeTicksOptions(); - core_scale.prototype.initialize.call(this); - }, - - update: function() { - var me = this; - var options = me.options; - var time = options.time || (options.time = {}); - var adapter = me._adapter = new core_adapters._date(options.adapters.date); - - // DEPRECATIONS: output a message only one time per update - if (time.format) { - console.warn('options.time.format is deprecated and replaced by options.time.parser.'); - } - - // Backward compatibility: before introducing adapter, `displayFormats` was - // supposed to contain *all* unit/string pairs but this can't be resolved - // when loading the scale (adapters are loaded afterward), so let's populate - // missing formats on update - helpers$1.mergeIf(time.displayFormats, adapter.formats()); - - return core_scale.prototype.update.apply(me, arguments); - }, - - /** - * Allows data to be referenced via 't' attribute - */ - getRightValue: function(rawValue) { - if (rawValue && rawValue.t !== undefined) { - rawValue = rawValue.t; - } - return core_scale.prototype.getRightValue.call(this, rawValue); - }, - - determineDataLimits: function() { - var me = this; - var chart = me.chart; - var adapter = me._adapter; - var timeOpts = me.options.time; - var unit = timeOpts.unit || 'day'; - var min = MAX_INTEGER; - var max = MIN_INTEGER; - var timestamps = []; - var datasets = []; - var labels = []; - var i, j, ilen, jlen, data, timestamp; - var dataLabels = chart.data.labels || []; - - // Convert labels to timestamps - for (i = 0, ilen = dataLabels.length; i < ilen; ++i) { - labels.push(parse(me, dataLabels[i])); - } - - // Convert data to timestamps - for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) { - if (chart.isDatasetVisible(i)) { - data = chart.data.datasets[i].data; - - // Let's consider that all data have the same format. - if (helpers$1.isObject(data[0])) { - datasets[i] = []; - - for (j = 0, jlen = data.length; j < jlen; ++j) { - timestamp = parse(me, data[j]); - timestamps.push(timestamp); - datasets[i][j] = timestamp; - } - } else { - for (j = 0, jlen = labels.length; j < jlen; ++j) { - timestamps.push(labels[j]); - } - datasets[i] = labels.slice(0); - } - } else { - datasets[i] = []; - } - } - - if (labels.length) { - // Sort labels **after** data have been converted - labels = arrayUnique(labels).sort(sorter); - min = Math.min(min, labels[0]); - max = Math.max(max, labels[labels.length - 1]); - } - - if (timestamps.length) { - timestamps = arrayUnique(timestamps).sort(sorter); - min = Math.min(min, timestamps[0]); - max = Math.max(max, timestamps[timestamps.length - 1]); - } - - min = parse(me, timeOpts.min) || min; - max = parse(me, timeOpts.max) || max; - - // In case there is no valid min/max, set limits based on unit time option - min = min === MAX_INTEGER ? +adapter.startOf(Date.now(), unit) : min; - max = max === MIN_INTEGER ? +adapter.endOf(Date.now(), unit) + 1 : max; - - // Make sure that max is strictly higher than min (required by the lookup table) - me.min = Math.min(min, max); - me.max = Math.max(min + 1, max); - - // PRIVATE - me._horizontal = me.isHorizontal(); - me._table = []; - me._timestamps = { - data: timestamps, - datasets: datasets, - labels: labels - }; - }, - - buildTicks: function() { - var me = this; - var min = me.min; - var max = me.max; - var options = me.options; - var timeOpts = options.time; - var timestamps = []; - var ticks = []; - var i, ilen, timestamp; - - switch (options.ticks.source) { - case 'data': - timestamps = me._timestamps.data; - break; - case 'labels': - timestamps = me._timestamps.labels; - break; - case 'auto': - default: - timestamps = generate(me, min, max, me.getLabelCapacity(min), options); - } - - if (options.bounds === 'ticks' && timestamps.length) { - min = timestamps[0]; - max = timestamps[timestamps.length - 1]; - } - - // Enforce limits with user min/max options - min = parse(me, timeOpts.min) || min; - max = parse(me, timeOpts.max) || max; - - // Remove ticks outside the min/max range - for (i = 0, ilen = timestamps.length; i < ilen; ++i) { - timestamp = timestamps[i]; - if (timestamp >= min && timestamp <= max) { - ticks.push(timestamp); - } - } - - me.min = min; - me.max = max; - - // PRIVATE - me._unit = timeOpts.unit || determineUnitForFormatting(me, ticks, timeOpts.minUnit, me.min, me.max); - me._majorUnit = determineMajorUnit(me._unit); - me._table = buildLookupTable(me._timestamps.data, min, max, options.distribution); - me._offsets = computeOffsets(me._table, ticks, min, max, options); - - if (options.ticks.reverse) { - ticks.reverse(); - } - - return ticksFromTimestamps(me, ticks, me._majorUnit); - }, - - getLabelForIndex: function(index, datasetIndex) { - var me = this; - var adapter = me._adapter; - var data = me.chart.data; - var timeOpts = me.options.time; - var label = data.labels && index < data.labels.length ? data.labels[index] : ''; - var value = data.datasets[datasetIndex].data[index]; - - if (helpers$1.isObject(value)) { - label = me.getRightValue(value); - } - if (timeOpts.tooltipFormat) { - return adapter.format(toTimestamp(me, label), timeOpts.tooltipFormat); - } - if (typeof label === 'string') { - return label; - } - return adapter.format(toTimestamp(me, label), timeOpts.displayFormats.datetime); - }, - - /** - * Function to format an individual tick mark - * @private - */ - tickFormatFunction: function(time, index, ticks, format) { - var me = this; - var adapter = me._adapter; - var options = me.options; - var formats = options.time.displayFormats; - var minorFormat = formats[me._unit]; - var majorUnit = me._majorUnit; - var majorFormat = formats[majorUnit]; - var majorTime = +adapter.startOf(time, majorUnit); - var majorTickOpts = options.ticks.major; - var major = majorTickOpts.enabled && majorUnit && majorFormat && time === majorTime; - var label = adapter.format(time, format ? format : major ? majorFormat : minorFormat); - var tickOpts = major ? majorTickOpts : options.ticks.minor; - var formatter = valueOrDefault$c(tickOpts.callback, tickOpts.userCallback); - - return formatter ? formatter(label, index, ticks) : label; - }, - - convertTicksToLabels: function(ticks) { - var labels = []; - var i, ilen; - - for (i = 0, ilen = ticks.length; i < ilen; ++i) { - labels.push(this.tickFormatFunction(ticks[i].value, i, ticks)); - } - - return labels; - }, - - /** - * @private - */ - getPixelForOffset: function(time) { - var me = this; - var isReverse = me.options.ticks.reverse; - var size = me._horizontal ? me.width : me.height; - var start = me._horizontal ? isReverse ? me.right : me.left : isReverse ? me.bottom : me.top; - var pos = interpolate$1(me._table, 'time', time, 'pos'); - var offset = size * (me._offsets.start + pos) / (me._offsets.start + 1 + me._offsets.end); - - return isReverse ? start - offset : start + offset; - }, - - getPixelForValue: function(value, index, datasetIndex) { - var me = this; - var time = null; - - if (index !== undefined && datasetIndex !== undefined) { - time = me._timestamps.datasets[datasetIndex][index]; - } - - if (time === null) { - time = parse(me, value); - } - - if (time !== null) { - return me.getPixelForOffset(time); - } - }, - - getPixelForTick: function(index) { - var ticks = this.getTicks(); - return index >= 0 && index < ticks.length ? - this.getPixelForOffset(ticks[index].value) : - null; - }, - - getValueForPixel: function(pixel) { - var me = this; - var size = me._horizontal ? me.width : me.height; - var start = me._horizontal ? me.left : me.top; - var pos = (size ? (pixel - start) / size : 0) * (me._offsets.start + 1 + me._offsets.start) - me._offsets.end; - var time = interpolate$1(me._table, 'pos', pos, 'time'); - - // DEPRECATION, we should return time directly - return me._adapter._create(time); - }, - - /** - * Crude approximation of what the label width might be - * @private - */ - getLabelWidth: function(label) { - var me = this; - var ticksOpts = me.options.ticks; - var tickLabelWidth = me.ctx.measureText(label).width; - var angle = helpers$1.toRadians(ticksOpts.maxRotation); - var cosRotation = Math.cos(angle); - var sinRotation = Math.sin(angle); - var tickFontSize = valueOrDefault$c(ticksOpts.fontSize, core_defaults.global.defaultFontSize); - - return (tickLabelWidth * cosRotation) + (tickFontSize * sinRotation); - }, - - /** - * @private - */ - getLabelCapacity: function(exampleTime) { - var me = this; - - // pick the longest format (milliseconds) for guestimation - var format = me.options.time.displayFormats.millisecond; - var exampleLabel = me.tickFormatFunction(exampleTime, 0, [], format); - var tickLabelWidth = me.getLabelWidth(exampleLabel); - var innerWidth = me.isHorizontal() ? me.width : me.height; - var capacity = Math.floor(innerWidth / tickLabelWidth); - - return capacity > 0 ? capacity : 1; - } -}); - -// INTERNAL: static default options, registered in src/index.js -var _defaults$4 = defaultConfig$4; -scale_time._defaults = _defaults$4; - -var scales = { - category: scale_category, - linear: scale_linear, - logarithmic: scale_logarithmic, - radialLinear: scale_radialLinear, - time: scale_time -}; - -var moment = createCommonjsModule(function (module, exports) { -(function (global, factory) { - module.exports = factory(); -}(commonjsGlobal, (function () { - var hookCallback; - - function hooks () { - return hookCallback.apply(null, arguments); - } - - // This is done to register the method called with moment() - // without creating circular dependencies. - function setHookCallback (callback) { - hookCallback = callback; - } - - function isArray(input) { - return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]'; - } - - function isObject(input) { - // IE8 will treat undefined and null as object if it wasn't for - // input != null - return input != null && Object.prototype.toString.call(input) === '[object Object]'; - } - - function isObjectEmpty(obj) { - if (Object.getOwnPropertyNames) { - return (Object.getOwnPropertyNames(obj).length === 0); - } else { - var k; - for (k in obj) { - if (obj.hasOwnProperty(k)) { - return false; - } - } - return true; - } - } - - function isUndefined(input) { - return input === void 0; - } - - function isNumber(input) { - return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]'; - } - - function isDate(input) { - return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]'; - } - - function map(arr, fn) { - var res = [], i; - for (i = 0; i < arr.length; ++i) { - res.push(fn(arr[i], i)); - } - return res; - } - - function hasOwnProp(a, b) { - return Object.prototype.hasOwnProperty.call(a, b); - } - - function extend(a, b) { - for (var i in b) { - if (hasOwnProp(b, i)) { - a[i] = b[i]; - } - } - - if (hasOwnProp(b, 'toString')) { - a.toString = b.toString; - } - - if (hasOwnProp(b, 'valueOf')) { - a.valueOf = b.valueOf; - } - - return a; - } - - function createUTC (input, format, locale, strict) { - return createLocalOrUTC(input, format, locale, strict, true).utc(); - } - - function defaultParsingFlags() { - // We need to deep clone this object. - return { - empty : false, - unusedTokens : [], - unusedInput : [], - overflow : -2, - charsLeftOver : 0, - nullInput : false, - invalidMonth : null, - invalidFormat : false, - userInvalidated : false, - iso : false, - parsedDateParts : [], - meridiem : null, - rfc2822 : false, - weekdayMismatch : false - }; - } - - function getParsingFlags(m) { - if (m._pf == null) { - m._pf = defaultParsingFlags(); - } - return m._pf; - } - - var some; - if (Array.prototype.some) { - some = Array.prototype.some; - } else { - some = function (fun) { - var t = Object(this); - var len = t.length >>> 0; - - for (var i = 0; i < len; i++) { - if (i in t && fun.call(this, t[i], i, t)) { - return true; - } - } - - return false; - }; - } - - function isValid(m) { - if (m._isValid == null) { - var flags = getParsingFlags(m); - var parsedParts = some.call(flags.parsedDateParts, function (i) { - return i != null; - }); - var isNowValid = !isNaN(m._d.getTime()) && - flags.overflow < 0 && - !flags.empty && - !flags.invalidMonth && - !flags.invalidWeekday && - !flags.weekdayMismatch && - !flags.nullInput && - !flags.invalidFormat && - !flags.userInvalidated && - (!flags.meridiem || (flags.meridiem && parsedParts)); - - if (m._strict) { - isNowValid = isNowValid && - flags.charsLeftOver === 0 && - flags.unusedTokens.length === 0 && - flags.bigHour === undefined; - } - - if (Object.isFrozen == null || !Object.isFrozen(m)) { - m._isValid = isNowValid; - } - else { - return isNowValid; - } - } - return m._isValid; - } - - function createInvalid (flags) { - var m = createUTC(NaN); - if (flags != null) { - extend(getParsingFlags(m), flags); - } - else { - getParsingFlags(m).userInvalidated = true; - } - - return m; - } - - // Plugins that add properties should also add the key here (null value), - // so we can properly clone ourselves. - var momentProperties = hooks.momentProperties = []; - - function copyConfig(to, from) { - var i, prop, val; - - if (!isUndefined(from._isAMomentObject)) { - to._isAMomentObject = from._isAMomentObject; - } - if (!isUndefined(from._i)) { - to._i = from._i; - } - if (!isUndefined(from._f)) { - to._f = from._f; - } - if (!isUndefined(from._l)) { - to._l = from._l; - } - if (!isUndefined(from._strict)) { - to._strict = from._strict; - } - if (!isUndefined(from._tzm)) { - to._tzm = from._tzm; - } - if (!isUndefined(from._isUTC)) { - to._isUTC = from._isUTC; - } - if (!isUndefined(from._offset)) { - to._offset = from._offset; - } - if (!isUndefined(from._pf)) { - to._pf = getParsingFlags(from); - } - if (!isUndefined(from._locale)) { - to._locale = from._locale; - } - - if (momentProperties.length > 0) { - for (i = 0; i < momentProperties.length; i++) { - prop = momentProperties[i]; - val = from[prop]; - if (!isUndefined(val)) { - to[prop] = val; - } - } - } - - return to; - } - - var updateInProgress = false; - - // Moment prototype object - function Moment(config) { - copyConfig(this, config); - this._d = new Date(config._d != null ? config._d.getTime() : NaN); - if (!this.isValid()) { - this._d = new Date(NaN); - } - // Prevent infinite loop in case updateOffset creates new moment - // objects. - if (updateInProgress === false) { - updateInProgress = true; - hooks.updateOffset(this); - updateInProgress = false; - } - } - - function isMoment (obj) { - return obj instanceof Moment || (obj != null && obj._isAMomentObject != null); - } - - function absFloor (number) { - if (number < 0) { - // -0 -> 0 - return Math.ceil(number) || 0; - } else { - return Math.floor(number); - } - } - - function toInt(argumentForCoercion) { - var coercedNumber = +argumentForCoercion, - value = 0; - - if (coercedNumber !== 0 && isFinite(coercedNumber)) { - value = absFloor(coercedNumber); - } - - return value; - } - - // compare two arrays, return the number of differences - function compareArrays(array1, array2, dontConvert) { - var len = Math.min(array1.length, array2.length), - lengthDiff = Math.abs(array1.length - array2.length), - diffs = 0, - i; - for (i = 0; i < len; i++) { - if ((dontConvert && array1[i] !== array2[i]) || - (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) { - diffs++; - } - } - return diffs + lengthDiff; - } - - function warn(msg) { - if (hooks.suppressDeprecationWarnings === false && - (typeof console !== 'undefined') && console.warn) { - console.warn('Deprecation warning: ' + msg); - } - } - - function deprecate(msg, fn) { - var firstTime = true; - - return extend(function () { - if (hooks.deprecationHandler != null) { - hooks.deprecationHandler(null, msg); - } - if (firstTime) { - var args = []; - var arg; - for (var i = 0; i < arguments.length; i++) { - arg = ''; - if (typeof arguments[i] === 'object') { - arg += '\n[' + i + '] '; - for (var key in arguments[0]) { - arg += key + ': ' + arguments[0][key] + ', '; - } - arg = arg.slice(0, -2); // Remove trailing comma and space - } else { - arg = arguments[i]; - } - args.push(arg); - } - warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack); - firstTime = false; - } - return fn.apply(this, arguments); - }, fn); - } - - var deprecations = {}; - - function deprecateSimple(name, msg) { - if (hooks.deprecationHandler != null) { - hooks.deprecationHandler(name, msg); - } - if (!deprecations[name]) { - warn(msg); - deprecations[name] = true; - } - } - - hooks.suppressDeprecationWarnings = false; - hooks.deprecationHandler = null; - - function isFunction(input) { - return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]'; - } - - function set (config) { - var prop, i; - for (i in config) { - prop = config[i]; - if (isFunction(prop)) { - this[i] = prop; - } else { - this['_' + i] = prop; - } - } - this._config = config; - // Lenient ordinal parsing accepts just a number in addition to - // number + (possibly) stuff coming from _dayOfMonthOrdinalParse. - // TODO: Remove "ordinalParse" fallback in next major release. - this._dayOfMonthOrdinalParseLenient = new RegExp( - (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + - '|' + (/\d{1,2}/).source); - } - - function mergeConfigs(parentConfig, childConfig) { - var res = extend({}, parentConfig), prop; - for (prop in childConfig) { - if (hasOwnProp(childConfig, prop)) { - if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) { - res[prop] = {}; - extend(res[prop], parentConfig[prop]); - extend(res[prop], childConfig[prop]); - } else if (childConfig[prop] != null) { - res[prop] = childConfig[prop]; - } else { - delete res[prop]; - } - } - } - for (prop in parentConfig) { - if (hasOwnProp(parentConfig, prop) && - !hasOwnProp(childConfig, prop) && - isObject(parentConfig[prop])) { - // make sure changes to properties don't modify parent config - res[prop] = extend({}, res[prop]); - } - } - return res; - } - - function Locale(config) { - if (config != null) { - this.set(config); - } - } - - var keys; - - if (Object.keys) { - keys = Object.keys; - } else { - keys = function (obj) { - var i, res = []; - for (i in obj) { - if (hasOwnProp(obj, i)) { - res.push(i); - } - } - return res; - }; - } - - var defaultCalendar = { - sameDay : '[Today at] LT', - nextDay : '[Tomorrow at] LT', - nextWeek : 'dddd [at] LT', - lastDay : '[Yesterday at] LT', - lastWeek : '[Last] dddd [at] LT', - sameElse : 'L' - }; - - function calendar (key, mom, now) { - var output = this._calendar[key] || this._calendar['sameElse']; - return isFunction(output) ? output.call(mom, now) : output; - } - - var defaultLongDateFormat = { - LTS : 'h:mm:ss A', - LT : 'h:mm A', - L : 'MM/DD/YYYY', - LL : 'MMMM D, YYYY', - LLL : 'MMMM D, YYYY h:mm A', - LLLL : 'dddd, MMMM D, YYYY h:mm A' - }; - - function longDateFormat (key) { - var format = this._longDateFormat[key], - formatUpper = this._longDateFormat[key.toUpperCase()]; - - if (format || !formatUpper) { - return format; - } - - this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) { - return val.slice(1); - }); - - return this._longDateFormat[key]; - } - - var defaultInvalidDate = 'Invalid date'; - - function invalidDate () { - return this._invalidDate; - } - - var defaultOrdinal = '%d'; - var defaultDayOfMonthOrdinalParse = /\d{1,2}/; - - function ordinal (number) { - return this._ordinal.replace('%d', number); - } - - var defaultRelativeTime = { - future : 'in %s', - past : '%s ago', - s : 'a few seconds', - ss : '%d seconds', - m : 'a minute', - mm : '%d minutes', - h : 'an hour', - hh : '%d hours', - d : 'a day', - dd : '%d days', - M : 'a month', - MM : '%d months', - y : 'a year', - yy : '%d years' - }; - - function relativeTime (number, withoutSuffix, string, isFuture) { - var output = this._relativeTime[string]; - return (isFunction(output)) ? - output(number, withoutSuffix, string, isFuture) : - output.replace(/%d/i, number); - } - - function pastFuture (diff, output) { - var format = this._relativeTime[diff > 0 ? 'future' : 'past']; - return isFunction(format) ? format(output) : format.replace(/%s/i, output); - } - - var aliases = {}; - - function addUnitAlias (unit, shorthand) { - var lowerCase = unit.toLowerCase(); - aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit; - } - - function normalizeUnits(units) { - return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined; - } - - function normalizeObjectUnits(inputObject) { - var normalizedInput = {}, - normalizedProp, - prop; - - for (prop in inputObject) { - if (hasOwnProp(inputObject, prop)) { - normalizedProp = normalizeUnits(prop); - if (normalizedProp) { - normalizedInput[normalizedProp] = inputObject[prop]; - } - } - } - - return normalizedInput; - } - - var priorities = {}; - - function addUnitPriority(unit, priority) { - priorities[unit] = priority; - } - - function getPrioritizedUnits(unitsObj) { - var units = []; - for (var u in unitsObj) { - units.push({unit: u, priority: priorities[u]}); - } - units.sort(function (a, b) { - return a.priority - b.priority; - }); - return units; - } - - function zeroFill(number, targetLength, forceSign) { - var absNumber = '' + Math.abs(number), - zerosToFill = targetLength - absNumber.length, - sign = number >= 0; - return (sign ? (forceSign ? '+' : '') : '-') + - Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber; - } - - var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g; - - var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g; - - var formatFunctions = {}; - - var formatTokenFunctions = {}; - - // token: 'M' - // padded: ['MM', 2] - // ordinal: 'Mo' - // callback: function () { this.month() + 1 } - function addFormatToken (token, padded, ordinal, callback) { - var func = callback; - if (typeof callback === 'string') { - func = function () { - return this[callback](); - }; - } - if (token) { - formatTokenFunctions[token] = func; - } - if (padded) { - formatTokenFunctions[padded[0]] = function () { - return zeroFill(func.apply(this, arguments), padded[1], padded[2]); - }; - } - if (ordinal) { - formatTokenFunctions[ordinal] = function () { - return this.localeData().ordinal(func.apply(this, arguments), token); - }; - } - } - - function removeFormattingTokens(input) { - if (input.match(/\[[\s\S]/)) { - return input.replace(/^\[|\]$/g, ''); - } - return input.replace(/\\/g, ''); - } - - function makeFormatFunction(format) { - var array = format.match(formattingTokens), i, length; - - for (i = 0, length = array.length; i < length; i++) { - if (formatTokenFunctions[array[i]]) { - array[i] = formatTokenFunctions[array[i]]; - } else { - array[i] = removeFormattingTokens(array[i]); - } - } - - return function (mom) { - var output = '', i; - for (i = 0; i < length; i++) { - output += isFunction(array[i]) ? array[i].call(mom, format) : array[i]; - } - return output; - }; - } - - // format date using native date object - function formatMoment(m, format) { - if (!m.isValid()) { - return m.localeData().invalidDate(); - } - - format = expandFormat(format, m.localeData()); - formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format); - - return formatFunctions[format](m); - } - - function expandFormat(format, locale) { - var i = 5; - - function replaceLongDateFormatTokens(input) { - return locale.longDateFormat(input) || input; - } - - localFormattingTokens.lastIndex = 0; - while (i >= 0 && localFormattingTokens.test(format)) { - format = format.replace(localFormattingTokens, replaceLongDateFormatTokens); - localFormattingTokens.lastIndex = 0; - i -= 1; - } - - return format; - } - - var match1 = /\d/; // 0 - 9 - var match2 = /\d\d/; // 00 - 99 - var match3 = /\d{3}/; // 000 - 999 - var match4 = /\d{4}/; // 0000 - 9999 - var match6 = /[+-]?\d{6}/; // -999999 - 999999 - var match1to2 = /\d\d?/; // 0 - 99 - var match3to4 = /\d\d\d\d?/; // 999 - 9999 - var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999 - var match1to3 = /\d{1,3}/; // 0 - 999 - var match1to4 = /\d{1,4}/; // 0 - 9999 - var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999 - - var matchUnsigned = /\d+/; // 0 - inf - var matchSigned = /[+-]?\d+/; // -inf - inf - - var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z - var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z - - var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123 - - // any word (or two) characters or numbers including two/three word month in arabic. - // includes scottish gaelic two word and hyphenated months - var matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i; - - var regexes = {}; - - function addRegexToken (token, regex, strictRegex) { - regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) { - return (isStrict && strictRegex) ? strictRegex : regex; - }; - } - - function getParseRegexForToken (token, config) { - if (!hasOwnProp(regexes, token)) { - return new RegExp(unescapeFormat(token)); - } - - return regexes[token](config._strict, config._locale); - } - - // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript - function unescapeFormat(s) { - return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { - return p1 || p2 || p3 || p4; - })); - } - - function regexEscape(s) { - return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); - } - - var tokens = {}; - - function addParseToken (token, callback) { - var i, func = callback; - if (typeof token === 'string') { - token = [token]; - } - if (isNumber(callback)) { - func = function (input, array) { - array[callback] = toInt(input); - }; - } - for (i = 0; i < token.length; i++) { - tokens[token[i]] = func; - } - } - - function addWeekParseToken (token, callback) { - addParseToken(token, function (input, array, config, token) { - config._w = config._w || {}; - callback(input, config._w, config, token); - }); - } - - function addTimeToArrayFromToken(token, input, config) { - if (input != null && hasOwnProp(tokens, token)) { - tokens[token](input, config._a, config, token); - } - } - - var YEAR = 0; - var MONTH = 1; - var DATE = 2; - var HOUR = 3; - var MINUTE = 4; - var SECOND = 5; - var MILLISECOND = 6; - var WEEK = 7; - var WEEKDAY = 8; - - // FORMATTING - - addFormatToken('Y', 0, 0, function () { - var y = this.year(); - return y <= 9999 ? '' + y : '+' + y; - }); - - addFormatToken(0, ['YY', 2], 0, function () { - return this.year() % 100; - }); - - addFormatToken(0, ['YYYY', 4], 0, 'year'); - addFormatToken(0, ['YYYYY', 5], 0, 'year'); - addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); - - // ALIASES - - addUnitAlias('year', 'y'); - - // PRIORITIES - - addUnitPriority('year', 1); - - // PARSING - - addRegexToken('Y', matchSigned); - addRegexToken('YY', match1to2, match2); - addRegexToken('YYYY', match1to4, match4); - addRegexToken('YYYYY', match1to6, match6); - addRegexToken('YYYYYY', match1to6, match6); - - addParseToken(['YYYYY', 'YYYYYY'], YEAR); - addParseToken('YYYY', function (input, array) { - array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input); - }); - addParseToken('YY', function (input, array) { - array[YEAR] = hooks.parseTwoDigitYear(input); - }); - addParseToken('Y', function (input, array) { - array[YEAR] = parseInt(input, 10); - }); - - // HELPERS - - function daysInYear(year) { - return isLeapYear(year) ? 366 : 365; - } - - function isLeapYear(year) { - return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; - } - - // HOOKS - - hooks.parseTwoDigitYear = function (input) { - return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); - }; - - // MOMENTS - - var getSetYear = makeGetSet('FullYear', true); - - function getIsLeapYear () { - return isLeapYear(this.year()); - } - - function makeGetSet (unit, keepTime) { - return function (value) { - if (value != null) { - set$1(this, unit, value); - hooks.updateOffset(this, keepTime); - return this; - } else { - return get(this, unit); - } - }; - } - - function get (mom, unit) { - return mom.isValid() ? - mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN; - } - - function set$1 (mom, unit, value) { - if (mom.isValid() && !isNaN(value)) { - if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) { - mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month())); - } - else { - mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); - } - } - } - - // MOMENTS - - function stringGet (units) { - units = normalizeUnits(units); - if (isFunction(this[units])) { - return this[units](); - } - return this; - } - - - function stringSet (units, value) { - if (typeof units === 'object') { - units = normalizeObjectUnits(units); - var prioritized = getPrioritizedUnits(units); - for (var i = 0; i < prioritized.length; i++) { - this[prioritized[i].unit](units[prioritized[i].unit]); - } - } else { - units = normalizeUnits(units); - if (isFunction(this[units])) { - return this[units](value); - } - } - return this; - } - - function mod(n, x) { - return ((n % x) + x) % x; - } - - var indexOf; - - if (Array.prototype.indexOf) { - indexOf = Array.prototype.indexOf; - } else { - indexOf = function (o) { - // I know - var i; - for (i = 0; i < this.length; ++i) { - if (this[i] === o) { - return i; - } - } - return -1; - }; - } - - function daysInMonth(year, month) { - if (isNaN(year) || isNaN(month)) { - return NaN; - } - var modMonth = mod(month, 12); - year += (month - modMonth) / 12; - return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2); - } - - // FORMATTING - - addFormatToken('M', ['MM', 2], 'Mo', function () { - return this.month() + 1; - }); - - addFormatToken('MMM', 0, 0, function (format) { - return this.localeData().monthsShort(this, format); - }); - - addFormatToken('MMMM', 0, 0, function (format) { - return this.localeData().months(this, format); - }); - - // ALIASES - - addUnitAlias('month', 'M'); - - // PRIORITY - - addUnitPriority('month', 8); - - // PARSING - - addRegexToken('M', match1to2); - addRegexToken('MM', match1to2, match2); - addRegexToken('MMM', function (isStrict, locale) { - return locale.monthsShortRegex(isStrict); - }); - addRegexToken('MMMM', function (isStrict, locale) { - return locale.monthsRegex(isStrict); - }); - - addParseToken(['M', 'MM'], function (input, array) { - array[MONTH] = toInt(input) - 1; - }); - - addParseToken(['MMM', 'MMMM'], function (input, array, config, token) { - var month = config._locale.monthsParse(input, token, config._strict); - // if we didn't find a month name, mark the date as invalid. - if (month != null) { - array[MONTH] = month; - } else { - getParsingFlags(config).invalidMonth = input; - } - }); - - // LOCALES - - var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/; - var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'); - function localeMonths (m, format) { - if (!m) { - return isArray(this._months) ? this._months : - this._months['standalone']; - } - return isArray(this._months) ? this._months[m.month()] : - this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()]; - } - - var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'); - function localeMonthsShort (m, format) { - if (!m) { - return isArray(this._monthsShort) ? this._monthsShort : - this._monthsShort['standalone']; - } - return isArray(this._monthsShort) ? this._monthsShort[m.month()] : - this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()]; - } - - function handleStrictParse(monthName, format, strict) { - var i, ii, mom, llc = monthName.toLocaleLowerCase(); - if (!this._monthsParse) { - // this is not used - this._monthsParse = []; - this._longMonthsParse = []; - this._shortMonthsParse = []; - for (i = 0; i < 12; ++i) { - mom = createUTC([2000, i]); - this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase(); - this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase(); - } - } - - if (strict) { - if (format === 'MMM') { - ii = indexOf.call(this._shortMonthsParse, llc); - return ii !== -1 ? ii : null; - } else { - ii = indexOf.call(this._longMonthsParse, llc); - return ii !== -1 ? ii : null; - } - } else { - if (format === 'MMM') { - ii = indexOf.call(this._shortMonthsParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._longMonthsParse, llc); - return ii !== -1 ? ii : null; - } else { - ii = indexOf.call(this._longMonthsParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._shortMonthsParse, llc); - return ii !== -1 ? ii : null; - } - } - } - - function localeMonthsParse (monthName, format, strict) { - var i, mom, regex; - - if (this._monthsParseExact) { - return handleStrictParse.call(this, monthName, format, strict); - } - - if (!this._monthsParse) { - this._monthsParse = []; - this._longMonthsParse = []; - this._shortMonthsParse = []; - } - - // TODO: add sorting - // Sorting makes sure if one month (or abbr) is a prefix of another - // see sorting in computeMonthsParse - for (i = 0; i < 12; i++) { - // make the regex if we don't have it already - mom = createUTC([2000, i]); - if (strict && !this._longMonthsParse[i]) { - this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i'); - this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i'); - } - if (!strict && !this._monthsParse[i]) { - regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); - this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); - } - // test the regex - if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) { - return i; - } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) { - return i; - } else if (!strict && this._monthsParse[i].test(monthName)) { - return i; - } - } - } - - // MOMENTS - - function setMonth (mom, value) { - var dayOfMonth; - - if (!mom.isValid()) { - // No op - return mom; - } - - if (typeof value === 'string') { - if (/^\d+$/.test(value)) { - value = toInt(value); - } else { - value = mom.localeData().monthsParse(value); - // TODO: Another silent failure? - if (!isNumber(value)) { - return mom; - } - } - } - - dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value)); - mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); - return mom; - } - - function getSetMonth (value) { - if (value != null) { - setMonth(this, value); - hooks.updateOffset(this, true); - return this; - } else { - return get(this, 'Month'); - } - } - - function getDaysInMonth () { - return daysInMonth(this.year(), this.month()); - } - - var defaultMonthsShortRegex = matchWord; - function monthsShortRegex (isStrict) { - if (this._monthsParseExact) { - if (!hasOwnProp(this, '_monthsRegex')) { - computeMonthsParse.call(this); - } - if (isStrict) { - return this._monthsShortStrictRegex; - } else { - return this._monthsShortRegex; - } - } else { - if (!hasOwnProp(this, '_monthsShortRegex')) { - this._monthsShortRegex = defaultMonthsShortRegex; - } - return this._monthsShortStrictRegex && isStrict ? - this._monthsShortStrictRegex : this._monthsShortRegex; - } - } - - var defaultMonthsRegex = matchWord; - function monthsRegex (isStrict) { - if (this._monthsParseExact) { - if (!hasOwnProp(this, '_monthsRegex')) { - computeMonthsParse.call(this); - } - if (isStrict) { - return this._monthsStrictRegex; - } else { - return this._monthsRegex; - } - } else { - if (!hasOwnProp(this, '_monthsRegex')) { - this._monthsRegex = defaultMonthsRegex; - } - return this._monthsStrictRegex && isStrict ? - this._monthsStrictRegex : this._monthsRegex; - } - } - - function computeMonthsParse () { - function cmpLenRev(a, b) { - return b.length - a.length; - } - - var shortPieces = [], longPieces = [], mixedPieces = [], - i, mom; - for (i = 0; i < 12; i++) { - // make the regex if we don't have it already - mom = createUTC([2000, i]); - shortPieces.push(this.monthsShort(mom, '')); - longPieces.push(this.months(mom, '')); - mixedPieces.push(this.months(mom, '')); - mixedPieces.push(this.monthsShort(mom, '')); - } - // Sorting makes sure if one month (or abbr) is a prefix of another it - // will match the longer piece. - shortPieces.sort(cmpLenRev); - longPieces.sort(cmpLenRev); - mixedPieces.sort(cmpLenRev); - for (i = 0; i < 12; i++) { - shortPieces[i] = regexEscape(shortPieces[i]); - longPieces[i] = regexEscape(longPieces[i]); - } - for (i = 0; i < 24; i++) { - mixedPieces[i] = regexEscape(mixedPieces[i]); - } - - this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); - this._monthsShortRegex = this._monthsRegex; - this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); - this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); - } - - function createDate (y, m, d, h, M, s, ms) { - // can't just apply() to create a date: - // https://stackoverflow.com/q/181348 - var date; - // the date constructor remaps years 0-99 to 1900-1999 - if (y < 100 && y >= 0) { - // preserve leap years using a full 400 year cycle, then reset - date = new Date(y + 400, m, d, h, M, s, ms); - if (isFinite(date.getFullYear())) { - date.setFullYear(y); - } - } else { - date = new Date(y, m, d, h, M, s, ms); - } - - return date; - } - - function createUTCDate (y) { - var date; - // the Date.UTC function remaps years 0-99 to 1900-1999 - if (y < 100 && y >= 0) { - var args = Array.prototype.slice.call(arguments); - // preserve leap years using a full 400 year cycle, then reset - args[0] = y + 400; - date = new Date(Date.UTC.apply(null, args)); - if (isFinite(date.getUTCFullYear())) { - date.setUTCFullYear(y); - } - } else { - date = new Date(Date.UTC.apply(null, arguments)); - } - - return date; - } - - // start-of-first-week - start-of-year - function firstWeekOffset(year, dow, doy) { - var // first-week day -- which january is always in the first week (4 for iso, 1 for other) - fwd = 7 + dow - doy, - // first-week day local weekday -- which local weekday is fwd - fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7; - - return -fwdlw + fwd - 1; - } - - // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday - function dayOfYearFromWeeks(year, week, weekday, dow, doy) { - var localWeekday = (7 + weekday - dow) % 7, - weekOffset = firstWeekOffset(year, dow, doy), - dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset, - resYear, resDayOfYear; - - if (dayOfYear <= 0) { - resYear = year - 1; - resDayOfYear = daysInYear(resYear) + dayOfYear; - } else if (dayOfYear > daysInYear(year)) { - resYear = year + 1; - resDayOfYear = dayOfYear - daysInYear(year); - } else { - resYear = year; - resDayOfYear = dayOfYear; - } - - return { - year: resYear, - dayOfYear: resDayOfYear - }; - } - - function weekOfYear(mom, dow, doy) { - var weekOffset = firstWeekOffset(mom.year(), dow, doy), - week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1, - resWeek, resYear; - - if (week < 1) { - resYear = mom.year() - 1; - resWeek = week + weeksInYear(resYear, dow, doy); - } else if (week > weeksInYear(mom.year(), dow, doy)) { - resWeek = week - weeksInYear(mom.year(), dow, doy); - resYear = mom.year() + 1; - } else { - resYear = mom.year(); - resWeek = week; - } - - return { - week: resWeek, - year: resYear - }; - } - - function weeksInYear(year, dow, doy) { - var weekOffset = firstWeekOffset(year, dow, doy), - weekOffsetNext = firstWeekOffset(year + 1, dow, doy); - return (daysInYear(year) - weekOffset + weekOffsetNext) / 7; - } - - // FORMATTING - - addFormatToken('w', ['ww', 2], 'wo', 'week'); - addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); - - // ALIASES - - addUnitAlias('week', 'w'); - addUnitAlias('isoWeek', 'W'); - - // PRIORITIES - - addUnitPriority('week', 5); - addUnitPriority('isoWeek', 5); - - // PARSING - - addRegexToken('w', match1to2); - addRegexToken('ww', match1to2, match2); - addRegexToken('W', match1to2); - addRegexToken('WW', match1to2, match2); - - addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) { - week[token.substr(0, 1)] = toInt(input); - }); - - // HELPERS - - // LOCALES - - function localeWeek (mom) { - return weekOfYear(mom, this._week.dow, this._week.doy).week; - } - - var defaultLocaleWeek = { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 6th is the first week of the year. - }; - - function localeFirstDayOfWeek () { - return this._week.dow; - } - - function localeFirstDayOfYear () { - return this._week.doy; - } - - // MOMENTS - - function getSetWeek (input) { - var week = this.localeData().week(this); - return input == null ? week : this.add((input - week) * 7, 'd'); - } - - function getSetISOWeek (input) { - var week = weekOfYear(this, 1, 4).week; - return input == null ? week : this.add((input - week) * 7, 'd'); - } - - // FORMATTING - - addFormatToken('d', 0, 'do', 'day'); - - addFormatToken('dd', 0, 0, function (format) { - return this.localeData().weekdaysMin(this, format); - }); - - addFormatToken('ddd', 0, 0, function (format) { - return this.localeData().weekdaysShort(this, format); - }); - - addFormatToken('dddd', 0, 0, function (format) { - return this.localeData().weekdays(this, format); - }); - - addFormatToken('e', 0, 0, 'weekday'); - addFormatToken('E', 0, 0, 'isoWeekday'); - - // ALIASES - - addUnitAlias('day', 'd'); - addUnitAlias('weekday', 'e'); - addUnitAlias('isoWeekday', 'E'); - - // PRIORITY - addUnitPriority('day', 11); - addUnitPriority('weekday', 11); - addUnitPriority('isoWeekday', 11); - - // PARSING - - addRegexToken('d', match1to2); - addRegexToken('e', match1to2); - addRegexToken('E', match1to2); - addRegexToken('dd', function (isStrict, locale) { - return locale.weekdaysMinRegex(isStrict); - }); - addRegexToken('ddd', function (isStrict, locale) { - return locale.weekdaysShortRegex(isStrict); - }); - addRegexToken('dddd', function (isStrict, locale) { - return locale.weekdaysRegex(isStrict); - }); - - addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) { - var weekday = config._locale.weekdaysParse(input, token, config._strict); - // if we didn't get a weekday name, mark the date as invalid - if (weekday != null) { - week.d = weekday; - } else { - getParsingFlags(config).invalidWeekday = input; - } - }); - - addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) { - week[token] = toInt(input); - }); - - // HELPERS - - function parseWeekday(input, locale) { - if (typeof input !== 'string') { - return input; - } - - if (!isNaN(input)) { - return parseInt(input, 10); - } - - input = locale.weekdaysParse(input); - if (typeof input === 'number') { - return input; - } - - return null; - } - - function parseIsoWeekday(input, locale) { - if (typeof input === 'string') { - return locale.weekdaysParse(input) % 7 || 7; - } - return isNaN(input) ? null : input; - } - - // LOCALES - function shiftWeekdays (ws, n) { - return ws.slice(n, 7).concat(ws.slice(0, n)); - } - - var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'); - function localeWeekdays (m, format) { - var weekdays = isArray(this._weekdays) ? this._weekdays : - this._weekdays[(m && m !== true && this._weekdays.isFormat.test(format)) ? 'format' : 'standalone']; - return (m === true) ? shiftWeekdays(weekdays, this._week.dow) - : (m) ? weekdays[m.day()] : weekdays; - } - - var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'); - function localeWeekdaysShort (m) { - return (m === true) ? shiftWeekdays(this._weekdaysShort, this._week.dow) - : (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort; - } - - var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'); - function localeWeekdaysMin (m) { - return (m === true) ? shiftWeekdays(this._weekdaysMin, this._week.dow) - : (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin; - } - - function handleStrictParse$1(weekdayName, format, strict) { - var i, ii, mom, llc = weekdayName.toLocaleLowerCase(); - if (!this._weekdaysParse) { - this._weekdaysParse = []; - this._shortWeekdaysParse = []; - this._minWeekdaysParse = []; - - for (i = 0; i < 7; ++i) { - mom = createUTC([2000, 1]).day(i); - this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase(); - this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase(); - this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase(); - } - } - - if (strict) { - if (format === 'dddd') { - ii = indexOf.call(this._weekdaysParse, llc); - return ii !== -1 ? ii : null; - } else if (format === 'ddd') { - ii = indexOf.call(this._shortWeekdaysParse, llc); - return ii !== -1 ? ii : null; - } else { - ii = indexOf.call(this._minWeekdaysParse, llc); - return ii !== -1 ? ii : null; - } - } else { - if (format === 'dddd') { - ii = indexOf.call(this._weekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._shortWeekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._minWeekdaysParse, llc); - return ii !== -1 ? ii : null; - } else if (format === 'ddd') { - ii = indexOf.call(this._shortWeekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._weekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._minWeekdaysParse, llc); - return ii !== -1 ? ii : null; - } else { - ii = indexOf.call(this._minWeekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._weekdaysParse, llc); - if (ii !== -1) { - return ii; - } - ii = indexOf.call(this._shortWeekdaysParse, llc); - return ii !== -1 ? ii : null; - } - } - } - - function localeWeekdaysParse (weekdayName, format, strict) { - var i, mom, regex; - - if (this._weekdaysParseExact) { - return handleStrictParse$1.call(this, weekdayName, format, strict); - } - - if (!this._weekdaysParse) { - this._weekdaysParse = []; - this._minWeekdaysParse = []; - this._shortWeekdaysParse = []; - this._fullWeekdaysParse = []; - } - - for (i = 0; i < 7; i++) { - // make the regex if we don't have it already - - mom = createUTC([2000, 1]).day(i); - if (strict && !this._fullWeekdaysParse[i]) { - this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\\.?') + '$', 'i'); - this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\\.?') + '$', 'i'); - this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\\.?') + '$', 'i'); - } - if (!this._weekdaysParse[i]) { - regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); - this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); - } - // test the regex - if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) { - return i; - } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) { - return i; - } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) { - return i; - } else if (!strict && this._weekdaysParse[i].test(weekdayName)) { - return i; - } - } - } - - // MOMENTS - - function getSetDayOfWeek (input) { - if (!this.isValid()) { - return input != null ? this : NaN; - } - var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); - if (input != null) { - input = parseWeekday(input, this.localeData()); - return this.add(input - day, 'd'); - } else { - return day; - } - } - - function getSetLocaleDayOfWeek (input) { - if (!this.isValid()) { - return input != null ? this : NaN; - } - var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; - return input == null ? weekday : this.add(input - weekday, 'd'); - } - - function getSetISODayOfWeek (input) { - if (!this.isValid()) { - return input != null ? this : NaN; - } - - // behaves the same as moment#day except - // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) - // as a setter, sunday should belong to the previous week. - - if (input != null) { - var weekday = parseIsoWeekday(input, this.localeData()); - return this.day(this.day() % 7 ? weekday : weekday - 7); - } else { - return this.day() || 7; - } - } - - var defaultWeekdaysRegex = matchWord; - function weekdaysRegex (isStrict) { - if (this._weekdaysParseExact) { - if (!hasOwnProp(this, '_weekdaysRegex')) { - computeWeekdaysParse.call(this); - } - if (isStrict) { - return this._weekdaysStrictRegex; - } else { - return this._weekdaysRegex; - } - } else { - if (!hasOwnProp(this, '_weekdaysRegex')) { - this._weekdaysRegex = defaultWeekdaysRegex; - } - return this._weekdaysStrictRegex && isStrict ? - this._weekdaysStrictRegex : this._weekdaysRegex; - } - } - - var defaultWeekdaysShortRegex = matchWord; - function weekdaysShortRegex (isStrict) { - if (this._weekdaysParseExact) { - if (!hasOwnProp(this, '_weekdaysRegex')) { - computeWeekdaysParse.call(this); - } - if (isStrict) { - return this._weekdaysShortStrictRegex; - } else { - return this._weekdaysShortRegex; - } - } else { - if (!hasOwnProp(this, '_weekdaysShortRegex')) { - this._weekdaysShortRegex = defaultWeekdaysShortRegex; - } - return this._weekdaysShortStrictRegex && isStrict ? - this._weekdaysShortStrictRegex : this._weekdaysShortRegex; - } - } - - var defaultWeekdaysMinRegex = matchWord; - function weekdaysMinRegex (isStrict) { - if (this._weekdaysParseExact) { - if (!hasOwnProp(this, '_weekdaysRegex')) { - computeWeekdaysParse.call(this); - } - if (isStrict) { - return this._weekdaysMinStrictRegex; - } else { - return this._weekdaysMinRegex; - } - } else { - if (!hasOwnProp(this, '_weekdaysMinRegex')) { - this._weekdaysMinRegex = defaultWeekdaysMinRegex; - } - return this._weekdaysMinStrictRegex && isStrict ? - this._weekdaysMinStrictRegex : this._weekdaysMinRegex; - } - } - - - function computeWeekdaysParse () { - function cmpLenRev(a, b) { - return b.length - a.length; - } - - var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [], - i, mom, minp, shortp, longp; - for (i = 0; i < 7; i++) { - // make the regex if we don't have it already - mom = createUTC([2000, 1]).day(i); - minp = this.weekdaysMin(mom, ''); - shortp = this.weekdaysShort(mom, ''); - longp = this.weekdays(mom, ''); - minPieces.push(minp); - shortPieces.push(shortp); - longPieces.push(longp); - mixedPieces.push(minp); - mixedPieces.push(shortp); - mixedPieces.push(longp); - } - // Sorting makes sure if one weekday (or abbr) is a prefix of another it - // will match the longer piece. - minPieces.sort(cmpLenRev); - shortPieces.sort(cmpLenRev); - longPieces.sort(cmpLenRev); - mixedPieces.sort(cmpLenRev); - for (i = 0; i < 7; i++) { - shortPieces[i] = regexEscape(shortPieces[i]); - longPieces[i] = regexEscape(longPieces[i]); - mixedPieces[i] = regexEscape(mixedPieces[i]); - } - - this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); - this._weekdaysShortRegex = this._weekdaysRegex; - this._weekdaysMinRegex = this._weekdaysRegex; - - this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); - this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); - this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i'); - } - - // FORMATTING - - function hFormat() { - return this.hours() % 12 || 12; - } - - function kFormat() { - return this.hours() || 24; - } - - addFormatToken('H', ['HH', 2], 0, 'hour'); - addFormatToken('h', ['hh', 2], 0, hFormat); - addFormatToken('k', ['kk', 2], 0, kFormat); - - addFormatToken('hmm', 0, 0, function () { - return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2); - }); - - addFormatToken('hmmss', 0, 0, function () { - return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + - zeroFill(this.seconds(), 2); - }); - - addFormatToken('Hmm', 0, 0, function () { - return '' + this.hours() + zeroFill(this.minutes(), 2); - }); - - addFormatToken('Hmmss', 0, 0, function () { - return '' + this.hours() + zeroFill(this.minutes(), 2) + - zeroFill(this.seconds(), 2); - }); - - function meridiem (token, lowercase) { - addFormatToken(token, 0, 0, function () { - return this.localeData().meridiem(this.hours(), this.minutes(), lowercase); - }); - } - - meridiem('a', true); - meridiem('A', false); - - // ALIASES - - addUnitAlias('hour', 'h'); - - // PRIORITY - addUnitPriority('hour', 13); - - // PARSING - - function matchMeridiem (isStrict, locale) { - return locale._meridiemParse; - } - - addRegexToken('a', matchMeridiem); - addRegexToken('A', matchMeridiem); - addRegexToken('H', match1to2); - addRegexToken('h', match1to2); - addRegexToken('k', match1to2); - addRegexToken('HH', match1to2, match2); - addRegexToken('hh', match1to2, match2); - addRegexToken('kk', match1to2, match2); - - addRegexToken('hmm', match3to4); - addRegexToken('hmmss', match5to6); - addRegexToken('Hmm', match3to4); - addRegexToken('Hmmss', match5to6); - - addParseToken(['H', 'HH'], HOUR); - addParseToken(['k', 'kk'], function (input, array, config) { - var kInput = toInt(input); - array[HOUR] = kInput === 24 ? 0 : kInput; - }); - addParseToken(['a', 'A'], function (input, array, config) { - config._isPm = config._locale.isPM(input); - config._meridiem = input; - }); - addParseToken(['h', 'hh'], function (input, array, config) { - array[HOUR] = toInt(input); - getParsingFlags(config).bigHour = true; - }); - addParseToken('hmm', function (input, array, config) { - var pos = input.length - 2; - array[HOUR] = toInt(input.substr(0, pos)); - array[MINUTE] = toInt(input.substr(pos)); - getParsingFlags(config).bigHour = true; - }); - addParseToken('hmmss', function (input, array, config) { - var pos1 = input.length - 4; - var pos2 = input.length - 2; - array[HOUR] = toInt(input.substr(0, pos1)); - array[MINUTE] = toInt(input.substr(pos1, 2)); - array[SECOND] = toInt(input.substr(pos2)); - getParsingFlags(config).bigHour = true; - }); - addParseToken('Hmm', function (input, array, config) { - var pos = input.length - 2; - array[HOUR] = toInt(input.substr(0, pos)); - array[MINUTE] = toInt(input.substr(pos)); - }); - addParseToken('Hmmss', function (input, array, config) { - var pos1 = input.length - 4; - var pos2 = input.length - 2; - array[HOUR] = toInt(input.substr(0, pos1)); - array[MINUTE] = toInt(input.substr(pos1, 2)); - array[SECOND] = toInt(input.substr(pos2)); - }); - - // LOCALES - - function localeIsPM (input) { - // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays - // Using charAt should be more compatible. - return ((input + '').toLowerCase().charAt(0) === 'p'); - } - - var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i; - function localeMeridiem (hours, minutes, isLower) { - if (hours > 11) { - return isLower ? 'pm' : 'PM'; - } else { - return isLower ? 'am' : 'AM'; - } - } - - - // MOMENTS - - // Setting the hour should keep the time, because the user explicitly - // specified which hour they want. So trying to maintain the same hour (in - // a new timezone) makes sense. Adding/subtracting hours does not follow - // this rule. - var getSetHour = makeGetSet('Hours', true); - - var baseConfig = { - calendar: defaultCalendar, - longDateFormat: defaultLongDateFormat, - invalidDate: defaultInvalidDate, - ordinal: defaultOrdinal, - dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse, - relativeTime: defaultRelativeTime, - - months: defaultLocaleMonths, - monthsShort: defaultLocaleMonthsShort, - - week: defaultLocaleWeek, - - weekdays: defaultLocaleWeekdays, - weekdaysMin: defaultLocaleWeekdaysMin, - weekdaysShort: defaultLocaleWeekdaysShort, - - meridiemParse: defaultLocaleMeridiemParse - }; - - // internal storage for locale config files - var locales = {}; - var localeFamilies = {}; - var globalLocale; - - function normalizeLocale(key) { - return key ? key.toLowerCase().replace('_', '-') : key; - } - - // pick the locale from the array - // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each - // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root - function chooseLocale(names) { - var i = 0, j, next, locale, split; - - while (i < names.length) { - split = normalizeLocale(names[i]).split('-'); - j = split.length; - next = normalizeLocale(names[i + 1]); - next = next ? next.split('-') : null; - while (j > 0) { - locale = loadLocale(split.slice(0, j).join('-')); - if (locale) { - return locale; - } - if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { - //the next array item is better than a shallower substring of this one - break; - } - j--; - } - i++; - } - return globalLocale; - } - - function loadLocale(name) { - var oldLocale = null; - // TODO: Find a better way to register and load all the locales in Node - if (!locales[name] && ('object' !== 'undefined') && - module && module.exports) { - try { - oldLocale = globalLocale._abbr; - var aliasedRequire = commonjsRequire; - aliasedRequire('./locale/' + name); - getSetGlobalLocale(oldLocale); - } catch (e) {} - } - return locales[name]; - } - - // This function will load locale and then set the global locale. If - // no arguments are passed in, it will simply return the current global - // locale key. - function getSetGlobalLocale (key, values) { - var data; - if (key) { - if (isUndefined(values)) { - data = getLocale(key); - } - else { - data = defineLocale(key, values); - } - - if (data) { - // moment.duration._locale = moment._locale = data; - globalLocale = data; - } - else { - if ((typeof console !== 'undefined') && console.warn) { - //warn user if arguments are passed but the locale could not be set - console.warn('Locale ' + key + ' not found. Did you forget to load it?'); - } - } - } - - return globalLocale._abbr; - } - - function defineLocale (name, config) { - if (config !== null) { - var locale, parentConfig = baseConfig; - config.abbr = name; - if (locales[name] != null) { - deprecateSimple('defineLocaleOverride', - 'use moment.updateLocale(localeName, config) to change ' + - 'an existing locale. moment.defineLocale(localeName, ' + - 'config) should only be used for creating a new locale ' + - 'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.'); - parentConfig = locales[name]._config; - } else if (config.parentLocale != null) { - if (locales[config.parentLocale] != null) { - parentConfig = locales[config.parentLocale]._config; - } else { - locale = loadLocale(config.parentLocale); - if (locale != null) { - parentConfig = locale._config; - } else { - if (!localeFamilies[config.parentLocale]) { - localeFamilies[config.parentLocale] = []; - } - localeFamilies[config.parentLocale].push({ - name: name, - config: config - }); - return null; - } - } - } - locales[name] = new Locale(mergeConfigs(parentConfig, config)); - - if (localeFamilies[name]) { - localeFamilies[name].forEach(function (x) { - defineLocale(x.name, x.config); - }); - } - - // backwards compat for now: also set the locale - // make sure we set the locale AFTER all child locales have been - // created, so we won't end up with the child locale set. - getSetGlobalLocale(name); - - - return locales[name]; - } else { - // useful for testing - delete locales[name]; - return null; - } - } - - function updateLocale(name, config) { - if (config != null) { - var locale, tmpLocale, parentConfig = baseConfig; - // MERGE - tmpLocale = loadLocale(name); - if (tmpLocale != null) { - parentConfig = tmpLocale._config; - } - config = mergeConfigs(parentConfig, config); - locale = new Locale(config); - locale.parentLocale = locales[name]; - locales[name] = locale; - - // backwards compat for now: also set the locale - getSetGlobalLocale(name); - } else { - // pass null for config to unupdate, useful for tests - if (locales[name] != null) { - if (locales[name].parentLocale != null) { - locales[name] = locales[name].parentLocale; - } else if (locales[name] != null) { - delete locales[name]; - } - } - } - return locales[name]; - } - - // returns locale data - function getLocale (key) { - var locale; - - if (key && key._locale && key._locale._abbr) { - key = key._locale._abbr; - } - - if (!key) { - return globalLocale; - } - - if (!isArray(key)) { - //short-circuit everything else - locale = loadLocale(key); - if (locale) { - return locale; - } - key = [key]; - } - - return chooseLocale(key); - } - - function listLocales() { - return keys(locales); - } - - function checkOverflow (m) { - var overflow; - var a = m._a; - - if (a && getParsingFlags(m).overflow === -2) { - overflow = - a[MONTH] < 0 || a[MONTH] > 11 ? MONTH : - a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE : - a[HOUR] < 0 || a[HOUR] > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR : - a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE : - a[SECOND] < 0 || a[SECOND] > 59 ? SECOND : - a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND : - -1; - - if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { - overflow = DATE; - } - if (getParsingFlags(m)._overflowWeeks && overflow === -1) { - overflow = WEEK; - } - if (getParsingFlags(m)._overflowWeekday && overflow === -1) { - overflow = WEEKDAY; - } - - getParsingFlags(m).overflow = overflow; - } - - return m; - } - - // Pick the first defined of two or three arguments. - function defaults(a, b, c) { - if (a != null) { - return a; - } - if (b != null) { - return b; - } - return c; - } - - function currentDateArray(config) { - // hooks is actually the exported moment object - var nowValue = new Date(hooks.now()); - if (config._useUTC) { - return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()]; - } - return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; - } - - // convert an array to a date. - // the array should mirror the parameters below - // note: all values past the year are optional and will default to the lowest possible value. - // [year, month, day , hour, minute, second, millisecond] - function configFromArray (config) { - var i, date, input = [], currentDate, expectedWeekday, yearToUse; - - if (config._d) { - return; - } - - currentDate = currentDateArray(config); - - //compute day of the year from weeks and weekdays - if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { - dayOfYearFromWeekInfo(config); - } - - //if the day of the year is set, figure out what it is - if (config._dayOfYear != null) { - yearToUse = defaults(config._a[YEAR], currentDate[YEAR]); - - if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) { - getParsingFlags(config)._overflowDayOfYear = true; - } - - date = createUTCDate(yearToUse, 0, config._dayOfYear); - config._a[MONTH] = date.getUTCMonth(); - config._a[DATE] = date.getUTCDate(); - } - - // Default to current date. - // * if no year, month, day of month are given, default to today - // * if day of month is given, default month and year - // * if month is given, default only year - // * if year is given, don't default anything - for (i = 0; i < 3 && config._a[i] == null; ++i) { - config._a[i] = input[i] = currentDate[i]; - } - - // Zero out whatever was not defaulted, including time - for (; i < 7; i++) { - config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; - } - - // Check for 24:00:00.000 - if (config._a[HOUR] === 24 && - config._a[MINUTE] === 0 && - config._a[SECOND] === 0 && - config._a[MILLISECOND] === 0) { - config._nextDay = true; - config._a[HOUR] = 0; - } - - config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input); - expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay(); - - // Apply timezone offset from input. The actual utcOffset can be changed - // with parseZone. - if (config._tzm != null) { - config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); - } - - if (config._nextDay) { - config._a[HOUR] = 24; - } - - // check for mismatching day of week - if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) { - getParsingFlags(config).weekdayMismatch = true; - } - } - - function dayOfYearFromWeekInfo(config) { - var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow; - - w = config._w; - if (w.GG != null || w.W != null || w.E != null) { - dow = 1; - doy = 4; - - // TODO: We need to take the current isoWeekYear, but that depends on - // how we interpret now (local, utc, fixed offset). So create - // a now version of current config (take local/utc/offset flags, and - // create now). - weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year); - week = defaults(w.W, 1); - weekday = defaults(w.E, 1); - if (weekday < 1 || weekday > 7) { - weekdayOverflow = true; - } - } else { - dow = config._locale._week.dow; - doy = config._locale._week.doy; - - var curWeek = weekOfYear(createLocal(), dow, doy); - - weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); - - // Default to current week. - week = defaults(w.w, curWeek.week); - - if (w.d != null) { - // weekday -- low day numbers are considered next week - weekday = w.d; - if (weekday < 0 || weekday > 6) { - weekdayOverflow = true; - } - } else if (w.e != null) { - // local weekday -- counting starts from beginning of week - weekday = w.e + dow; - if (w.e < 0 || w.e > 6) { - weekdayOverflow = true; - } - } else { - // default to beginning of week - weekday = dow; - } - } - if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { - getParsingFlags(config)._overflowWeeks = true; - } else if (weekdayOverflow != null) { - getParsingFlags(config)._overflowWeekday = true; - } else { - temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); - config._a[YEAR] = temp.year; - config._dayOfYear = temp.dayOfYear; - } - } - - // iso 8601 regex - // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) - var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; - var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; - - var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/; - - var isoDates = [ - ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/], - ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/], - ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/], - ['GGGG-[W]WW', /\d{4}-W\d\d/, false], - ['YYYY-DDD', /\d{4}-\d{3}/], - ['YYYY-MM', /\d{4}-\d\d/, false], - ['YYYYYYMMDD', /[+-]\d{10}/], - ['YYYYMMDD', /\d{8}/], - // YYYYMM is NOT allowed by the standard - ['GGGG[W]WWE', /\d{4}W\d{3}/], - ['GGGG[W]WW', /\d{4}W\d{2}/, false], - ['YYYYDDD', /\d{7}/] - ]; - - // iso time formats and regexes - var isoTimes = [ - ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/], - ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/], - ['HH:mm:ss', /\d\d:\d\d:\d\d/], - ['HH:mm', /\d\d:\d\d/], - ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/], - ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/], - ['HHmmss', /\d\d\d\d\d\d/], - ['HHmm', /\d\d\d\d/], - ['HH', /\d\d/] - ]; - - var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; - - // date from iso format - function configFromISO(config) { - var i, l, - string = config._i, - match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string), - allowTime, dateFormat, timeFormat, tzFormat; - - if (match) { - getParsingFlags(config).iso = true; - - for (i = 0, l = isoDates.length; i < l; i++) { - if (isoDates[i][1].exec(match[1])) { - dateFormat = isoDates[i][0]; - allowTime = isoDates[i][2] !== false; - break; - } - } - if (dateFormat == null) { - config._isValid = false; - return; - } - if (match[3]) { - for (i = 0, l = isoTimes.length; i < l; i++) { - if (isoTimes[i][1].exec(match[3])) { - // match[2] should be 'T' or space - timeFormat = (match[2] || ' ') + isoTimes[i][0]; - break; - } - } - if (timeFormat == null) { - config._isValid = false; - return; - } - } - if (!allowTime && timeFormat != null) { - config._isValid = false; - return; - } - if (match[4]) { - if (tzRegex.exec(match[4])) { - tzFormat = 'Z'; - } else { - config._isValid = false; - return; - } - } - config._f = dateFormat + (timeFormat || '') + (tzFormat || ''); - configFromStringAndFormat(config); - } else { - config._isValid = false; - } - } - - // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3 - var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/; - - function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) { - var result = [ - untruncateYear(yearStr), - defaultLocaleMonthsShort.indexOf(monthStr), - parseInt(dayStr, 10), - parseInt(hourStr, 10), - parseInt(minuteStr, 10) - ]; - - if (secondStr) { - result.push(parseInt(secondStr, 10)); - } - - return result; - } - - function untruncateYear(yearStr) { - var year = parseInt(yearStr, 10); - if (year <= 49) { - return 2000 + year; - } else if (year <= 999) { - return 1900 + year; - } - return year; - } - - function preprocessRFC2822(s) { - // Remove comments and folding whitespace and replace multiple-spaces with a single space - return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').replace(/^\s\s*/, '').replace(/\s\s*$/, ''); - } - - function checkWeekday(weekdayStr, parsedInput, config) { - if (weekdayStr) { - // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check. - var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr), - weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay(); - if (weekdayProvided !== weekdayActual) { - getParsingFlags(config).weekdayMismatch = true; - config._isValid = false; - return false; - } - } - return true; - } - - var obsOffsets = { - UT: 0, - GMT: 0, - EDT: -4 * 60, - EST: -5 * 60, - CDT: -5 * 60, - CST: -6 * 60, - MDT: -6 * 60, - MST: -7 * 60, - PDT: -7 * 60, - PST: -8 * 60 - }; - - function calculateOffset(obsOffset, militaryOffset, numOffset) { - if (obsOffset) { - return obsOffsets[obsOffset]; - } else if (militaryOffset) { - // the only allowed military tz is Z - return 0; - } else { - var hm = parseInt(numOffset, 10); - var m = hm % 100, h = (hm - m) / 100; - return h * 60 + m; - } - } - - // date and time from ref 2822 format - function configFromRFC2822(config) { - var match = rfc2822.exec(preprocessRFC2822(config._i)); - if (match) { - var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]); - if (!checkWeekday(match[1], parsedArray, config)) { - return; - } - - config._a = parsedArray; - config._tzm = calculateOffset(match[8], match[9], match[10]); - - config._d = createUTCDate.apply(null, config._a); - config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); - - getParsingFlags(config).rfc2822 = true; - } else { - config._isValid = false; - } - } - - // date from iso format or fallback - function configFromString(config) { - var matched = aspNetJsonRegex.exec(config._i); - - if (matched !== null) { - config._d = new Date(+matched[1]); - return; - } - - configFromISO(config); - if (config._isValid === false) { - delete config._isValid; - } else { - return; - } - - configFromRFC2822(config); - if (config._isValid === false) { - delete config._isValid; - } else { - return; - } - - // Final attempt, use Input Fallback - hooks.createFromInputFallback(config); - } - - hooks.createFromInputFallback = deprecate( - 'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' + - 'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' + - 'discouraged and will be removed in an upcoming major release. Please refer to ' + - 'http://momentjs.com/guides/#/warnings/js-date/ for more info.', - function (config) { - config._d = new Date(config._i + (config._useUTC ? ' UTC' : '')); - } - ); - - // constant that refers to the ISO standard - hooks.ISO_8601 = function () {}; - - // constant that refers to the RFC 2822 form - hooks.RFC_2822 = function () {}; - - // date from string and format string - function configFromStringAndFormat(config) { - // TODO: Move this to another part of the creation flow to prevent circular deps - if (config._f === hooks.ISO_8601) { - configFromISO(config); - return; - } - if (config._f === hooks.RFC_2822) { - configFromRFC2822(config); - return; - } - config._a = []; - getParsingFlags(config).empty = true; - - // This array is used to make a Date, either with `new Date` or `Date.UTC` - var string = '' + config._i, - i, parsedInput, tokens, token, skipped, - stringLength = string.length, - totalParsedInputLength = 0; - - tokens = expandFormat(config._f, config._locale).match(formattingTokens) || []; - - for (i = 0; i < tokens.length; i++) { - token = tokens[i]; - parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; - // console.log('token', token, 'parsedInput', parsedInput, - // 'regex', getParseRegexForToken(token, config)); - if (parsedInput) { - skipped = string.substr(0, string.indexOf(parsedInput)); - if (skipped.length > 0) { - getParsingFlags(config).unusedInput.push(skipped); - } - string = string.slice(string.indexOf(parsedInput) + parsedInput.length); - totalParsedInputLength += parsedInput.length; - } - // don't parse if it's not a known token - if (formatTokenFunctions[token]) { - if (parsedInput) { - getParsingFlags(config).empty = false; - } - else { - getParsingFlags(config).unusedTokens.push(token); - } - addTimeToArrayFromToken(token, parsedInput, config); - } - else if (config._strict && !parsedInput) { - getParsingFlags(config).unusedTokens.push(token); - } - } - - // add remaining unparsed input length to the string - getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength; - if (string.length > 0) { - getParsingFlags(config).unusedInput.push(string); - } - - // clear _12h flag if hour is <= 12 - if (config._a[HOUR] <= 12 && - getParsingFlags(config).bigHour === true && - config._a[HOUR] > 0) { - getParsingFlags(config).bigHour = undefined; - } - - getParsingFlags(config).parsedDateParts = config._a.slice(0); - getParsingFlags(config).meridiem = config._meridiem; - // handle meridiem - config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem); - - configFromArray(config); - checkOverflow(config); - } - - - function meridiemFixWrap (locale, hour, meridiem) { - var isPm; - - if (meridiem == null) { - // nothing to do - return hour; - } - if (locale.meridiemHour != null) { - return locale.meridiemHour(hour, meridiem); - } else if (locale.isPM != null) { - // Fallback - isPm = locale.isPM(meridiem); - if (isPm && hour < 12) { - hour += 12; - } - if (!isPm && hour === 12) { - hour = 0; - } - return hour; - } else { - // this is not supposed to happen - return hour; - } - } - - // date from string and array of format strings - function configFromStringAndArray(config) { - var tempConfig, - bestMoment, - - scoreToBeat, - i, - currentScore; - - if (config._f.length === 0) { - getParsingFlags(config).invalidFormat = true; - config._d = new Date(NaN); - return; - } - - for (i = 0; i < config._f.length; i++) { - currentScore = 0; - tempConfig = copyConfig({}, config); - if (config._useUTC != null) { - tempConfig._useUTC = config._useUTC; - } - tempConfig._f = config._f[i]; - configFromStringAndFormat(tempConfig); - - if (!isValid(tempConfig)) { - continue; - } - - // if there is any input that was not parsed add a penalty for that format - currentScore += getParsingFlags(tempConfig).charsLeftOver; - - //or tokens - currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10; - - getParsingFlags(tempConfig).score = currentScore; - - if (scoreToBeat == null || currentScore < scoreToBeat) { - scoreToBeat = currentScore; - bestMoment = tempConfig; - } - } - - extend(config, bestMoment || tempConfig); - } - - function configFromObject(config) { - if (config._d) { - return; - } - - var i = normalizeObjectUnits(config._i); - config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) { - return obj && parseInt(obj, 10); - }); - - configFromArray(config); - } - - function createFromConfig (config) { - var res = new Moment(checkOverflow(prepareConfig(config))); - if (res._nextDay) { - // Adding is smart enough around DST - res.add(1, 'd'); - res._nextDay = undefined; - } - - return res; - } - - function prepareConfig (config) { - var input = config._i, - format = config._f; - - config._locale = config._locale || getLocale(config._l); - - if (input === null || (format === undefined && input === '')) { - return createInvalid({nullInput: true}); - } - - if (typeof input === 'string') { - config._i = input = config._locale.preparse(input); - } - - if (isMoment(input)) { - return new Moment(checkOverflow(input)); - } else if (isDate(input)) { - config._d = input; - } else if (isArray(format)) { - configFromStringAndArray(config); - } else if (format) { - configFromStringAndFormat(config); - } else { - configFromInput(config); - } - - if (!isValid(config)) { - config._d = null; - } - - return config; - } - - function configFromInput(config) { - var input = config._i; - if (isUndefined(input)) { - config._d = new Date(hooks.now()); - } else if (isDate(input)) { - config._d = new Date(input.valueOf()); - } else if (typeof input === 'string') { - configFromString(config); - } else if (isArray(input)) { - config._a = map(input.slice(0), function (obj) { - return parseInt(obj, 10); - }); - configFromArray(config); - } else if (isObject(input)) { - configFromObject(config); - } else if (isNumber(input)) { - // from milliseconds - config._d = new Date(input); - } else { - hooks.createFromInputFallback(config); - } - } - - function createLocalOrUTC (input, format, locale, strict, isUTC) { - var c = {}; - - if (locale === true || locale === false) { - strict = locale; - locale = undefined; - } - - if ((isObject(input) && isObjectEmpty(input)) || - (isArray(input) && input.length === 0)) { - input = undefined; - } - // object construction must be done this way. - // https://github.com/moment/moment/issues/1423 - c._isAMomentObject = true; - c._useUTC = c._isUTC = isUTC; - c._l = locale; - c._i = input; - c._f = format; - c._strict = strict; - - return createFromConfig(c); - } - - function createLocal (input, format, locale, strict) { - return createLocalOrUTC(input, format, locale, strict, false); - } - - var prototypeMin = deprecate( - 'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', - function () { - var other = createLocal.apply(null, arguments); - if (this.isValid() && other.isValid()) { - return other < this ? this : other; - } else { - return createInvalid(); - } - } - ); - - var prototypeMax = deprecate( - 'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', - function () { - var other = createLocal.apply(null, arguments); - if (this.isValid() && other.isValid()) { - return other > this ? this : other; - } else { - return createInvalid(); - } - } - ); - - // Pick a moment m from moments so that m[fn](other) is true for all - // other. This relies on the function fn to be transitive. - // - // moments should either be an array of moment objects or an array, whose - // first element is an array of moment objects. - function pickBy(fn, moments) { - var res, i; - if (moments.length === 1 && isArray(moments[0])) { - moments = moments[0]; - } - if (!moments.length) { - return createLocal(); - } - res = moments[0]; - for (i = 1; i < moments.length; ++i) { - if (!moments[i].isValid() || moments[i][fn](res)) { - res = moments[i]; - } - } - return res; - } - - // TODO: Use [].sort instead? - function min () { - var args = [].slice.call(arguments, 0); - - return pickBy('isBefore', args); - } - - function max () { - var args = [].slice.call(arguments, 0); - - return pickBy('isAfter', args); - } - - var now = function () { - return Date.now ? Date.now() : +(new Date()); - }; - - var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond']; - - function isDurationValid(m) { - for (var key in m) { - if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) { - return false; - } - } - - var unitHasDecimal = false; - for (var i = 0; i < ordering.length; ++i) { - if (m[ordering[i]]) { - if (unitHasDecimal) { - return false; // only allow non-integers for smallest unit - } - if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) { - unitHasDecimal = true; - } - } - } - - return true; - } - - function isValid$1() { - return this._isValid; - } - - function createInvalid$1() { - return createDuration(NaN); - } - - function Duration (duration) { - var normalizedInput = normalizeObjectUnits(duration), - years = normalizedInput.year || 0, - quarters = normalizedInput.quarter || 0, - months = normalizedInput.month || 0, - weeks = normalizedInput.week || normalizedInput.isoWeek || 0, - days = normalizedInput.day || 0, - hours = normalizedInput.hour || 0, - minutes = normalizedInput.minute || 0, - seconds = normalizedInput.second || 0, - milliseconds = normalizedInput.millisecond || 0; - - this._isValid = isDurationValid(normalizedInput); - - // representation for dateAddRemove - this._milliseconds = +milliseconds + - seconds * 1e3 + // 1000 - minutes * 6e4 + // 1000 * 60 - hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978 - // Because of dateAddRemove treats 24 hours as different from a - // day when working around DST, we need to store them separately - this._days = +days + - weeks * 7; - // It is impossible to translate months into days without knowing - // which months you are are talking about, so we have to store - // it separately. - this._months = +months + - quarters * 3 + - years * 12; - - this._data = {}; - - this._locale = getLocale(); - - this._bubble(); - } - - function isDuration (obj) { - return obj instanceof Duration; - } - - function absRound (number) { - if (number < 0) { - return Math.round(-1 * number) * -1; - } else { - return Math.round(number); - } - } - - // FORMATTING - - function offset (token, separator) { - addFormatToken(token, 0, 0, function () { - var offset = this.utcOffset(); - var sign = '+'; - if (offset < 0) { - offset = -offset; - sign = '-'; - } - return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2); - }); - } - - offset('Z', ':'); - offset('ZZ', ''); - - // PARSING - - addRegexToken('Z', matchShortOffset); - addRegexToken('ZZ', matchShortOffset); - addParseToken(['Z', 'ZZ'], function (input, array, config) { - config._useUTC = true; - config._tzm = offsetFromString(matchShortOffset, input); - }); - - // HELPERS - - // timezone chunker - // '+10:00' > ['10', '00'] - // '-1530' > ['-15', '30'] - var chunkOffset = /([\+\-]|\d\d)/gi; - - function offsetFromString(matcher, string) { - var matches = (string || '').match(matcher); - - if (matches === null) { - return null; - } - - var chunk = matches[matches.length - 1] || []; - var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0]; - var minutes = +(parts[1] * 60) + toInt(parts[2]); - - return minutes === 0 ? - 0 : - parts[0] === '+' ? minutes : -minutes; - } - - // Return a moment from input, that is local/utc/zone equivalent to model. - function cloneWithOffset(input, model) { - var res, diff; - if (model._isUTC) { - res = model.clone(); - diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf(); - // Use low-level api, because this fn is low-level api. - res._d.setTime(res._d.valueOf() + diff); - hooks.updateOffset(res, false); - return res; - } else { - return createLocal(input).local(); - } - } - - function getDateOffset (m) { - // On Firefox.24 Date#getTimezoneOffset returns a floating point. - // https://github.com/moment/moment/pull/1871 - return -Math.round(m._d.getTimezoneOffset() / 15) * 15; - } - - // HOOKS - - // This function will be called whenever a moment is mutated. - // It is intended to keep the offset in sync with the timezone. - hooks.updateOffset = function () {}; - - // MOMENTS - - // keepLocalTime = true means only change the timezone, without - // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]--> - // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset - // +0200, so we adjust the time as needed, to be valid. - // - // Keeping the time actually adds/subtracts (one hour) - // from the actual represented time. That is why we call updateOffset - // a second time. In case it wants us to change the offset again - // _changeInProgress == true case, then we have to adjust, because - // there is no such time in the given timezone. - function getSetOffset (input, keepLocalTime, keepMinutes) { - var offset = this._offset || 0, - localAdjust; - if (!this.isValid()) { - return input != null ? this : NaN; - } - if (input != null) { - if (typeof input === 'string') { - input = offsetFromString(matchShortOffset, input); - if (input === null) { - return this; - } - } else if (Math.abs(input) < 16 && !keepMinutes) { - input = input * 60; - } - if (!this._isUTC && keepLocalTime) { - localAdjust = getDateOffset(this); - } - this._offset = input; - this._isUTC = true; - if (localAdjust != null) { - this.add(localAdjust, 'm'); - } - if (offset !== input) { - if (!keepLocalTime || this._changeInProgress) { - addSubtract(this, createDuration(input - offset, 'm'), 1, false); - } else if (!this._changeInProgress) { - this._changeInProgress = true; - hooks.updateOffset(this, true); - this._changeInProgress = null; - } - } - return this; - } else { - return this._isUTC ? offset : getDateOffset(this); - } - } - - function getSetZone (input, keepLocalTime) { - if (input != null) { - if (typeof input !== 'string') { - input = -input; - } - - this.utcOffset(input, keepLocalTime); - - return this; - } else { - return -this.utcOffset(); - } - } - - function setOffsetToUTC (keepLocalTime) { - return this.utcOffset(0, keepLocalTime); - } - - function setOffsetToLocal (keepLocalTime) { - if (this._isUTC) { - this.utcOffset(0, keepLocalTime); - this._isUTC = false; - - if (keepLocalTime) { - this.subtract(getDateOffset(this), 'm'); - } - } - return this; - } - - function setOffsetToParsedOffset () { - if (this._tzm != null) { - this.utcOffset(this._tzm, false, true); - } else if (typeof this._i === 'string') { - var tZone = offsetFromString(matchOffset, this._i); - if (tZone != null) { - this.utcOffset(tZone); - } - else { - this.utcOffset(0, true); - } - } - return this; - } - - function hasAlignedHourOffset (input) { - if (!this.isValid()) { - return false; - } - input = input ? createLocal(input).utcOffset() : 0; - - return (this.utcOffset() - input) % 60 === 0; - } - - function isDaylightSavingTime () { - return ( - this.utcOffset() > this.clone().month(0).utcOffset() || - this.utcOffset() > this.clone().month(5).utcOffset() - ); - } - - function isDaylightSavingTimeShifted () { - if (!isUndefined(this._isDSTShifted)) { - return this._isDSTShifted; - } - - var c = {}; - - copyConfig(c, this); - c = prepareConfig(c); - - if (c._a) { - var other = c._isUTC ? createUTC(c._a) : createLocal(c._a); - this._isDSTShifted = this.isValid() && - compareArrays(c._a, other.toArray()) > 0; - } else { - this._isDSTShifted = false; - } - - return this._isDSTShifted; - } - - function isLocal () { - return this.isValid() ? !this._isUTC : false; - } - - function isUtcOffset () { - return this.isValid() ? this._isUTC : false; - } - - function isUtc () { - return this.isValid() ? this._isUTC && this._offset === 0 : false; - } - - // ASP.NET json date format regex - var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; - - // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html - // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere - // and further modified to allow for strings containing both week and day - var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; - - function createDuration (input, key) { - var duration = input, - // matching against regexp is expensive, do it on demand - match = null, - sign, - ret, - diffRes; - - if (isDuration(input)) { - duration = { - ms : input._milliseconds, - d : input._days, - M : input._months - }; - } else if (isNumber(input)) { - duration = {}; - if (key) { - duration[key] = input; - } else { - duration.milliseconds = input; - } - } else if (!!(match = aspNetRegex.exec(input))) { - sign = (match[1] === '-') ? -1 : 1; - duration = { - y : 0, - d : toInt(match[DATE]) * sign, - h : toInt(match[HOUR]) * sign, - m : toInt(match[MINUTE]) * sign, - s : toInt(match[SECOND]) * sign, - ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match - }; - } else if (!!(match = isoRegex.exec(input))) { - sign = (match[1] === '-') ? -1 : 1; - duration = { - y : parseIso(match[2], sign), - M : parseIso(match[3], sign), - w : parseIso(match[4], sign), - d : parseIso(match[5], sign), - h : parseIso(match[6], sign), - m : parseIso(match[7], sign), - s : parseIso(match[8], sign) - }; - } else if (duration == null) {// checks for null or undefined - duration = {}; - } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) { - diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to)); - - duration = {}; - duration.ms = diffRes.milliseconds; - duration.M = diffRes.months; - } - - ret = new Duration(duration); - - if (isDuration(input) && hasOwnProp(input, '_locale')) { - ret._locale = input._locale; - } - - return ret; - } - - createDuration.fn = Duration.prototype; - createDuration.invalid = createInvalid$1; - - function parseIso (inp, sign) { - // We'd normally use ~~inp for this, but unfortunately it also - // converts floats to ints. - // inp may be undefined, so careful calling replace on it. - var res = inp && parseFloat(inp.replace(',', '.')); - // apply sign while we're at it - return (isNaN(res) ? 0 : res) * sign; - } - - function positiveMomentsDifference(base, other) { - var res = {}; - - res.months = other.month() - base.month() + - (other.year() - base.year()) * 12; - if (base.clone().add(res.months, 'M').isAfter(other)) { - --res.months; - } - - res.milliseconds = +other - +(base.clone().add(res.months, 'M')); - - return res; - } - - function momentsDifference(base, other) { - var res; - if (!(base.isValid() && other.isValid())) { - return {milliseconds: 0, months: 0}; - } - - other = cloneWithOffset(other, base); - if (base.isBefore(other)) { - res = positiveMomentsDifference(base, other); - } else { - res = positiveMomentsDifference(other, base); - res.milliseconds = -res.milliseconds; - res.months = -res.months; - } - - return res; - } - - // TODO: remove 'name' arg after deprecation is removed - function createAdder(direction, name) { - return function (val, period) { - var dur, tmp; - //invert the arguments, but complain about it - if (period !== null && !isNaN(+period)) { - deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' + - 'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.'); - tmp = val; val = period; period = tmp; - } - - val = typeof val === 'string' ? +val : val; - dur = createDuration(val, period); - addSubtract(this, dur, direction); - return this; - }; - } - - function addSubtract (mom, duration, isAdding, updateOffset) { - var milliseconds = duration._milliseconds, - days = absRound(duration._days), - months = absRound(duration._months); - - if (!mom.isValid()) { - // No op - return; - } - - updateOffset = updateOffset == null ? true : updateOffset; - - if (months) { - setMonth(mom, get(mom, 'Month') + months * isAdding); - } - if (days) { - set$1(mom, 'Date', get(mom, 'Date') + days * isAdding); - } - if (milliseconds) { - mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding); - } - if (updateOffset) { - hooks.updateOffset(mom, days || months); - } - } - - var add = createAdder(1, 'add'); - var subtract = createAdder(-1, 'subtract'); - - function getCalendarFormat(myMoment, now) { - var diff = myMoment.diff(now, 'days', true); - return diff < -6 ? 'sameElse' : - diff < -1 ? 'lastWeek' : - diff < 0 ? 'lastDay' : - diff < 1 ? 'sameDay' : - diff < 2 ? 'nextDay' : - diff < 7 ? 'nextWeek' : 'sameElse'; - } - - function calendar$1 (time, formats) { - // We want to compare the start of today, vs this. - // Getting start-of-today depends on whether we're local/utc/offset or not. - var now = time || createLocal(), - sod = cloneWithOffset(now, this).startOf('day'), - format = hooks.calendarFormat(this, sod) || 'sameElse'; - - var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]); - - return this.format(output || this.localeData().calendar(format, this, createLocal(now))); - } - - function clone () { - return new Moment(this); - } - - function isAfter (input, units) { - var localInput = isMoment(input) ? input : createLocal(input); - if (!(this.isValid() && localInput.isValid())) { - return false; - } - units = normalizeUnits(units) || 'millisecond'; - if (units === 'millisecond') { - return this.valueOf() > localInput.valueOf(); - } else { - return localInput.valueOf() < this.clone().startOf(units).valueOf(); - } - } - - function isBefore (input, units) { - var localInput = isMoment(input) ? input : createLocal(input); - if (!(this.isValid() && localInput.isValid())) { - return false; - } - units = normalizeUnits(units) || 'millisecond'; - if (units === 'millisecond') { - return this.valueOf() < localInput.valueOf(); - } else { - return this.clone().endOf(units).valueOf() < localInput.valueOf(); - } - } - - function isBetween (from, to, units, inclusivity) { - var localFrom = isMoment(from) ? from : createLocal(from), - localTo = isMoment(to) ? to : createLocal(to); - if (!(this.isValid() && localFrom.isValid() && localTo.isValid())) { - return false; - } - inclusivity = inclusivity || '()'; - return (inclusivity[0] === '(' ? this.isAfter(localFrom, units) : !this.isBefore(localFrom, units)) && - (inclusivity[1] === ')' ? this.isBefore(localTo, units) : !this.isAfter(localTo, units)); - } - - function isSame (input, units) { - var localInput = isMoment(input) ? input : createLocal(input), - inputMs; - if (!(this.isValid() && localInput.isValid())) { - return false; - } - units = normalizeUnits(units) || 'millisecond'; - if (units === 'millisecond') { - return this.valueOf() === localInput.valueOf(); - } else { - inputMs = localInput.valueOf(); - return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf(); - } - } - - function isSameOrAfter (input, units) { - return this.isSame(input, units) || this.isAfter(input, units); - } - - function isSameOrBefore (input, units) { - return this.isSame(input, units) || this.isBefore(input, units); - } - - function diff (input, units, asFloat) { - var that, - zoneDelta, - output; - - if (!this.isValid()) { - return NaN; - } - - that = cloneWithOffset(input, this); - - if (!that.isValid()) { - return NaN; - } - - zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4; - - units = normalizeUnits(units); - - switch (units) { - case 'year': output = monthDiff(this, that) / 12; break; - case 'month': output = monthDiff(this, that); break; - case 'quarter': output = monthDiff(this, that) / 3; break; - case 'second': output = (this - that) / 1e3; break; // 1000 - case 'minute': output = (this - that) / 6e4; break; // 1000 * 60 - case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60 - case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst - case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst - default: output = this - that; - } - - return asFloat ? output : absFloor(output); - } - - function monthDiff (a, b) { - // difference in months - var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()), - // b is in (anchor - 1 month, anchor + 1 month) - anchor = a.clone().add(wholeMonthDiff, 'months'), - anchor2, adjust; - - if (b - anchor < 0) { - anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); - // linear across the month - adjust = (b - anchor) / (anchor - anchor2); - } else { - anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); - // linear across the month - adjust = (b - anchor) / (anchor2 - anchor); - } - - //check for negative zero, return zero if negative zero - return -(wholeMonthDiff + adjust) || 0; - } - - hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ'; - hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]'; - - function toString () { - return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); - } - - function toISOString(keepOffset) { - if (!this.isValid()) { - return null; - } - var utc = keepOffset !== true; - var m = utc ? this.clone().utc() : this; - if (m.year() < 0 || m.year() > 9999) { - return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ'); - } - if (isFunction(Date.prototype.toISOString)) { - // native implementation is ~50x faster, use it when we can - if (utc) { - return this.toDate().toISOString(); - } else { - return new Date(this.valueOf() + this.utcOffset() * 60 * 1000).toISOString().replace('Z', formatMoment(m, 'Z')); - } - } - return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ'); - } - - /** - * Return a human readable representation of a moment that can - * also be evaluated to get a new moment which is the same - * - * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects - */ - function inspect () { - if (!this.isValid()) { - return 'moment.invalid(/* ' + this._i + ' */)'; - } - var func = 'moment'; - var zone = ''; - if (!this.isLocal()) { - func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone'; - zone = 'Z'; - } - var prefix = '[' + func + '("]'; - var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY'; - var datetime = '-MM-DD[T]HH:mm:ss.SSS'; - var suffix = zone + '[")]'; - - return this.format(prefix + year + datetime + suffix); - } - - function format (inputString) { - if (!inputString) { - inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat; - } - var output = formatMoment(this, inputString); - return this.localeData().postformat(output); - } - - function from (time, withoutSuffix) { - if (this.isValid() && - ((isMoment(time) && time.isValid()) || - createLocal(time).isValid())) { - return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); - } else { - return this.localeData().invalidDate(); - } - } - - function fromNow (withoutSuffix) { - return this.from(createLocal(), withoutSuffix); - } - - function to (time, withoutSuffix) { - if (this.isValid() && - ((isMoment(time) && time.isValid()) || - createLocal(time).isValid())) { - return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix); - } else { - return this.localeData().invalidDate(); - } - } - - function toNow (withoutSuffix) { - return this.to(createLocal(), withoutSuffix); - } - - // If passed a locale key, it will set the locale for this - // instance. Otherwise, it will return the locale configuration - // variables for this instance. - function locale (key) { - var newLocaleData; - - if (key === undefined) { - return this._locale._abbr; - } else { - newLocaleData = getLocale(key); - if (newLocaleData != null) { - this._locale = newLocaleData; - } - return this; - } - } - - var lang = deprecate( - 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', - function (key) { - if (key === undefined) { - return this.localeData(); - } else { - return this.locale(key); - } - } - ); - - function localeData () { - return this._locale; - } - - var MS_PER_SECOND = 1000; - var MS_PER_MINUTE = 60 * MS_PER_SECOND; - var MS_PER_HOUR = 60 * MS_PER_MINUTE; - var MS_PER_400_YEARS = (365 * 400 + 97) * 24 * MS_PER_HOUR; - - // actual modulo - handles negative numbers (for dates before 1970): - function mod$1(dividend, divisor) { - return (dividend % divisor + divisor) % divisor; - } - - function localStartOfDate(y, m, d) { - // the date constructor remaps years 0-99 to 1900-1999 - if (y < 100 && y >= 0) { - // preserve leap years using a full 400 year cycle, then reset - return new Date(y + 400, m, d) - MS_PER_400_YEARS; - } else { - return new Date(y, m, d).valueOf(); - } - } - - function utcStartOfDate(y, m, d) { - // Date.UTC remaps years 0-99 to 1900-1999 - if (y < 100 && y >= 0) { - // preserve leap years using a full 400 year cycle, then reset - return Date.UTC(y + 400, m, d) - MS_PER_400_YEARS; - } else { - return Date.UTC(y, m, d); - } - } - - function startOf (units) { - var time; - units = normalizeUnits(units); - if (units === undefined || units === 'millisecond' || !this.isValid()) { - return this; - } - - var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate; - - switch (units) { - case 'year': - time = startOfDate(this.year(), 0, 1); - break; - case 'quarter': - time = startOfDate(this.year(), this.month() - this.month() % 3, 1); - break; - case 'month': - time = startOfDate(this.year(), this.month(), 1); - break; - case 'week': - time = startOfDate(this.year(), this.month(), this.date() - this.weekday()); - break; - case 'isoWeek': - time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1)); - break; - case 'day': - case 'date': - time = startOfDate(this.year(), this.month(), this.date()); - break; - case 'hour': - time = this._d.valueOf(); - time -= mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR); - break; - case 'minute': - time = this._d.valueOf(); - time -= mod$1(time, MS_PER_MINUTE); - break; - case 'second': - time = this._d.valueOf(); - time -= mod$1(time, MS_PER_SECOND); - break; - } - - this._d.setTime(time); - hooks.updateOffset(this, true); - return this; - } - - function endOf (units) { - var time; - units = normalizeUnits(units); - if (units === undefined || units === 'millisecond' || !this.isValid()) { - return this; - } - - var startOfDate = this._isUTC ? utcStartOfDate : localStartOfDate; - - switch (units) { - case 'year': - time = startOfDate(this.year() + 1, 0, 1) - 1; - break; - case 'quarter': - time = startOfDate(this.year(), this.month() - this.month() % 3 + 3, 1) - 1; - break; - case 'month': - time = startOfDate(this.year(), this.month() + 1, 1) - 1; - break; - case 'week': - time = startOfDate(this.year(), this.month(), this.date() - this.weekday() + 7) - 1; - break; - case 'isoWeek': - time = startOfDate(this.year(), this.month(), this.date() - (this.isoWeekday() - 1) + 7) - 1; - break; - case 'day': - case 'date': - time = startOfDate(this.year(), this.month(), this.date() + 1) - 1; - break; - case 'hour': - time = this._d.valueOf(); - time += MS_PER_HOUR - mod$1(time + (this._isUTC ? 0 : this.utcOffset() * MS_PER_MINUTE), MS_PER_HOUR) - 1; - break; - case 'minute': - time = this._d.valueOf(); - time += MS_PER_MINUTE - mod$1(time, MS_PER_MINUTE) - 1; - break; - case 'second': - time = this._d.valueOf(); - time += MS_PER_SECOND - mod$1(time, MS_PER_SECOND) - 1; - break; - } - - this._d.setTime(time); - hooks.updateOffset(this, true); - return this; - } - - function valueOf () { - return this._d.valueOf() - ((this._offset || 0) * 60000); - } - - function unix () { - return Math.floor(this.valueOf() / 1000); - } - - function toDate () { - return new Date(this.valueOf()); - } - - function toArray () { - var m = this; - return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()]; - } - - function toObject () { - var m = this; - return { - years: m.year(), - months: m.month(), - date: m.date(), - hours: m.hours(), - minutes: m.minutes(), - seconds: m.seconds(), - milliseconds: m.milliseconds() - }; - } - - function toJSON () { - // new Date(NaN).toJSON() === null - return this.isValid() ? this.toISOString() : null; - } - - function isValid$2 () { - return isValid(this); - } - - function parsingFlags () { - return extend({}, getParsingFlags(this)); - } - - function invalidAt () { - return getParsingFlags(this).overflow; - } - - function creationData() { - return { - input: this._i, - format: this._f, - locale: this._locale, - isUTC: this._isUTC, - strict: this._strict - }; - } - - // FORMATTING - - addFormatToken(0, ['gg', 2], 0, function () { - return this.weekYear() % 100; - }); - - addFormatToken(0, ['GG', 2], 0, function () { - return this.isoWeekYear() % 100; - }); - - function addWeekYearFormatToken (token, getter) { - addFormatToken(0, [token, token.length], 0, getter); - } - - addWeekYearFormatToken('gggg', 'weekYear'); - addWeekYearFormatToken('ggggg', 'weekYear'); - addWeekYearFormatToken('GGGG', 'isoWeekYear'); - addWeekYearFormatToken('GGGGG', 'isoWeekYear'); - - // ALIASES - - addUnitAlias('weekYear', 'gg'); - addUnitAlias('isoWeekYear', 'GG'); - - // PRIORITY - - addUnitPriority('weekYear', 1); - addUnitPriority('isoWeekYear', 1); - - - // PARSING - - addRegexToken('G', matchSigned); - addRegexToken('g', matchSigned); - addRegexToken('GG', match1to2, match2); - addRegexToken('gg', match1to2, match2); - addRegexToken('GGGG', match1to4, match4); - addRegexToken('gggg', match1to4, match4); - addRegexToken('GGGGG', match1to6, match6); - addRegexToken('ggggg', match1to6, match6); - - addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) { - week[token.substr(0, 2)] = toInt(input); - }); - - addWeekParseToken(['gg', 'GG'], function (input, week, config, token) { - week[token] = hooks.parseTwoDigitYear(input); - }); - - // MOMENTS - - function getSetWeekYear (input) { - return getSetWeekYearHelper.call(this, - input, - this.week(), - this.weekday(), - this.localeData()._week.dow, - this.localeData()._week.doy); - } - - function getSetISOWeekYear (input) { - return getSetWeekYearHelper.call(this, - input, this.isoWeek(), this.isoWeekday(), 1, 4); - } - - function getISOWeeksInYear () { - return weeksInYear(this.year(), 1, 4); - } - - function getWeeksInYear () { - var weekInfo = this.localeData()._week; - return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); - } - - function getSetWeekYearHelper(input, week, weekday, dow, doy) { - var weeksTarget; - if (input == null) { - return weekOfYear(this, dow, doy).year; - } else { - weeksTarget = weeksInYear(input, dow, doy); - if (week > weeksTarget) { - week = weeksTarget; - } - return setWeekAll.call(this, input, week, weekday, dow, doy); - } - } - - function setWeekAll(weekYear, week, weekday, dow, doy) { - var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy), - date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear); - - this.year(date.getUTCFullYear()); - this.month(date.getUTCMonth()); - this.date(date.getUTCDate()); - return this; - } - - // FORMATTING - - addFormatToken('Q', 0, 'Qo', 'quarter'); - - // ALIASES - - addUnitAlias('quarter', 'Q'); - - // PRIORITY - - addUnitPriority('quarter', 7); - - // PARSING - - addRegexToken('Q', match1); - addParseToken('Q', function (input, array) { - array[MONTH] = (toInt(input) - 1) * 3; - }); - - // MOMENTS - - function getSetQuarter (input) { - return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); - } - - // FORMATTING - - addFormatToken('D', ['DD', 2], 'Do', 'date'); - - // ALIASES - - addUnitAlias('date', 'D'); - - // PRIORITY - addUnitPriority('date', 9); - - // PARSING - - addRegexToken('D', match1to2); - addRegexToken('DD', match1to2, match2); - addRegexToken('Do', function (isStrict, locale) { - // TODO: Remove "ordinalParse" fallback in next major release. - return isStrict ? - (locale._dayOfMonthOrdinalParse || locale._ordinalParse) : - locale._dayOfMonthOrdinalParseLenient; - }); - - addParseToken(['D', 'DD'], DATE); - addParseToken('Do', function (input, array) { - array[DATE] = toInt(input.match(match1to2)[0]); - }); - - // MOMENTS - - var getSetDayOfMonth = makeGetSet('Date', true); - - // FORMATTING - - addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); - - // ALIASES - - addUnitAlias('dayOfYear', 'DDD'); - - // PRIORITY - addUnitPriority('dayOfYear', 4); - - // PARSING - - addRegexToken('DDD', match1to3); - addRegexToken('DDDD', match3); - addParseToken(['DDD', 'DDDD'], function (input, array, config) { - config._dayOfYear = toInt(input); - }); - - // HELPERS - - // MOMENTS - - function getSetDayOfYear (input) { - var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1; - return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); - } - - // FORMATTING - - addFormatToken('m', ['mm', 2], 0, 'minute'); - - // ALIASES - - addUnitAlias('minute', 'm'); - - // PRIORITY - - addUnitPriority('minute', 14); - - // PARSING - - addRegexToken('m', match1to2); - addRegexToken('mm', match1to2, match2); - addParseToken(['m', 'mm'], MINUTE); - - // MOMENTS - - var getSetMinute = makeGetSet('Minutes', false); - - // FORMATTING - - addFormatToken('s', ['ss', 2], 0, 'second'); - - // ALIASES - - addUnitAlias('second', 's'); - - // PRIORITY - - addUnitPriority('second', 15); - - // PARSING - - addRegexToken('s', match1to2); - addRegexToken('ss', match1to2, match2); - addParseToken(['s', 'ss'], SECOND); - - // MOMENTS - - var getSetSecond = makeGetSet('Seconds', false); - - // FORMATTING - - addFormatToken('S', 0, 0, function () { - return ~~(this.millisecond() / 100); - }); - - addFormatToken(0, ['SS', 2], 0, function () { - return ~~(this.millisecond() / 10); - }); - - addFormatToken(0, ['SSS', 3], 0, 'millisecond'); - addFormatToken(0, ['SSSS', 4], 0, function () { - return this.millisecond() * 10; - }); - addFormatToken(0, ['SSSSS', 5], 0, function () { - return this.millisecond() * 100; - }); - addFormatToken(0, ['SSSSSS', 6], 0, function () { - return this.millisecond() * 1000; - }); - addFormatToken(0, ['SSSSSSS', 7], 0, function () { - return this.millisecond() * 10000; - }); - addFormatToken(0, ['SSSSSSSS', 8], 0, function () { - return this.millisecond() * 100000; - }); - addFormatToken(0, ['SSSSSSSSS', 9], 0, function () { - return this.millisecond() * 1000000; - }); - - - // ALIASES - - addUnitAlias('millisecond', 'ms'); - - // PRIORITY - - addUnitPriority('millisecond', 16); - - // PARSING - - addRegexToken('S', match1to3, match1); - addRegexToken('SS', match1to3, match2); - addRegexToken('SSS', match1to3, match3); - - var token; - for (token = 'SSSS'; token.length <= 9; token += 'S') { - addRegexToken(token, matchUnsigned); - } - - function parseMs(input, array) { - array[MILLISECOND] = toInt(('0.' + input) * 1000); - } - - for (token = 'S'; token.length <= 9; token += 'S') { - addParseToken(token, parseMs); - } - // MOMENTS - - var getSetMillisecond = makeGetSet('Milliseconds', false); - - // FORMATTING - - addFormatToken('z', 0, 0, 'zoneAbbr'); - addFormatToken('zz', 0, 0, 'zoneName'); - - // MOMENTS - - function getZoneAbbr () { - return this._isUTC ? 'UTC' : ''; - } - - function getZoneName () { - return this._isUTC ? 'Coordinated Universal Time' : ''; - } - - var proto = Moment.prototype; - - proto.add = add; - proto.calendar = calendar$1; - proto.clone = clone; - proto.diff = diff; - proto.endOf = endOf; - proto.format = format; - proto.from = from; - proto.fromNow = fromNow; - proto.to = to; - proto.toNow = toNow; - proto.get = stringGet; - proto.invalidAt = invalidAt; - proto.isAfter = isAfter; - proto.isBefore = isBefore; - proto.isBetween = isBetween; - proto.isSame = isSame; - proto.isSameOrAfter = isSameOrAfter; - proto.isSameOrBefore = isSameOrBefore; - proto.isValid = isValid$2; - proto.lang = lang; - proto.locale = locale; - proto.localeData = localeData; - proto.max = prototypeMax; - proto.min = prototypeMin; - proto.parsingFlags = parsingFlags; - proto.set = stringSet; - proto.startOf = startOf; - proto.subtract = subtract; - proto.toArray = toArray; - proto.toObject = toObject; - proto.toDate = toDate; - proto.toISOString = toISOString; - proto.inspect = inspect; - proto.toJSON = toJSON; - proto.toString = toString; - proto.unix = unix; - proto.valueOf = valueOf; - proto.creationData = creationData; - proto.year = getSetYear; - proto.isLeapYear = getIsLeapYear; - proto.weekYear = getSetWeekYear; - proto.isoWeekYear = getSetISOWeekYear; - proto.quarter = proto.quarters = getSetQuarter; - proto.month = getSetMonth; - proto.daysInMonth = getDaysInMonth; - proto.week = proto.weeks = getSetWeek; - proto.isoWeek = proto.isoWeeks = getSetISOWeek; - proto.weeksInYear = getWeeksInYear; - proto.isoWeeksInYear = getISOWeeksInYear; - proto.date = getSetDayOfMonth; - proto.day = proto.days = getSetDayOfWeek; - proto.weekday = getSetLocaleDayOfWeek; - proto.isoWeekday = getSetISODayOfWeek; - proto.dayOfYear = getSetDayOfYear; - proto.hour = proto.hours = getSetHour; - proto.minute = proto.minutes = getSetMinute; - proto.second = proto.seconds = getSetSecond; - proto.millisecond = proto.milliseconds = getSetMillisecond; - proto.utcOffset = getSetOffset; - proto.utc = setOffsetToUTC; - proto.local = setOffsetToLocal; - proto.parseZone = setOffsetToParsedOffset; - proto.hasAlignedHourOffset = hasAlignedHourOffset; - proto.isDST = isDaylightSavingTime; - proto.isLocal = isLocal; - proto.isUtcOffset = isUtcOffset; - proto.isUtc = isUtc; - proto.isUTC = isUtc; - proto.zoneAbbr = getZoneAbbr; - proto.zoneName = getZoneName; - proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth); - proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth); - proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear); - proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone); - proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted); - - function createUnix (input) { - return createLocal(input * 1000); - } - - function createInZone () { - return createLocal.apply(null, arguments).parseZone(); - } - - function preParsePostFormat (string) { - return string; - } - - var proto$1 = Locale.prototype; - - proto$1.calendar = calendar; - proto$1.longDateFormat = longDateFormat; - proto$1.invalidDate = invalidDate; - proto$1.ordinal = ordinal; - proto$1.preparse = preParsePostFormat; - proto$1.postformat = preParsePostFormat; - proto$1.relativeTime = relativeTime; - proto$1.pastFuture = pastFuture; - proto$1.set = set; - - proto$1.months = localeMonths; - proto$1.monthsShort = localeMonthsShort; - proto$1.monthsParse = localeMonthsParse; - proto$1.monthsRegex = monthsRegex; - proto$1.monthsShortRegex = monthsShortRegex; - proto$1.week = localeWeek; - proto$1.firstDayOfYear = localeFirstDayOfYear; - proto$1.firstDayOfWeek = localeFirstDayOfWeek; - - proto$1.weekdays = localeWeekdays; - proto$1.weekdaysMin = localeWeekdaysMin; - proto$1.weekdaysShort = localeWeekdaysShort; - proto$1.weekdaysParse = localeWeekdaysParse; - - proto$1.weekdaysRegex = weekdaysRegex; - proto$1.weekdaysShortRegex = weekdaysShortRegex; - proto$1.weekdaysMinRegex = weekdaysMinRegex; - - proto$1.isPM = localeIsPM; - proto$1.meridiem = localeMeridiem; - - function get$1 (format, index, field, setter) { - var locale = getLocale(); - var utc = createUTC().set(setter, index); - return locale[field](utc, format); - } - - function listMonthsImpl (format, index, field) { - if (isNumber(format)) { - index = format; - format = undefined; - } - - format = format || ''; - - if (index != null) { - return get$1(format, index, field, 'month'); - } - - var i; - var out = []; - for (i = 0; i < 12; i++) { - out[i] = get$1(format, i, field, 'month'); - } - return out; - } - - // () - // (5) - // (fmt, 5) - // (fmt) - // (true) - // (true, 5) - // (true, fmt, 5) - // (true, fmt) - function listWeekdaysImpl (localeSorted, format, index, field) { - if (typeof localeSorted === 'boolean') { - if (isNumber(format)) { - index = format; - format = undefined; - } - - format = format || ''; - } else { - format = localeSorted; - index = format; - localeSorted = false; - - if (isNumber(format)) { - index = format; - format = undefined; - } - - format = format || ''; - } - - var locale = getLocale(), - shift = localeSorted ? locale._week.dow : 0; - - if (index != null) { - return get$1(format, (index + shift) % 7, field, 'day'); - } - - var i; - var out = []; - for (i = 0; i < 7; i++) { - out[i] = get$1(format, (i + shift) % 7, field, 'day'); - } - return out; - } - - function listMonths (format, index) { - return listMonthsImpl(format, index, 'months'); - } - - function listMonthsShort (format, index) { - return listMonthsImpl(format, index, 'monthsShort'); - } - - function listWeekdays (localeSorted, format, index) { - return listWeekdaysImpl(localeSorted, format, index, 'weekdays'); - } - - function listWeekdaysShort (localeSorted, format, index) { - return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort'); - } - - function listWeekdaysMin (localeSorted, format, index) { - return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin'); - } - - getSetGlobalLocale('en', { - dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, - ordinal : function (number) { - var b = number % 10, - output = (toInt(number % 100 / 10) === 1) ? 'th' : - (b === 1) ? 'st' : - (b === 2) ? 'nd' : - (b === 3) ? 'rd' : 'th'; - return number + output; - } - }); - - // Side effect imports - - hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale); - hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale); - - var mathAbs = Math.abs; - - function abs () { - var data = this._data; - - this._milliseconds = mathAbs(this._milliseconds); - this._days = mathAbs(this._days); - this._months = mathAbs(this._months); - - data.milliseconds = mathAbs(data.milliseconds); - data.seconds = mathAbs(data.seconds); - data.minutes = mathAbs(data.minutes); - data.hours = mathAbs(data.hours); - data.months = mathAbs(data.months); - data.years = mathAbs(data.years); - - return this; - } - - function addSubtract$1 (duration, input, value, direction) { - var other = createDuration(input, value); - - duration._milliseconds += direction * other._milliseconds; - duration._days += direction * other._days; - duration._months += direction * other._months; - - return duration._bubble(); - } - - // supports only 2.0-style add(1, 's') or add(duration) - function add$1 (input, value) { - return addSubtract$1(this, input, value, 1); - } - - // supports only 2.0-style subtract(1, 's') or subtract(duration) - function subtract$1 (input, value) { - return addSubtract$1(this, input, value, -1); - } - - function absCeil (number) { - if (number < 0) { - return Math.floor(number); - } else { - return Math.ceil(number); - } - } - - function bubble () { - var milliseconds = this._milliseconds; - var days = this._days; - var months = this._months; - var data = this._data; - var seconds, minutes, hours, years, monthsFromDays; - - // if we have a mix of positive and negative values, bubble down first - // check: https://github.com/moment/moment/issues/2166 - if (!((milliseconds >= 0 && days >= 0 && months >= 0) || - (milliseconds <= 0 && days <= 0 && months <= 0))) { - milliseconds += absCeil(monthsToDays(months) + days) * 864e5; - days = 0; - months = 0; - } - - // The following code bubbles up values, see the tests for - // examples of what that means. - data.milliseconds = milliseconds % 1000; - - seconds = absFloor(milliseconds / 1000); - data.seconds = seconds % 60; - - minutes = absFloor(seconds / 60); - data.minutes = minutes % 60; - - hours = absFloor(minutes / 60); - data.hours = hours % 24; - - days += absFloor(hours / 24); - - // convert days to months - monthsFromDays = absFloor(daysToMonths(days)); - months += monthsFromDays; - days -= absCeil(monthsToDays(monthsFromDays)); - - // 12 months -> 1 year - years = absFloor(months / 12); - months %= 12; - - data.days = days; - data.months = months; - data.years = years; - - return this; - } - - function daysToMonths (days) { - // 400 years have 146097 days (taking into account leap year rules) - // 400 years have 12 months === 4800 - return days * 4800 / 146097; - } - - function monthsToDays (months) { - // the reverse of daysToMonths - return months * 146097 / 4800; - } - - function as (units) { - if (!this.isValid()) { - return NaN; - } - var days; - var months; - var milliseconds = this._milliseconds; - - units = normalizeUnits(units); - - if (units === 'month' || units === 'quarter' || units === 'year') { - days = this._days + milliseconds / 864e5; - months = this._months + daysToMonths(days); - switch (units) { - case 'month': return months; - case 'quarter': return months / 3; - case 'year': return months / 12; - } - } else { - // handle milliseconds separately because of floating point math errors (issue #1867) - days = this._days + Math.round(monthsToDays(this._months)); - switch (units) { - case 'week' : return days / 7 + milliseconds / 6048e5; - case 'day' : return days + milliseconds / 864e5; - case 'hour' : return days * 24 + milliseconds / 36e5; - case 'minute' : return days * 1440 + milliseconds / 6e4; - case 'second' : return days * 86400 + milliseconds / 1000; - // Math.floor prevents floating point math errors here - case 'millisecond': return Math.floor(days * 864e5) + milliseconds; - default: throw new Error('Unknown unit ' + units); - } - } - } - - // TODO: Use this.as('ms')? - function valueOf$1 () { - if (!this.isValid()) { - return NaN; - } - return ( - this._milliseconds + - this._days * 864e5 + - (this._months % 12) * 2592e6 + - toInt(this._months / 12) * 31536e6 - ); - } - - function makeAs (alias) { - return function () { - return this.as(alias); - }; - } - - var asMilliseconds = makeAs('ms'); - var asSeconds = makeAs('s'); - var asMinutes = makeAs('m'); - var asHours = makeAs('h'); - var asDays = makeAs('d'); - var asWeeks = makeAs('w'); - var asMonths = makeAs('M'); - var asQuarters = makeAs('Q'); - var asYears = makeAs('y'); - - function clone$1 () { - return createDuration(this); - } - - function get$2 (units) { - units = normalizeUnits(units); - return this.isValid() ? this[units + 's']() : NaN; - } - - function makeGetter(name) { - return function () { - return this.isValid() ? this._data[name] : NaN; - }; - } - - var milliseconds = makeGetter('milliseconds'); - var seconds = makeGetter('seconds'); - var minutes = makeGetter('minutes'); - var hours = makeGetter('hours'); - var days = makeGetter('days'); - var months = makeGetter('months'); - var years = makeGetter('years'); - - function weeks () { - return absFloor(this.days() / 7); - } - - var round = Math.round; - var thresholds = { - ss: 44, // a few seconds to seconds - s : 45, // seconds to minute - m : 45, // minutes to hour - h : 22, // hours to day - d : 26, // days to month - M : 11 // months to year - }; - - // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize - function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { - return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); - } - - function relativeTime$1 (posNegDuration, withoutSuffix, locale) { - var duration = createDuration(posNegDuration).abs(); - var seconds = round(duration.as('s')); - var minutes = round(duration.as('m')); - var hours = round(duration.as('h')); - var days = round(duration.as('d')); - var months = round(duration.as('M')); - var years = round(duration.as('y')); - - var a = seconds <= thresholds.ss && ['s', seconds] || - seconds < thresholds.s && ['ss', seconds] || - minutes <= 1 && ['m'] || - minutes < thresholds.m && ['mm', minutes] || - hours <= 1 && ['h'] || - hours < thresholds.h && ['hh', hours] || - days <= 1 && ['d'] || - days < thresholds.d && ['dd', days] || - months <= 1 && ['M'] || - months < thresholds.M && ['MM', months] || - years <= 1 && ['y'] || ['yy', years]; - - a[2] = withoutSuffix; - a[3] = +posNegDuration > 0; - a[4] = locale; - return substituteTimeAgo.apply(null, a); - } - - // This function allows you to set the rounding function for relative time strings - function getSetRelativeTimeRounding (roundingFunction) { - if (roundingFunction === undefined) { - return round; - } - if (typeof(roundingFunction) === 'function') { - round = roundingFunction; - return true; - } - return false; - } - - // This function allows you to set a threshold for relative time strings - function getSetRelativeTimeThreshold (threshold, limit) { - if (thresholds[threshold] === undefined) { - return false; - } - if (limit === undefined) { - return thresholds[threshold]; - } - thresholds[threshold] = limit; - if (threshold === 's') { - thresholds.ss = limit - 1; - } - return true; - } - - function humanize (withSuffix) { - if (!this.isValid()) { - return this.localeData().invalidDate(); - } - - var locale = this.localeData(); - var output = relativeTime$1(this, !withSuffix, locale); - - if (withSuffix) { - output = locale.pastFuture(+this, output); - } - - return locale.postformat(output); - } - - var abs$1 = Math.abs; - - function sign(x) { - return ((x > 0) - (x < 0)) || +x; - } - - function toISOString$1() { - // for ISO strings we do not use the normal bubbling rules: - // * milliseconds bubble up until they become hours - // * days do not bubble at all - // * months bubble up until they become years - // This is because there is no context-free conversion between hours and days - // (think of clock changes) - // and also not between days and months (28-31 days per month) - if (!this.isValid()) { - return this.localeData().invalidDate(); - } - - var seconds = abs$1(this._milliseconds) / 1000; - var days = abs$1(this._days); - var months = abs$1(this._months); - var minutes, hours, years; - - // 3600 seconds -> 60 minutes -> 1 hour - minutes = absFloor(seconds / 60); - hours = absFloor(minutes / 60); - seconds %= 60; - minutes %= 60; - - // 12 months -> 1 year - years = absFloor(months / 12); - months %= 12; - - - // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js - var Y = years; - var M = months; - var D = days; - var h = hours; - var m = minutes; - var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : ''; - var total = this.asSeconds(); - - if (!total) { - // this is the same as C#'s (Noda) and python (isodate)... - // but not other JS (goog.date) - return 'P0D'; - } - - var totalSign = total < 0 ? '-' : ''; - var ymSign = sign(this._months) !== sign(total) ? '-' : ''; - var daysSign = sign(this._days) !== sign(total) ? '-' : ''; - var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : ''; - - return totalSign + 'P' + - (Y ? ymSign + Y + 'Y' : '') + - (M ? ymSign + M + 'M' : '') + - (D ? daysSign + D + 'D' : '') + - ((h || m || s) ? 'T' : '') + - (h ? hmsSign + h + 'H' : '') + - (m ? hmsSign + m + 'M' : '') + - (s ? hmsSign + s + 'S' : ''); - } - - var proto$2 = Duration.prototype; - - proto$2.isValid = isValid$1; - proto$2.abs = abs; - proto$2.add = add$1; - proto$2.subtract = subtract$1; - proto$2.as = as; - proto$2.asMilliseconds = asMilliseconds; - proto$2.asSeconds = asSeconds; - proto$2.asMinutes = asMinutes; - proto$2.asHours = asHours; - proto$2.asDays = asDays; - proto$2.asWeeks = asWeeks; - proto$2.asMonths = asMonths; - proto$2.asQuarters = asQuarters; - proto$2.asYears = asYears; - proto$2.valueOf = valueOf$1; - proto$2._bubble = bubble; - proto$2.clone = clone$1; - proto$2.get = get$2; - proto$2.milliseconds = milliseconds; - proto$2.seconds = seconds; - proto$2.minutes = minutes; - proto$2.hours = hours; - proto$2.days = days; - proto$2.weeks = weeks; - proto$2.months = months; - proto$2.years = years; - proto$2.humanize = humanize; - proto$2.toISOString = toISOString$1; - proto$2.toString = toISOString$1; - proto$2.toJSON = toISOString$1; - proto$2.locale = locale; - proto$2.localeData = localeData; - - proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1); - proto$2.lang = lang; - - // Side effect imports - - // FORMATTING - - addFormatToken('X', 0, 0, 'unix'); - addFormatToken('x', 0, 0, 'valueOf'); - - // PARSING - - addRegexToken('x', matchSigned); - addRegexToken('X', matchTimestamp); - addParseToken('X', function (input, array, config) { - config._d = new Date(parseFloat(input, 10) * 1000); - }); - addParseToken('x', function (input, array, config) { - config._d = new Date(toInt(input)); - }); - - // Side effect imports - - - hooks.version = '2.24.0'; - - setHookCallback(createLocal); - - hooks.fn = proto; - hooks.min = min; - hooks.max = max; - hooks.now = now; - hooks.utc = createUTC; - hooks.unix = createUnix; - hooks.months = listMonths; - hooks.isDate = isDate; - hooks.locale = getSetGlobalLocale; - hooks.invalid = createInvalid; - hooks.duration = createDuration; - hooks.isMoment = isMoment; - hooks.weekdays = listWeekdays; - hooks.parseZone = createInZone; - hooks.localeData = getLocale; - hooks.isDuration = isDuration; - hooks.monthsShort = listMonthsShort; - hooks.weekdaysMin = listWeekdaysMin; - hooks.defineLocale = defineLocale; - hooks.updateLocale = updateLocale; - hooks.locales = listLocales; - hooks.weekdaysShort = listWeekdaysShort; - hooks.normalizeUnits = normalizeUnits; - hooks.relativeTimeRounding = getSetRelativeTimeRounding; - hooks.relativeTimeThreshold = getSetRelativeTimeThreshold; - hooks.calendarFormat = getCalendarFormat; - hooks.prototype = proto; - - // currently HTML5 input type only supports 24-hour formats - hooks.HTML5_FMT = { - DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', // - DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // - DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // - DATE: 'YYYY-MM-DD', // - TIME: 'HH:mm', // - TIME_SECONDS: 'HH:mm:ss', // - TIME_MS: 'HH:mm:ss.SSS', // - WEEK: 'GGGG-[W]WW', // - MONTH: 'YYYY-MM' // - }; - - return hooks; - -}))); -}); - -var FORMATS = { - datetime: 'MMM D, YYYY, h:mm:ss a', - millisecond: 'h:mm:ss.SSS a', - second: 'h:mm:ss a', - minute: 'h:mm a', - hour: 'hA', - day: 'MMM D', - week: 'll', - month: 'MMM YYYY', - quarter: '[Q]Q - YYYY', - year: 'YYYY' -}; - -core_adapters._date.override(typeof moment === 'function' ? { - _id: 'moment', // DEBUG ONLY - - formats: function() { - return FORMATS; - }, - - parse: function(value, format) { - if (typeof value === 'string' && typeof format === 'string') { - value = moment(value, format); - } else if (!(value instanceof moment)) { - value = moment(value); - } - return value.isValid() ? value.valueOf() : null; - }, - - format: function(time, format) { - return moment(time).format(format); - }, - - add: function(time, amount, unit) { - return moment(time).add(amount, unit).valueOf(); - }, - - diff: function(max, min, unit) { - return moment.duration(moment(max).diff(moment(min))).as(unit); - }, - - startOf: function(time, unit, weekday) { - time = moment(time); - if (unit === 'isoWeek') { - return time.isoWeekday(weekday).valueOf(); - } - return time.startOf(unit).valueOf(); - }, - - endOf: function(time, unit) { - return moment(time).endOf(unit).valueOf(); - }, - - // DEPRECATIONS - - /** - * Provided for backward compatibility with scale.getValueForPixel(). - * @deprecated since version 2.8.0 - * @todo remove at version 3 - * @private - */ - _create: function(time) { - return moment(time); - }, -} : {}); - -core_defaults._set('global', { - plugins: { - filler: { - propagate: true - } - } -}); - -var mappers = { - dataset: function(source) { - var index = source.fill; - var chart = source.chart; - var meta = chart.getDatasetMeta(index); - var visible = meta && chart.isDatasetVisible(index); - var points = (visible && meta.dataset._children) || []; - var length = points.length || 0; - - return !length ? null : function(point, i) { - return (i < length && points[i]._view) || null; - }; - }, - - boundary: function(source) { - var boundary = source.boundary; - var x = boundary ? boundary.x : null; - var y = boundary ? boundary.y : null; - - return function(point) { - return { - x: x === null ? point.x : x, - y: y === null ? point.y : y, - }; - }; - } -}; - -// @todo if (fill[0] === '#') -function decodeFill(el, index, count) { - var model = el._model || {}; - var fill = model.fill; - var target; - - if (fill === undefined) { - fill = !!model.backgroundColor; - } - - if (fill === false || fill === null) { - return false; - } - - if (fill === true) { - return 'origin'; - } - - target = parseFloat(fill, 10); - if (isFinite(target) && Math.floor(target) === target) { - if (fill[0] === '-' || fill[0] === '+') { - target = index + target; - } - - if (target === index || target < 0 || target >= count) { - return false; - } - - return target; - } - - switch (fill) { - // compatibility - case 'bottom': - return 'start'; - case 'top': - return 'end'; - case 'zero': - return 'origin'; - // supported boundaries - case 'origin': - case 'start': - case 'end': - return fill; - // invalid fill values - default: - return false; - } -} - -function computeBoundary(source) { - var model = source.el._model || {}; - var scale = source.el._scale || {}; - var fill = source.fill; - var target = null; - var horizontal; - - if (isFinite(fill)) { - return null; - } - - // Backward compatibility: until v3, we still need to support boundary values set on - // the model (scaleTop, scaleBottom and scaleZero) because some external plugins and - // controllers might still use it (e.g. the Smith chart). - - if (fill === 'start') { - target = model.scaleBottom === undefined ? scale.bottom : model.scaleBottom; - } else if (fill === 'end') { - target = model.scaleTop === undefined ? scale.top : model.scaleTop; - } else if (model.scaleZero !== undefined) { - target = model.scaleZero; - } else if (scale.getBasePosition) { - target = scale.getBasePosition(); - } else if (scale.getBasePixel) { - target = scale.getBasePixel(); - } - - if (target !== undefined && target !== null) { - if (target.x !== undefined && target.y !== undefined) { - return target; - } - - if (helpers$1.isFinite(target)) { - horizontal = scale.isHorizontal(); - return { - x: horizontal ? target : null, - y: horizontal ? null : target - }; - } - } - - return null; -} - -function resolveTarget(sources, index, propagate) { - var source = sources[index]; - var fill = source.fill; - var visited = [index]; - var target; - - if (!propagate) { - return fill; - } - - while (fill !== false && visited.indexOf(fill) === -1) { - if (!isFinite(fill)) { - return fill; - } - - target = sources[fill]; - if (!target) { - return false; - } - - if (target.visible) { - return fill; - } - - visited.push(fill); - fill = target.fill; - } - - return false; -} - -function createMapper(source) { - var fill = source.fill; - var type = 'dataset'; - - if (fill === false) { - return null; - } - - if (!isFinite(fill)) { - type = 'boundary'; - } - - return mappers[type](source); -} - -function isDrawable(point) { - return point && !point.skip; -} - -function drawArea(ctx, curve0, curve1, len0, len1) { - var i; - - if (!len0 || !len1) { - return; - } - - // building first area curve (normal) - ctx.moveTo(curve0[0].x, curve0[0].y); - for (i = 1; i < len0; ++i) { - helpers$1.canvas.lineTo(ctx, curve0[i - 1], curve0[i]); - } - - // joining the two area curves - ctx.lineTo(curve1[len1 - 1].x, curve1[len1 - 1].y); - - // building opposite area curve (reverse) - for (i = len1 - 1; i > 0; --i) { - helpers$1.canvas.lineTo(ctx, curve1[i], curve1[i - 1], true); - } -} - -function doFill(ctx, points, mapper, view, color, loop) { - var count = points.length; - var span = view.spanGaps; - var curve0 = []; - var curve1 = []; - var len0 = 0; - var len1 = 0; - var i, ilen, index, p0, p1, d0, d1; - - ctx.beginPath(); - - for (i = 0, ilen = (count + !!loop); i < ilen; ++i) { - index = i % count; - p0 = points[index]._view; - p1 = mapper(p0, index, view); - d0 = isDrawable(p0); - d1 = isDrawable(p1); - - if (d0 && d1) { - len0 = curve0.push(p0); - len1 = curve1.push(p1); - } else if (len0 && len1) { - if (!span) { - drawArea(ctx, curve0, curve1, len0, len1); - len0 = len1 = 0; - curve0 = []; - curve1 = []; - } else { - if (d0) { - curve0.push(p0); - } - if (d1) { - curve1.push(p1); - } - } - } - } - - drawArea(ctx, curve0, curve1, len0, len1); - - ctx.closePath(); - ctx.fillStyle = color; - ctx.fill(); -} - -var plugin_filler = { - id: 'filler', - - afterDatasetsUpdate: function(chart, options) { - var count = (chart.data.datasets || []).length; - var propagate = options.propagate; - var sources = []; - var meta, i, el, source; - - for (i = 0; i < count; ++i) { - meta = chart.getDatasetMeta(i); - el = meta.dataset; - source = null; - - if (el && el._model && el instanceof elements.Line) { - source = { - visible: chart.isDatasetVisible(i), - fill: decodeFill(el, i, count), - chart: chart, - el: el - }; - } - - meta.$filler = source; - sources.push(source); - } - - for (i = 0; i < count; ++i) { - source = sources[i]; - if (!source) { - continue; - } - - source.fill = resolveTarget(sources, i, propagate); - source.boundary = computeBoundary(source); - source.mapper = createMapper(source); - } - }, - - beforeDatasetDraw: function(chart, args) { - var meta = args.meta.$filler; - if (!meta) { - return; - } - - var ctx = chart.ctx; - var el = meta.el; - var view = el._view; - var points = el._children || []; - var mapper = meta.mapper; - var color = view.backgroundColor || core_defaults.global.defaultColor; - - if (mapper && color && points.length) { - helpers$1.canvas.clipArea(ctx, chart.chartArea); - doFill(ctx, points, mapper, view, color, el._loop); - helpers$1.canvas.unclipArea(ctx); - } - } -}; - -var noop$1 = helpers$1.noop; -var valueOrDefault$d = helpers$1.valueOrDefault; - -core_defaults._set('global', { - legend: { - display: true, - position: 'top', - fullWidth: true, - reverse: false, - weight: 1000, - - // a callback that will handle - onClick: function(e, legendItem) { - var index = legendItem.datasetIndex; - var ci = this.chart; - var meta = ci.getDatasetMeta(index); - - // See controller.isDatasetVisible comment - meta.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null; - - // We hid a dataset ... rerender the chart - ci.update(); - }, - - onHover: null, - onLeave: null, - - labels: { - boxWidth: 40, - padding: 10, - // Generates labels shown in the legend - // Valid properties to return: - // text : text to display - // fillStyle : fill of coloured box - // strokeStyle: stroke of coloured box - // hidden : if this legend item refers to a hidden item - // lineCap : cap style for line - // lineDash - // lineDashOffset : - // lineJoin : - // lineWidth : - generateLabels: function(chart) { - var data = chart.data; - return helpers$1.isArray(data.datasets) ? data.datasets.map(function(dataset, i) { - return { - text: dataset.label, - fillStyle: (!helpers$1.isArray(dataset.backgroundColor) ? dataset.backgroundColor : dataset.backgroundColor[0]), - hidden: !chart.isDatasetVisible(i), - lineCap: dataset.borderCapStyle, - lineDash: dataset.borderDash, - lineDashOffset: dataset.borderDashOffset, - lineJoin: dataset.borderJoinStyle, - lineWidth: dataset.borderWidth, - strokeStyle: dataset.borderColor, - pointStyle: dataset.pointStyle, - - // Below is extra data used for toggling the datasets - datasetIndex: i - }; - }, this) : []; - } - } - }, - - legendCallback: function(chart) { - var text = []; - text.push('
    '); - for (var i = 0; i < chart.data.datasets.length; i++) { - text.push('
  • '); - if (chart.data.datasets[i].label) { - text.push(chart.data.datasets[i].label); - } - text.push('
  • '); - } - text.push('
'); - return text.join(''); - } -}); - -/** - * Helper function to get the box width based on the usePointStyle option - * @param {object} labelopts - the label options on the legend - * @param {number} fontSize - the label font size - * @return {number} width of the color box area - */ -function getBoxWidth(labelOpts, fontSize) { - return labelOpts.usePointStyle && labelOpts.boxWidth > fontSize ? - fontSize : - labelOpts.boxWidth; -} - -/** - * IMPORTANT: this class is exposed publicly as Chart.Legend, backward compatibility required! - */ -var Legend = core_element.extend({ - - initialize: function(config) { - helpers$1.extend(this, config); - - // Contains hit boxes for each dataset (in dataset order) - this.legendHitBoxes = []; - - /** - * @private - */ - this._hoveredItem = null; - - // Are we in doughnut mode which has a different data type - this.doughnutMode = false; - }, - - // These methods are ordered by lifecycle. Utilities then follow. - // Any function defined here is inherited by all legend types. - // Any function can be extended by the legend type - - beforeUpdate: noop$1, - update: function(maxWidth, maxHeight, margins) { - var me = this; - - // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;) - me.beforeUpdate(); - - // Absorb the master measurements - me.maxWidth = maxWidth; - me.maxHeight = maxHeight; - me.margins = margins; - - // Dimensions - me.beforeSetDimensions(); - me.setDimensions(); - me.afterSetDimensions(); - // Labels - me.beforeBuildLabels(); - me.buildLabels(); - me.afterBuildLabels(); - - // Fit - me.beforeFit(); - me.fit(); - me.afterFit(); - // - me.afterUpdate(); - - return me.minSize; - }, - afterUpdate: noop$1, - - // - - beforeSetDimensions: noop$1, - setDimensions: function() { - var me = this; - // Set the unconstrained dimension before label rotation - if (me.isHorizontal()) { - // Reset position before calculating rotation - me.width = me.maxWidth; - me.left = 0; - me.right = me.width; - } else { - me.height = me.maxHeight; - - // Reset position before calculating rotation - me.top = 0; - me.bottom = me.height; - } - - // Reset padding - me.paddingLeft = 0; - me.paddingTop = 0; - me.paddingRight = 0; - me.paddingBottom = 0; - - // Reset minSize - me.minSize = { - width: 0, - height: 0 - }; - }, - afterSetDimensions: noop$1, - - // - - beforeBuildLabels: noop$1, - buildLabels: function() { - var me = this; - var labelOpts = me.options.labels || {}; - var legendItems = helpers$1.callback(labelOpts.generateLabels, [me.chart], me) || []; - - if (labelOpts.filter) { - legendItems = legendItems.filter(function(item) { - return labelOpts.filter(item, me.chart.data); - }); - } - - if (me.options.reverse) { - legendItems.reverse(); - } - - me.legendItems = legendItems; - }, - afterBuildLabels: noop$1, - - // - - beforeFit: noop$1, - fit: function() { - var me = this; - var opts = me.options; - var labelOpts = opts.labels; - var display = opts.display; - - var ctx = me.ctx; - - var labelFont = helpers$1.options._parseFont(labelOpts); - var fontSize = labelFont.size; - - // Reset hit boxes - var hitboxes = me.legendHitBoxes = []; - - var minSize = me.minSize; - var isHorizontal = me.isHorizontal(); - - if (isHorizontal) { - minSize.width = me.maxWidth; // fill all the width - minSize.height = display ? 10 : 0; - } else { - minSize.width = display ? 10 : 0; - minSize.height = me.maxHeight; // fill all the height - } - - // Increase sizes here - if (display) { - ctx.font = labelFont.string; - - if (isHorizontal) { - // Labels - - // Width of each line of legend boxes. Labels wrap onto multiple lines when there are too many to fit on one - var lineWidths = me.lineWidths = [0]; - var totalHeight = 0; - - ctx.textAlign = 'left'; - ctx.textBaseline = 'top'; - - helpers$1.each(me.legendItems, function(legendItem, i) { - var boxWidth = getBoxWidth(labelOpts, fontSize); - var width = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width; - - if (i === 0 || lineWidths[lineWidths.length - 1] + width + labelOpts.padding > minSize.width) { - totalHeight += fontSize + labelOpts.padding; - lineWidths[lineWidths.length - (i > 0 ? 0 : 1)] = labelOpts.padding; - } - - // Store the hitbox width and height here. Final position will be updated in `draw` - hitboxes[i] = { - left: 0, - top: 0, - width: width, - height: fontSize - }; - - lineWidths[lineWidths.length - 1] += width + labelOpts.padding; - }); - - minSize.height += totalHeight; - - } else { - var vPadding = labelOpts.padding; - var columnWidths = me.columnWidths = []; - var totalWidth = labelOpts.padding; - var currentColWidth = 0; - var currentColHeight = 0; - var itemHeight = fontSize + vPadding; - - helpers$1.each(me.legendItems, function(legendItem, i) { - var boxWidth = getBoxWidth(labelOpts, fontSize); - var itemWidth = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width; - - // If too tall, go to new column - if (i > 0 && currentColHeight + itemHeight > minSize.height - vPadding) { - totalWidth += currentColWidth + labelOpts.padding; - columnWidths.push(currentColWidth); // previous column width - - currentColWidth = 0; - currentColHeight = 0; - } - - // Get max width - currentColWidth = Math.max(currentColWidth, itemWidth); - currentColHeight += itemHeight; - - // Store the hitbox width and height here. Final position will be updated in `draw` - hitboxes[i] = { - left: 0, - top: 0, - width: itemWidth, - height: fontSize - }; - }); - - totalWidth += currentColWidth; - columnWidths.push(currentColWidth); - minSize.width += totalWidth; - } - } - - me.width = minSize.width; - me.height = minSize.height; - }, - afterFit: noop$1, - - // Shared Methods - isHorizontal: function() { - return this.options.position === 'top' || this.options.position === 'bottom'; - }, - - // Actually draw the legend on the canvas - draw: function() { - var me = this; - var opts = me.options; - var labelOpts = opts.labels; - var globalDefaults = core_defaults.global; - var defaultColor = globalDefaults.defaultColor; - var lineDefault = globalDefaults.elements.line; - var legendWidth = me.width; - var lineWidths = me.lineWidths; - - if (opts.display) { - var ctx = me.ctx; - var fontColor = valueOrDefault$d(labelOpts.fontColor, globalDefaults.defaultFontColor); - var labelFont = helpers$1.options._parseFont(labelOpts); - var fontSize = labelFont.size; - var cursor; - - // Canvas setup - ctx.textAlign = 'left'; - ctx.textBaseline = 'middle'; - ctx.lineWidth = 0.5; - ctx.strokeStyle = fontColor; // for strikethrough effect - ctx.fillStyle = fontColor; // render in correct colour - ctx.font = labelFont.string; - - var boxWidth = getBoxWidth(labelOpts, fontSize); - var hitboxes = me.legendHitBoxes; - - // current position - var drawLegendBox = function(x, y, legendItem) { - if (isNaN(boxWidth) || boxWidth <= 0) { - return; - } - - // Set the ctx for the box - ctx.save(); - - var lineWidth = valueOrDefault$d(legendItem.lineWidth, lineDefault.borderWidth); - ctx.fillStyle = valueOrDefault$d(legendItem.fillStyle, defaultColor); - ctx.lineCap = valueOrDefault$d(legendItem.lineCap, lineDefault.borderCapStyle); - ctx.lineDashOffset = valueOrDefault$d(legendItem.lineDashOffset, lineDefault.borderDashOffset); - ctx.lineJoin = valueOrDefault$d(legendItem.lineJoin, lineDefault.borderJoinStyle); - ctx.lineWidth = lineWidth; - ctx.strokeStyle = valueOrDefault$d(legendItem.strokeStyle, defaultColor); - - if (ctx.setLineDash) { - // IE 9 and 10 do not support line dash - ctx.setLineDash(valueOrDefault$d(legendItem.lineDash, lineDefault.borderDash)); - } - - if (opts.labels && opts.labels.usePointStyle) { - // Recalculate x and y for drawPoint() because its expecting - // x and y to be center of figure (instead of top left) - var radius = boxWidth * Math.SQRT2 / 2; - var centerX = x + boxWidth / 2; - var centerY = y + fontSize / 2; - - // Draw pointStyle as legend symbol - helpers$1.canvas.drawPoint(ctx, legendItem.pointStyle, radius, centerX, centerY); - } else { - // Draw box as legend symbol - if (lineWidth !== 0) { - ctx.strokeRect(x, y, boxWidth, fontSize); - } - ctx.fillRect(x, y, boxWidth, fontSize); - } - - ctx.restore(); - }; - var fillText = function(x, y, legendItem, textWidth) { - var halfFontSize = fontSize / 2; - var xLeft = boxWidth + halfFontSize + x; - var yMiddle = y + halfFontSize; - - ctx.fillText(legendItem.text, xLeft, yMiddle); - - if (legendItem.hidden) { - // Strikethrough the text if hidden - ctx.beginPath(); - ctx.lineWidth = 2; - ctx.moveTo(xLeft, yMiddle); - ctx.lineTo(xLeft + textWidth, yMiddle); - ctx.stroke(); - } - }; - - // Horizontal - var isHorizontal = me.isHorizontal(); - if (isHorizontal) { - cursor = { - x: me.left + ((legendWidth - lineWidths[0]) / 2) + labelOpts.padding, - y: me.top + labelOpts.padding, - line: 0 - }; - } else { - cursor = { - x: me.left + labelOpts.padding, - y: me.top + labelOpts.padding, - line: 0 - }; - } - - var itemHeight = fontSize + labelOpts.padding; - helpers$1.each(me.legendItems, function(legendItem, i) { - var textWidth = ctx.measureText(legendItem.text).width; - var width = boxWidth + (fontSize / 2) + textWidth; - var x = cursor.x; - var y = cursor.y; - - // Use (me.left + me.minSize.width) and (me.top + me.minSize.height) - // instead of me.right and me.bottom because me.width and me.height - // may have been changed since me.minSize was calculated - if (isHorizontal) { - if (i > 0 && x + width + labelOpts.padding > me.left + me.minSize.width) { - y = cursor.y += itemHeight; - cursor.line++; - x = cursor.x = me.left + ((legendWidth - lineWidths[cursor.line]) / 2) + labelOpts.padding; - } - } else if (i > 0 && y + itemHeight > me.top + me.minSize.height) { - x = cursor.x = x + me.columnWidths[cursor.line] + labelOpts.padding; - y = cursor.y = me.top + labelOpts.padding; - cursor.line++; - } - - drawLegendBox(x, y, legendItem); - - hitboxes[i].left = x; - hitboxes[i].top = y; - - // Fill the actual label - fillText(x, y, legendItem, textWidth); - - if (isHorizontal) { - cursor.x += width + labelOpts.padding; - } else { - cursor.y += itemHeight; - } - - }); - } - }, - - /** - * @private - */ - _getLegendItemAt: function(x, y) { - var me = this; - var i, hitBox, lh; - - if (x >= me.left && x <= me.right && y >= me.top && y <= me.bottom) { - // See if we are touching one of the dataset boxes - lh = me.legendHitBoxes; - for (i = 0; i < lh.length; ++i) { - hitBox = lh[i]; - - if (x >= hitBox.left && x <= hitBox.left + hitBox.width && y >= hitBox.top && y <= hitBox.top + hitBox.height) { - // Touching an element - return me.legendItems[i]; - } - } - } - - return null; - }, - - /** - * Handle an event - * @private - * @param {IEvent} event - The event to handle - */ - handleEvent: function(e) { - var me = this; - var opts = me.options; - var type = e.type === 'mouseup' ? 'click' : e.type; - var hoveredItem; - - if (type === 'mousemove') { - if (!opts.onHover && !opts.onLeave) { - return; - } - } else if (type === 'click') { - if (!opts.onClick) { - return; - } - } else { - return; - } - - // Chart event already has relative position in it - hoveredItem = me._getLegendItemAt(e.x, e.y); - - if (type === 'click') { - if (hoveredItem && opts.onClick) { - // use e.native for backwards compatibility - opts.onClick.call(me, e.native, hoveredItem); - } - } else { - if (opts.onLeave && hoveredItem !== me._hoveredItem) { - if (me._hoveredItem) { - opts.onLeave.call(me, e.native, me._hoveredItem); - } - me._hoveredItem = hoveredItem; - } - - if (opts.onHover && hoveredItem) { - // use e.native for backwards compatibility - opts.onHover.call(me, e.native, hoveredItem); - } - } - } -}); - -function createNewLegendAndAttach(chart, legendOpts) { - var legend = new Legend({ - ctx: chart.ctx, - options: legendOpts, - chart: chart - }); - - core_layouts.configure(chart, legend, legendOpts); - core_layouts.addBox(chart, legend); - chart.legend = legend; -} - -var plugin_legend = { - id: 'legend', - - /** - * Backward compatibility: since 2.1.5, the legend is registered as a plugin, making - * Chart.Legend obsolete. To avoid a breaking change, we export the Legend as part of - * the plugin, which one will be re-exposed in the chart.js file. - * https://github.com/chartjs/Chart.js/pull/2640 - * @private - */ - _element: Legend, - - beforeInit: function(chart) { - var legendOpts = chart.options.legend; - - if (legendOpts) { - createNewLegendAndAttach(chart, legendOpts); - } - }, - - beforeUpdate: function(chart) { - var legendOpts = chart.options.legend; - var legend = chart.legend; - - if (legendOpts) { - helpers$1.mergeIf(legendOpts, core_defaults.global.legend); - - if (legend) { - core_layouts.configure(chart, legend, legendOpts); - legend.options = legendOpts; - } else { - createNewLegendAndAttach(chart, legendOpts); - } - } else if (legend) { - core_layouts.removeBox(chart, legend); - delete chart.legend; - } - }, - - afterEvent: function(chart, e) { - var legend = chart.legend; - if (legend) { - legend.handleEvent(e); - } - } -}; - -var noop$2 = helpers$1.noop; - -core_defaults._set('global', { - title: { - display: false, - fontStyle: 'bold', - fullWidth: true, - padding: 10, - position: 'top', - text: '', - weight: 2000 // by default greater than legend (1000) to be above - } -}); - -/** - * IMPORTANT: this class is exposed publicly as Chart.Legend, backward compatibility required! - */ -var Title = core_element.extend({ - initialize: function(config) { - var me = this; - helpers$1.extend(me, config); - - // Contains hit boxes for each dataset (in dataset order) - me.legendHitBoxes = []; - }, - - // These methods are ordered by lifecycle. Utilities then follow. - - beforeUpdate: noop$2, - update: function(maxWidth, maxHeight, margins) { - var me = this; - - // Update Lifecycle - Probably don't want to ever extend or overwrite this function ;) - me.beforeUpdate(); - - // Absorb the master measurements - me.maxWidth = maxWidth; - me.maxHeight = maxHeight; - me.margins = margins; - - // Dimensions - me.beforeSetDimensions(); - me.setDimensions(); - me.afterSetDimensions(); - // Labels - me.beforeBuildLabels(); - me.buildLabels(); - me.afterBuildLabels(); - - // Fit - me.beforeFit(); - me.fit(); - me.afterFit(); - // - me.afterUpdate(); - - return me.minSize; - - }, - afterUpdate: noop$2, - - // - - beforeSetDimensions: noop$2, - setDimensions: function() { - var me = this; - // Set the unconstrained dimension before label rotation - if (me.isHorizontal()) { - // Reset position before calculating rotation - me.width = me.maxWidth; - me.left = 0; - me.right = me.width; - } else { - me.height = me.maxHeight; - - // Reset position before calculating rotation - me.top = 0; - me.bottom = me.height; - } - - // Reset padding - me.paddingLeft = 0; - me.paddingTop = 0; - me.paddingRight = 0; - me.paddingBottom = 0; - - // Reset minSize - me.minSize = { - width: 0, - height: 0 - }; - }, - afterSetDimensions: noop$2, - - // - - beforeBuildLabels: noop$2, - buildLabels: noop$2, - afterBuildLabels: noop$2, - - // - - beforeFit: noop$2, - fit: function() { - var me = this; - var opts = me.options; - var display = opts.display; - var minSize = me.minSize; - var lineCount = helpers$1.isArray(opts.text) ? opts.text.length : 1; - var fontOpts = helpers$1.options._parseFont(opts); - var textSize = display ? (lineCount * fontOpts.lineHeight) + (opts.padding * 2) : 0; - - if (me.isHorizontal()) { - minSize.width = me.maxWidth; // fill all the width - minSize.height = textSize; - } else { - minSize.width = textSize; - minSize.height = me.maxHeight; // fill all the height - } - - me.width = minSize.width; - me.height = minSize.height; - - }, - afterFit: noop$2, - - // Shared Methods - isHorizontal: function() { - var pos = this.options.position; - return pos === 'top' || pos === 'bottom'; - }, - - // Actually draw the title block on the canvas - draw: function() { - var me = this; - var ctx = me.ctx; - var opts = me.options; - - if (opts.display) { - var fontOpts = helpers$1.options._parseFont(opts); - var lineHeight = fontOpts.lineHeight; - var offset = lineHeight / 2 + opts.padding; - var rotation = 0; - var top = me.top; - var left = me.left; - var bottom = me.bottom; - var right = me.right; - var maxWidth, titleX, titleY; - - ctx.fillStyle = helpers$1.valueOrDefault(opts.fontColor, core_defaults.global.defaultFontColor); // render in correct colour - ctx.font = fontOpts.string; - - // Horizontal - if (me.isHorizontal()) { - titleX = left + ((right - left) / 2); // midpoint of the width - titleY = top + offset; - maxWidth = right - left; - } else { - titleX = opts.position === 'left' ? left + offset : right - offset; - titleY = top + ((bottom - top) / 2); - maxWidth = bottom - top; - rotation = Math.PI * (opts.position === 'left' ? -0.5 : 0.5); - } - - ctx.save(); - ctx.translate(titleX, titleY); - ctx.rotate(rotation); - ctx.textAlign = 'center'; - ctx.textBaseline = 'middle'; - - var text = opts.text; - if (helpers$1.isArray(text)) { - var y = 0; - for (var i = 0; i < text.length; ++i) { - ctx.fillText(text[i], 0, y, maxWidth); - y += lineHeight; - } - } else { - ctx.fillText(text, 0, 0, maxWidth); - } - - ctx.restore(); - } - } -}); - -function createNewTitleBlockAndAttach(chart, titleOpts) { - var title = new Title({ - ctx: chart.ctx, - options: titleOpts, - chart: chart - }); - - core_layouts.configure(chart, title, titleOpts); - core_layouts.addBox(chart, title); - chart.titleBlock = title; -} - -var plugin_title = { - id: 'title', - - /** - * Backward compatibility: since 2.1.5, the title is registered as a plugin, making - * Chart.Title obsolete. To avoid a breaking change, we export the Title as part of - * the plugin, which one will be re-exposed in the chart.js file. - * https://github.com/chartjs/Chart.js/pull/2640 - * @private - */ - _element: Title, - - beforeInit: function(chart) { - var titleOpts = chart.options.title; - - if (titleOpts) { - createNewTitleBlockAndAttach(chart, titleOpts); - } - }, - - beforeUpdate: function(chart) { - var titleOpts = chart.options.title; - var titleBlock = chart.titleBlock; - - if (titleOpts) { - helpers$1.mergeIf(titleOpts, core_defaults.global.title); - - if (titleBlock) { - core_layouts.configure(chart, titleBlock, titleOpts); - titleBlock.options = titleOpts; - } else { - createNewTitleBlockAndAttach(chart, titleOpts); - } - } else if (titleBlock) { - core_layouts.removeBox(chart, titleBlock); - delete chart.titleBlock; - } - } -}; - -var plugins = {}; -var filler = plugin_filler; -var legend = plugin_legend; -var title = plugin_title; -plugins.filler = filler; -plugins.legend = legend; -plugins.title = title; - -/** - * @namespace Chart - */ - - -core_controller.helpers = helpers$1; - -// @todo dispatch these helpers into appropriated helpers/helpers.* file and write unit tests! -core_helpers(core_controller); - -core_controller._adapters = core_adapters; -core_controller.Animation = core_animation; -core_controller.animationService = core_animations; -core_controller.controllers = controllers; -core_controller.DatasetController = core_datasetController; -core_controller.defaults = core_defaults; -core_controller.Element = core_element; -core_controller.elements = elements; -core_controller.Interaction = core_interaction; -core_controller.layouts = core_layouts; -core_controller.platform = platform; -core_controller.plugins = core_plugins; -core_controller.Scale = core_scale; -core_controller.scaleService = core_scaleService; -core_controller.Ticks = core_ticks; -core_controller.Tooltip = core_tooltip; - -// Register built-in scales - -core_controller.helpers.each(scales, function(scale, type) { - core_controller.scaleService.registerScaleType(type, scale, scale._defaults); -}); - -// Load to register built-in adapters (as side effects) - - -// Loading built-in plugins - -for (var k in plugins) { - if (plugins.hasOwnProperty(k)) { - core_controller.plugins.register(plugins[k]); - } -} - -core_controller.platform.initialize(); - -var src = core_controller; -if (typeof window !== 'undefined') { - window.Chart = core_controller; -} - -// DEPRECATIONS - -/** - * Provided for backward compatibility, not available anymore - * @namespace Chart.Chart - * @deprecated since version 2.8.0 - * @todo remove at version 3 - * @private - */ -core_controller.Chart = core_controller; - -/** - * Provided for backward compatibility, not available anymore - * @namespace Chart.Legend - * @deprecated since version 2.1.5 - * @todo remove at version 3 - * @private - */ -core_controller.Legend = plugins.legend._element; - -/** - * Provided for backward compatibility, not available anymore - * @namespace Chart.Title - * @deprecated since version 2.1.5 - * @todo remove at version 3 - * @private - */ -core_controller.Title = plugins.title._element; - -/** - * Provided for backward compatibility, use Chart.plugins instead - * @namespace Chart.pluginService - * @deprecated since version 2.1.5 - * @todo remove at version 3 - * @private - */ -core_controller.pluginService = core_controller.plugins; - -/** - * Provided for backward compatibility, inheriting from Chart.PlugingBase has no - * effect, instead simply create/register plugins via plain JavaScript objects. - * @interface Chart.PluginBase - * @deprecated since version 2.5.0 - * @todo remove at version 3 - * @private - */ -core_controller.PluginBase = core_controller.Element.extend({}); - -/** - * Provided for backward compatibility, use Chart.helpers.canvas instead. - * @namespace Chart.canvasHelpers - * @deprecated since version 2.6.0 - * @todo remove at version 3 - * @private - */ -core_controller.canvasHelpers = core_controller.helpers.canvas; - -/** - * Provided for backward compatibility, use Chart.layouts instead. - * @namespace Chart.layoutService - * @deprecated since version 2.7.3 - * @todo remove at version 3 - * @private - */ -core_controller.layoutService = core_controller.layouts; - -/** - * Provided for backward compatibility, not available anymore. - * @namespace Chart.LinearScaleBase - * @deprecated since version 2.8 - * @todo remove at version 3 - * @private - */ -core_controller.LinearScaleBase = scale_linearbase; - -/** - * Provided for backward compatibility, instead we should create a new Chart - * by setting the type in the config (`new Chart(id, {type: '{chart-type}'}`). - * @deprecated since version 2.8.0 - * @todo remove at version 3 - */ -core_controller.helpers.each( - [ - 'Bar', - 'Bubble', - 'Doughnut', - 'Line', - 'PolarArea', - 'Radar', - 'Scatter' - ], - function(klass) { - core_controller[klass] = function(ctx, cfg) { - return new core_controller(ctx, core_controller.helpers.merge(cfg || {}, { - type: klass.charAt(0).toLowerCase() + klass.slice(1) - })); - }; - } -); - -return src; - -}))); \ No newline at end of file diff --git a/thirdparty/applait.finder.min.js b/thirdparty/applait.finder.min.js index 7ca9cae..bba305e 100644 --- a/thirdparty/applait.finder.min.js +++ b/thirdparty/applait.finder.min.js @@ -4,7 +4,7 @@ * MIT license * @preserve */ -(function(){"use strict";function EventEmitter(){}function indexOfListener(listeners,listener){for(var i=listeners.length;i--;)if(listeners[i].listener===listener)return i;return-1}function alias(name){return function(){return this[name].apply(this,arguments)}}var proto=EventEmitter.prototype,exports=this,originalGlobalValue=exports.EventEmitter;proto.getListeners=function(evt){var response,key,events=this._getEvents();if(evt instanceof RegExp){response={};for(key in events)events.hasOwnProperty(key)&&evt.test(key)&&(response[key]=events[key])}else response=events[evt]||(events[evt]=[]);return response},proto.flattenListeners=function(listeners){var i,flatListeners=[];for(i=0;i-1&&this.checkhidden(fullpath)}; +const Applait = Applait || {}; +Applait.Finder = function (options) { this.options = options || {}, this.type = this.options.type || "sdcard", this.hidden = this.options.hidden || !1, this.casesensitive = this.options.caseSensitive || !1, this.minsearchlength = this.options.minSearchLength && "number" == typeof this.options.minSearchLength ? options.minSearchLength : 3, this.debugmode = this.options.debugMode ? !0 : !1, this.storages = navigator.getDeviceStorages && navigator.getDeviceStorages(this.type), this.searchcompletecount = 0, this.filematchcount = 0, this.searchkey = "" }, +Applait.Finder.prototype = new EventEmitter +Applait.Finder.prototype.checkhidden = function (fullpath) { return "/" === fullpath[fullpath.indexOf(".") - 1] && this.hidden !== !0 ? !1 : !0 } +Applait.Finder.prototype.search = function (needle) { var self = this; return self.reset(), self.searchkey = self.casesensitive ? needle.trim() : needle.trim().toLowerCase(), self.searchkey.length < self.minsearchlength ? (self.log("searchCancelled", ["Search string should be at least " + self.minsearchlength + " characters"]), self.emitEvent("searchCancelled", ["Search string should be at least " + self.minsearchlength + " characters"]), null) : self.storagecount() < 1 ? (self.log("empty", [self.searchkey]), self.emitEvent("empty", [self.searchkey]), null) : (self.log("searchBegin", [self.searchkey]), self.emitEvent("searchBegin", [self.searchkey]), void self.storages.forEach(function (storage) { var cursor = storage.enumerate(); self.log("storageSearchBegin", [storage.storageName, self.searchkey]), self.emitEvent("storageSearchBegin", [storage.storageName, self.searchkey]), cursor.onsuccess = function () { if (this.result) { var file = this.result, fileinfo = self.splitname(file.name); self.matchname(fileinfo.name, file.name) && (self.filematchcount++ , self.log("fileFound", [file, fileinfo, storage.storageName]), self.emitEvent("fileFound", [file, fileinfo, storage.storageName])), this.done ? (self.searchcompletecount++ , self.log("storageSearchComplete", [storage.storageName, self.searchkey]), self.emitEvent("storageSearchComplete", [storage.storageName, self.searchkey])) : this.continue() } else self.searchcompletecount++ , self.log("storageSearchComplete", [storage.storageName, self.searchkey]), self.emitEvent("storageSearchComplete", [storage.storageName, self.searchkey]); self.searchcompletecount === self.storagecount() && (self.log("searchComplete", [self.searchkey, self.filematchcount]), self.emitEvent("searchComplete", [self.searchkey, self.filematchcount])) }, cursor.onerror = function () { self.log("error", ["Error accessing device storage '" + storage.storageName + "'", this.error]), self.emitEvent("error", ["Error accessing device storage '" + storage.storageName + "'", this.error]) } })) } +Applait.Finder.prototype.splitname = function (filename) { return filename = filename.split(/[\\/]/), { name: filename.pop(), path: filename.join("/") } } +Applait.Finder.prototype.storagecount = function () { return this.storages && this.storages.length ? this.storages.length : 0 } +Applait.Finder.prototype.reset = function () { this.filematchcount = 0, this.searchcompletecount = 0, this.searchkey = "" } +Applait.Finder.prototype.log = function (message, args) { this.debugmode && console.log(message, args) } +Applait.Finder.prototype.matchname = function (name, fullpath) { return name = this.casesensitive ? name.trim() : name.trim().toLowerCase(), name.indexOf(this.searchkey) > -1 && this.checkhidden(fullpath) }; + +export default Applait \ No newline at end of file diff --git a/thirdparty/client.min.js b/thirdparty/client.min.js deleted file mode 100755 index 38fb520..0000000 --- a/thirdparty/client.min.js +++ /dev/null @@ -1,81 +0,0 @@ -(function(f){var d,e,p=function(){d=(new (window.UAParser||exports.UAParser)).getResult();e=new Detector;return this};p.prototype={getSoftwareVersion:function(){return"0.1.11"},getBrowserData:function(){return d},getFingerprint:function(){var b=d.ua,c=this.getScreenPrint(),a=this.getPlugins(),g=this.getFonts(),n=this.isLocalStorage(),f=this.isSessionStorage(),h=this.getTimeZone(),u=this.getLanguage(),m=this.getSystemLanguage(),e=this.isCookie(),C=this.getCanvasPrint();return murmurhash3_32_gc(b+"|"+ -c+"|"+a+"|"+g+"|"+n+"|"+f+"|"+h+"|"+u+"|"+m+"|"+e+"|"+C,256)},getCustomFingerprint:function(){for(var b="",c=0;c 1.0",2,15);c.fillStyle="rgba(102, 204, 0, 0.7)";c.fillText("ClientJS,org 1.0",4,17);return b.toDataURL()}};"object"=== -typeof module&&"undefined"!==typeof exports&&(module.exports=p);f.ClientJS=p})(window);var deployJava=function(){function f(a){c.debug&&(console.log?console.log(a):alert(a))}function d(a){if(null==a||0==a.length)return"http://java.com/dt-redirect";"&"==a.charAt(0)&&(a=a.substring(1,a.length));return"http://java.com/dt-redirect?"+a}var e=["id","class","title","style"];"classid codebase codetype data type archive declare standby height width usemap name tabindex align border hspace vspace".split(" ").concat(e,["lang","dir"],"onclick ondblclick onmousedown onmouseup onmouseover onmousemove onmouseout onkeypress onkeydown onkeyup".split(" ")); -var p="codebase code name archive object width height alt align hspace vspace".split(" ").concat(e),b;try{b=-1!=document.location.protocol.indexOf("http")?"//java.com/js/webstart.png":"http://java.com/js/webstart.png"}catch(a){b="http://java.com/js/webstart.png"}var c={debug:null,version:"20120801",firefoxJavaVersion:null,myInterval:null,preInstallJREList:null,returnPage:null,brand:null,locale:null,installType:null,EAInstallEnabled:!1,EarlyAccessURL:null,oldMimeType:"application/npruntime-scriptable-plugin;DeploymentToolkit", -mimeType:"application/java-deployment-toolkit",launchButtonPNG:b,browserName:null,browserName2:null,getJREs:function(){var a=[];if(this.isPluginInstalled())for(var g=this.getPlugin().jvms,b=0;b'}d||(c+='');h&&(b+=' code="dummy"');document.write(b+">\n"+c+"\n")},versionCheck:function(a){var g=0,b=a.match("^(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)(?:_(\\d+))?)?)?(\\*|\\+)?$");if(null!=b){for(var c=a=!1,h=[],d=1;dh.length&&(c=!1,a=!0);g=this.getJREs();for(d=0;d':"Netscape Family"==c&&(d='');"undefined"==document.body||null==document.body? -(document.write(d),document.location=b):(a=document.createElement("div"),a.id="div1",a.style.position="relative",a.style.left="-10000px",a.style.margin="0px auto",a.className="dynamicDiv",a.innerHTML=d,document.body.appendChild(a))},createWebStartLaunchButtonEx:function(a,b){null==this.returnPage&&(this.returnPage=a);document.write('')}, -createWebStartLaunchButton:function(a,b){null==this.returnPage&&(this.returnPage=a);document.write('')},launch:function(a){document.location=a;return!0},isPluginInstalled:function(){var a= -this.getPlugin();return a&&a.jvms?!0:!1},isAutoUpdateEnabled:function(){return this.isPluginInstalled()?this.getPlugin().isAutoUpdateEnabled():!1},setAutoUpdateEnabled:function(){return this.isPluginInstalled()?this.getPlugin().setAutoUpdateEnabled():!1},setInstallerType:function(a){this.installType=a;return this.isPluginInstalled()?this.getPlugin().setInstallerType(a):!1},setAdditionalPackages:function(a){return this.isPluginInstalled()?this.getPlugin().setAdditionalPackages(a):!1},setEarlyAccess:function(a){this.EAInstallEnabled= -a},isPlugin2:function(){if(this.isPluginInstalled()&&this.versionCheck("1.6.0_10+"))try{return this.getPlugin().isPlugin2()}catch(a){}return!1},allowPlugin:function(){this.getBrowser();return"Safari"!=this.browserName2&&"Opera"!=this.browserName2},getPlugin:function(){this.refresh();var a=null;this.allowPlugin()&&(a=document.getElementById("deployJavaPlugin"));return a},compareVersionToPattern:function(a,b,c,d){if(void 0==a||void 0==b)return!1;var h=a.match("^(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)(?:_(\\d+))?)?)?$"); -if(null!=h){var f=0;a=[];for(var m=1;mb[m])break}return!0}for(m=0;m "+a);-1!=a.indexOf("msie")&&-1==a.indexOf("opera")?this.browserName2=this.browserName= -"MSIE":-1!=a.indexOf("iphone")?(this.browserName="Netscape Family",this.browserName2="iPhone"):-1!=a.indexOf("firefox")&&-1==a.indexOf("opera")?(this.browserName="Netscape Family",this.browserName2="Firefox"):-1!=a.indexOf("chrome")?(this.browserName="Netscape Family",this.browserName2="Chrome"):-1!=a.indexOf("safari")?(this.browserName="Netscape Family",this.browserName2="Safari"):-1!=a.indexOf("mozilla")&&-1==a.indexOf("opera")?(this.browserName="Netscape Family",this.browserName2="Other"):-1!= -a.indexOf("opera")?(this.browserName="Netscape Family",this.browserName2="Opera"):(this.browserName="?",this.browserName2="unknown");f("[getBrowser()] Detected browser name:"+this.browserName+", "+this.browserName2)}return this.browserName},testUsingActiveX:function(a){a="JavaWebStart.isInstalled."+a+".0";if("undefined"==typeof ActiveXObject||!ActiveXObject)return f("[testUsingActiveX()] Browser claims to be IE, but no ActiveXObject object?"),!1;try{return null!=new ActiveXObject(a)}catch(b){return!1}}, -testForMSVM:function(){if("undefined"!=typeof oClientCaps){var a=oClientCaps.getComponentVersion("{08B0E5C0-4FCB-11CF-AAA5-00401C608500}","ComponentID");return""==a||"5,0,5000,0"==a?!1:!0}return!1},testUsingMimeTypes:function(a){if(!navigator.mimeTypes)return f("[testUsingMimeTypes()] Browser claims to be Netscape family, but no mimeTypes[] array?"),!1;for(var b=0;bd[0]?!0:c[0]d[1]?!0:c[1]d[2]?!0:c[2]'):"Netscape Family"==a&&this.allowPlugin()&&this.writeEmbedTag()},refresh:function(){navigator.plugins.refresh(!1);"Netscape Family"==this.getBrowser()&&this.allowPlugin()&&null== -document.getElementById("deployJavaPlugin")&&this.writeEmbedTag()},writeEmbedTag:function(){var a=!1;if(null!=navigator.mimeTypes){for(var b=0;b