From d90a6a25bd94d374199e0f0993ee00736f30c96a Mon Sep 17 00:00:00 2001 From: Gabriel Dutra Date: Mon, 6 Apr 2020 17:29:16 -0300 Subject: [PATCH 1/6] Basic visualizations project setup --- package-lock.json | 2868 ++++++++++++++++++++++++++++ package.json | 1 + redash-visualizations/.babelrc | 15 + redash-visualizations/.gitignore | 20 + redash-visualizations/package.json | 38 + 5 files changed, 2942 insertions(+) create mode 100644 redash-visualizations/.babelrc create mode 100644 redash-visualizations/.gitignore create mode 100644 redash-visualizations/package.json diff --git a/package-lock.json b/package-lock.json index d9721873df..e5e0624f6a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13933,6 +13933,2874 @@ "util.promisify": "^1.0.0" } }, + "redash-visualizations": { + "version": "file:redash-visualizations", + "requires": { + "chroma-js": "^2.1.0", + "numeral": "^2.0.6" + }, + "dependencies": { + "@babel/cli": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.8.4.tgz", + "integrity": "sha512-XXLgAm6LBbaNxaGhMAznXXaxtCWfuv6PIDJ9Alsy9JYTOh+j2jJz+L/162kkfU1j/pTSxK1xGmlwI4pdIMkoag==", + "requires": { + "chokidar": "^2.1.8", + "commander": "^4.0.1", + "convert-source-map": "^1.1.0", + "fs-readdir-recursive": "^1.1.0", + "glob": "^7.0.0", + "lodash": "^4.17.13", + "make-dir": "^2.1.0", + "slash": "^2.0.0", + "source-map": "^0.5.0" + } + }, + "@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==", + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/compat-data": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.9.0.tgz", + "integrity": "sha512-zeFQrr+284Ekvd9e7KAX954LkapWiOmQtsfHirhxqfdlX6MEC32iRE+pqUGlYIBchdevaCwvzxWGSy/YBNI85g==", + "requires": { + "browserslist": "^4.9.1", + "invariant": "^2.2.4", + "semver": "^5.5.0" + } + }, + "@babel/core": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", + "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.0", + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helpers": "^7.9.0", + "@babel/parser": "^7.9.0", + "@babel/template": "^7.8.6", + "@babel/traverse": "^7.9.0", + "@babel/types": "^7.9.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "@babel/generator": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.4.tgz", + "integrity": "sha512-rjP8ahaDy/ouhrvCoU1E5mqaitWrxwuNGU+dy1EpaoK48jZay4MdkskKGIMHLZNewg8sAsqpGSREJwP0zH3YQA==", + "requires": { + "@babel/types": "^7.9.0", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@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==", + "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==", + "requires": { + "@babel/helper-explode-assignable-expression": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-builder-react-jsx": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.9.0.tgz", + "integrity": "sha512-weiIo4gaoGgnhff54GQ3P5wsUQmnSwpkvU0r6ZHq6TzoSzKy4JxHEgnxNytaKbov2a9z/CVNyzliuCOUPEX3Jw==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/types": "^7.9.0" + } + }, + "@babel/helper-builder-react-jsx-experimental": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.9.0.tgz", + "integrity": "sha512-3xJEiyuYU4Q/Ar9BsHisgdxZsRlsShMe90URZ0e6przL26CCs8NJbDoxH94kKT17PcxlMhsCAwZd90evCo26VQ==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-module-imports": "^7.8.3", + "@babel/types": "^7.9.0" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.7.tgz", + "integrity": "sha512-4mWm8DCK2LugIS+p1yArqvG1Pf162upsIsjE7cNBjez+NjliQpVhj20obE520nao0o14DaTnFJv+Fw5a0JpoUw==", + "requires": { + "@babel/compat-data": "^7.8.6", + "browserslist": "^4.9.1", + "invariant": "^2.2.4", + "levenary": "^1.1.1", + "semver": "^5.5.0" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.8.6.tgz", + "integrity": "sha512-klTBDdsr+VFFqaDHm5rR69OpEQtO2Qv8ECxHS1mNhJJvaHArR6a1xTf5K/eZW7eZpJbhCx3NW1Yt/sKsLXLblg==", + "requires": { + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-member-expression-to-functions": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.6", + "@babel/helper-split-export-declaration": "^7.8.3" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.8.8", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.8.tgz", + "integrity": "sha512-LYVPdwkrQEiX9+1R29Ld/wTrmQu1SSKYnuOk3g0CkcZMA1p0gsNxJFj/3gBdaJ7Cg0Fnek5z0DsMULePP7Lrqg==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-regex": "^7.8.3", + "regexpu-core": "^4.7.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==", + "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==", + "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==", + "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==", + "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==", + "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==", + "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==", + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-module-transforms": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz", + "integrity": "sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==", + "requires": { + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.6", + "@babel/helper-simple-access": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/template": "^7.8.6", + "@babel/types": "^7.9.0", + "lodash": "^4.17.13" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", + "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", + "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==" + }, + "@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==", + "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==", + "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.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz", + "integrity": "sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA==", + "requires": { + "@babel/helper-member-expression-to-functions": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/traverse": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/helper-simple-access": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", + "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", + "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==", + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz", + "integrity": "sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw==" + }, + "@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==", + "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.9.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.2.tgz", + "integrity": "sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA==", + "requires": { + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.9.0", + "@babel/types": "^7.9.0" + } + }, + "@babel/highlight": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", + "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", + "requires": { + "@babel/helper-validator-identifier": "^7.9.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz", + "integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==" + }, + "@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==", + "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-class-properties": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.8.3.tgz", + "integrity": "sha512-EqFhbo7IosdgPgZggHaNObkmO1kNUe3slaKu54d5OWvy+p9QIKOzK1GAEpAIsZtWVtPXUHSMcT4smvDrCfY4AA==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@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==", + "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==", + "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==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" + } + }, + "@babel/plugin-proposal-numeric-separator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.8.3.tgz", + "integrity": "sha512-jWioO1s6R/R+wEHizfaScNsAx+xKgwTLNXSh7tTC4Usj3ItsPEhYkEpU4h+lpnBwq7NBVOJXfO6cRFYcX69JUQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.0.tgz", + "integrity": "sha512-UgqBv6bjq4fDb8uku9f+wcm1J7YxJ5nT7WO/jBr0cl0PLKb7t1O6RNR1kZbjgx2LQtsDI9hwoQVmn0yhXeQyow==", + "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==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.9.0.tgz", + "integrity": "sha512-NDn5tu3tcv4W30jNhmc2hyD5c56G6cXx4TesJubhxrJeCvuuMpttxr0OnNCqbZGhFjLrg+NIhxxC+BK5F6yS3w==", + "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.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.8.tgz", + "integrity": "sha512-EVhjVsMpbhLw9ZfHWSx2iy13Q8Z/eg8e8ccVWt23sWQK5l1UdkoLJPN5w69UA4uITGBnEZD2JOe4QOHycYKv8A==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.8", + "@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==", + "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==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@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==", + "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==", + "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==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz", + "integrity": "sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@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==", + "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==", + "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==", + "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==", + "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==", + "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==", + "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==", + "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==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "lodash": "^4.17.13" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.9.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.2.tgz", + "integrity": "sha512-TC2p3bPzsfvSsqBZo0kJnuelnoK9O3welkUpqSqBQuBF6R5MN2rysopri8kNvtlGIb2jmUO7i15IooAZJjZuMQ==", + "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.6", + "@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==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.8.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.8.8.tgz", + "integrity": "sha512-eRJu4Vs2rmttFCdhPUM3bV0Yo/xPSdPw6ML9KHs/bjB4bLA5HXlbvYXPOD5yASodGod+krjYx21xm1QmL8dCJQ==", + "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==", + "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==", + "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==", + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.9.0.tgz", + "integrity": "sha512-lTAnWOpMwOXpyDx06N+ywmF3jNbafZEqZ96CGYabxHrxNX8l5ny7dt4bK/rGwAh9utyP2b2Hv7PlZh1AAS54FQ==", + "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==", + "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==", + "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==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.9.0.tgz", + "integrity": "sha512-vZgDDF003B14O8zJy0XXLnPH4sg+9X5hFBBGN1V+B2rgrB+J2xIypSN6Rk9imB2hSTHQi5OHLrFWsZab1GMk+Q==", + "requires": { + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helper-plugin-utils": "^7.8.3", + "babel-plugin-dynamic-import-node": "^2.3.0" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.0.tgz", + "integrity": "sha512-qzlCrLnKqio4SlgJ6FMMLBe4bySNis8DFn1VkGmOcxG9gqEyPIOzeQrA//u0HAKrWpJlpZbZMPB1n/OPa4+n8g==", + "requires": { + "@babel/helper-module-transforms": "^7.9.0", + "@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.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.9.0.tgz", + "integrity": "sha512-FsiAv/nao/ud2ZWy4wFacoLOm5uxl0ExSQ7ErvP7jpoihLR6Cq90ilOFyX9UXct3rbtKsAiZ9kFt5XGfPe/5SQ==", + "requires": { + "@babel/helper-hoist-variables": "^7.8.3", + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helper-plugin-utils": "^7.8.3", + "babel-plugin-dynamic-import-node": "^2.3.0" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.9.0.tgz", + "integrity": "sha512-uTWkXkIVtg/JGRSIABdBoMsoIeoHQHPTL0Y2E7xf5Oj7sLqwVsNXOkNk0VJc7vF0IMBsPeikHxFjGe+qmwPtTQ==", + "requires": { + "@babel/helper-module-transforms": "^7.9.0", + "@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==", + "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==", + "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==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.3" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.9.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.9.3.tgz", + "integrity": "sha512-fzrQFQhp7mIhOzmOtPiKffvCYQSK10NR8t6BBz2yPbeUHb9OLW8RZGtgDRBn8z2hGcwvKDL3vC7ojPTLNxmqEg==", + "requires": { + "@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==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-react-display-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.8.3.tgz", + "integrity": "sha512-3Jy/PCw8Fe6uBKtEgz3M82ljt+lTg+xJaM4og+eyu83qLT87ZUSckn0wy7r31jflURWLO83TW6Ylf7lyXj3m5A==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-transform-react-jsx": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.9.4.tgz", + "integrity": "sha512-Mjqf3pZBNLt854CK0C/kRuXAnE6H/bo7xYojP+WGtX8glDGSibcwnsWwhwoSuRg0+EBnxPC1ouVnuetUIlPSAw==", + "requires": { + "@babel/helper-builder-react-jsx": "^7.9.0", + "@babel/helper-builder-react-jsx-experimental": "^7.9.0", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-jsx": "^7.8.3" + } + }, + "@babel/plugin-transform-react-jsx-development": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.9.0.tgz", + "integrity": "sha512-tK8hWKrQncVvrhvtOiPpKrQjfNX3DtkNLSX4ObuGcpS9p0QrGetKmlySIGR07y48Zft8WVgPakqd/bk46JrMSw==", + "requires": { + "@babel/helper-builder-react-jsx-experimental": "^7.9.0", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-jsx": "^7.8.3" + } + }, + "@babel/plugin-transform-react-jsx-self": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.9.0.tgz", + "integrity": "sha512-K2ObbWPKT7KUTAoyjCsFilOkEgMvFG+y0FqOl6Lezd0/13kMkkjHskVsZvblRPj1PHA44PrToaZANrryppzTvQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-jsx": "^7.8.3" + } + }, + "@babel/plugin-transform-react-jsx-source": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.9.0.tgz", + "integrity": "sha512-K6m3LlSnTSfRkM6FcRk8saNEeaeyG5k7AVkBU2bZK3+1zdkSED3qNdsWrUgQBeTVD2Tp3VMmerxVO2yM5iITmw==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-jsx": "^7.8.3" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.7.tgz", + "integrity": "sha512-TIg+gAl4Z0a3WmD3mbYSk+J9ZUH6n/Yc57rtKRnlA/7rcCvpekHXe0CMZHP1gYp7/KLe9GHTuIba0vXmls6drA==", + "requires": { + "regenerator-transform": "^0.14.2" + } + }, + "@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==", + "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==", + "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==", + "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==", + "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==", + "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==", + "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==", + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/preset-env": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.9.0.tgz", + "integrity": "sha512-712DeRXT6dyKAM/FMbQTV/FvRCms2hPCx+3weRjZ8iQVQWZejWWk1wwG6ViWMyqb/ouBbGOl5b6aCk0+j1NmsQ==", + "requires": { + "@babel/compat-data": "^7.9.0", + "@babel/helper-compilation-targets": "^7.8.7", + "@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-numeric-separator": "^7.8.3", + "@babel/plugin-proposal-object-rest-spread": "^7.9.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.8.3", + "@babel/plugin-proposal-optional-chaining": "^7.9.0", + "@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-numeric-separator": "^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.9.0", + "@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.9.0", + "@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.9.0", + "@babel/plugin-transform-modules-commonjs": "^7.9.0", + "@babel/plugin-transform-modules-systemjs": "^7.9.0", + "@babel/plugin-transform-modules-umd": "^7.9.0", + "@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.7", + "@babel/plugin-transform-property-literals": "^7.8.3", + "@babel/plugin-transform-regenerator": "^7.8.7", + "@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/preset-modules": "^0.1.3", + "@babel/types": "^7.9.0", + "browserslist": "^4.9.1", + "core-js-compat": "^3.6.2", + "invariant": "^2.2.2", + "levenary": "^1.1.1", + "semver": "^5.5.0" + } + }, + "@babel/preset-modules": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.3.tgz", + "integrity": "sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + } + }, + "@babel/preset-react": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.9.4.tgz", + "integrity": "sha512-AxylVB3FXeOTQXNXyiuAQJSvss62FEotbX2Pzx3K/7c+MKJMdSg6Ose6QYllkdCFA8EInCJVw7M/o5QbLuA4ZQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-transform-react-display-name": "^7.8.3", + "@babel/plugin-transform-react-jsx": "^7.9.4", + "@babel/plugin-transform-react-jsx-development": "^7.9.0", + "@babel/plugin-transform-react-jsx-self": "^7.9.0", + "@babel/plugin-transform-react-jsx-source": "^7.9.0" + } + }, + "@babel/runtime": { + "version": "7.9.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.2.tgz", + "integrity": "sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/traverse": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.0.tgz", + "integrity": "sha512-jAZQj0+kn4WTHO5dUZkZKhbFrqZE7K5LAQ5JysMnmvGij+wOdr+8lWqPeW0BcF4wFwrEXXtdGO7wcV6YPJcf3w==", + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.0", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.9.0", + "@babel/types": "^7.9.0", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "@babel/types": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", + "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", + "requires": { + "@babel/helper-validator-identifier": "^7.9.0", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "optional": 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=", + "optional": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "optional": 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==", + "optional": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "optional": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "optional": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "optional": 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==", + "optional": 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==", + "optional": 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==", + "requires": { + "object.assign": "^4.1.0" + } + }, + "babel-plugin-module-resolver": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-4.0.0.tgz", + "integrity": "sha512-3pdEq3PXALilSJ6dnC4wMWr0AZixHRM4utpdpBR9g5QG7B7JwWyukQv7a9hVxkbGFl+nQbrHDqqQOIBtTXTP/Q==", + "requires": { + "find-babel-config": "^1.2.0", + "glob": "^7.1.6", + "pkg-up": "^3.1.0", + "reselect": "^4.0.0", + "resolve": "^1.13.1" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "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==", + "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==" + }, + "pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "requires": { + "find-up": "^3.0.0" + } + } + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "optional": 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=", + "optional": 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==", + "optional": 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==", + "optional": 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==", + "optional": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "optional": 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==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "optional": 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=", + "optional": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "browserslist": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.11.1.tgz", + "integrity": "sha512-DCTr3kDrKEYNw6Jb9HFxVLQNaue8z+0ZfRBRjmCunKDEXEBajKDj2Y+Uelg+Pi29OnvaSGwjOsnRyNEkXzHg5g==", + "requires": { + "caniuse-lite": "^1.0.30001038", + "electron-to-chromium": "^1.3.390", + "node-releases": "^1.1.53", + "pkg-up": "^2.0.0" + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "optional": 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" + } + }, + "caniuse-lite": { + "version": "1.0.30001039", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001039.tgz", + "integrity": "sha512-SezbWCTT34eyFoWHgx8UWso7YtvtM7oosmFoXbCkdC6qJzRfBTeTgE9REtKtiuKXuMwWTZEvdnFNGAyVMorv8Q==" + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "optional": 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" + } + }, + "chroma-js": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.1.0.tgz", + "integrity": "sha512-uiRdh4ZZy+UTPSrAdp8hqEdVb1EllLtTHOt5TMaOjJUvi+O54/83Fc5K2ld1P+TJX+dw5B+8/sCgzI6eaur/lg==", + "requires": { + "cross-env": "^6.0.3" + } + }, + "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==", + "optional": 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=", + "optional": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "optional": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "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=" + }, + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==" + }, + "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==", + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "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==", + "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=", + "optional": 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==", + "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==" + } + } + }, + "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=", + "optional": true + }, + "cross-env": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-6.0.3.tgz", + "integrity": "sha512-+KqxF6LCvfhWvADcDPqo64yVIB31gv/jQulX2NGzKS/g3GEVz6/pt4wjHFtFWsHMddebWD/sDthJemzM4MaAag==", + "requires": { + "cross-spawn": "^7.0.0" + } + }, + "cross-spawn": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.2.tgz", + "integrity": "sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "optional": 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==", + "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==", + "optional": 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==", + "optional": 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==", + "optional": 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==", + "optional": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "electron-to-chromium": { + "version": "1.3.397", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.397.tgz", + "integrity": "sha512-zcUd1p/7yzTSdWkCTrqGvbnEOASy96d0RJL/lc5BDJoO23Z3G/VHd0yIPbguDU9n8QNUTCigLO7oEdtOb7fp2A==" + }, + "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=" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "optional": 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": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "optional": 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=", + "optional": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "optional": 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==", + "optional": 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==", + "optional": 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=", + "optional": 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=", + "optional": 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==", + "optional": 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==", + "optional": 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==", + "optional": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "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==" + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "optional": 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=", + "optional": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "find-babel-config": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-1.2.0.tgz", + "integrity": "sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA==", + "requires": { + "json5": "^0.5.1", + "path-exists": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=" + } + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "^2.0.0" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "optional": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "optional": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "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==" + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "optional": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "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=", + "optional": 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=", + "optional": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "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==", + "optional": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "optional": 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=", + "optional": 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=", + "optional": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "requires": { + "loose-envify": "^1.0.0" + } + }, + "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=", + "optional": 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=", + "optional": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "optional": 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==", + "optional": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "optional": 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=", + "optional": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "optional": 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==", + "optional": true + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "optional": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "optional": 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==", + "optional": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "optional": 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=", + "optional": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "optional": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "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==", + "optional": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "optional": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "optional": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "requires": { + "minimist": "^1.2.5" + } + }, + "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==", + "optional": true + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" + }, + "levenary": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", + "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==", + "requires": { + "leven": "^3.1.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "requires": { + "p-locate": "^2.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==" + }, + "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==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "optional": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "optional": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "optional": 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" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "optional": 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==", + "optional": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "optional": true + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "optional": 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" + } + }, + "node-releases": { + "version": "1.1.53", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.53.tgz", + "integrity": "sha512-wp8zyQVwef2hpZ/dJH7SfSrIPD6YoJz6BDQDpGEkcA0s3LpAQoxBIYmfIq6QAhC1DhwsyCgTaTTcONwX8qzCuQ==" + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "optional": true + }, + "numeral": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/numeral/-/numeral-2.0.6.tgz", + "integrity": "sha1-StCAk21EPCVhrtnyGX7//iX05QY=" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "optional": 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=", + "optional": 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=", + "optional": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "optional": 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==", + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "optional": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "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=", + "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=" + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "optional": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "optional": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "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==" + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + }, + "pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", + "requires": { + "find-up": "^2.1.0" + } + }, + "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=", + "optional": 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==" + }, + "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==", + "optional": true + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "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==", + "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" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "optional": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==" + }, + "regenerate-unicode-properties": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", + "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==" + }, + "regenerator-transform": { + "version": "0.14.4", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.4.tgz", + "integrity": "sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw==", + "requires": { + "@babel/runtime": "^7.8.4", + "private": "^0.1.8" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "optional": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexpu-core": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.0.tgz", + "integrity": "sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==", + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.2.0", + "regjsgen": "^0.5.1", + "regjsparser": "^0.6.4", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.2.0" + } + }, + "regjsgen": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz", + "integrity": "sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg==" + }, + "regjsparser": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz", + "integrity": "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==", + "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=" + } + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "optional": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "optional": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "optional": true + }, + "reselect": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.0.0.tgz", + "integrity": "sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA==" + }, + "resolve": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "optional": true + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "optional": true + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "optional": true, + "requires": { + "ret": "~0.1.10" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "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==", + "optional": 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=", + "optional": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==" + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "optional": 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": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "optional": 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=", + "optional": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "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==", + "optional": 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=", + "optional": 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==", + "optional": 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==", + "optional": 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==", + "optional": 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==", + "optional": 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=", + "optional": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "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==", + "optional": 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-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "optional": 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==", + "optional": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "optional": 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=", + "optional": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "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=" + }, + "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=", + "optional": 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=", + "optional": 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==", + "optional": 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=", + "optional": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.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==" + }, + "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==", + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", + "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==" + }, + "unicode-property-aliases-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", + "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==" + }, + "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==", + "optional": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "optional": 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=", + "optional": 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=", + "optional": 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=", + "optional": true + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "optional": true + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "optional": 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==", + "optional": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "optional": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + } + } + }, "redeyed": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-0.4.4.tgz", diff --git a/package.json b/package.json index 82e3fbd0fb..8301e44fe4 100644 --- a/package.json +++ b/package.json @@ -76,6 +76,7 @@ "react-resizable": "^1.10.1", "react-sortable-hoc": "^1.10.1", "react-virtualized": "^9.21.2", + "redash-visualizations": "file:redash-visualizations", "tinycolor2": "^1.4.1", "universal-router": "^8.3.0", "use-debounce": "^3.1.0", diff --git a/redash-visualizations/.babelrc b/redash-visualizations/.babelrc new file mode 100644 index 0000000000..49ae3baaac --- /dev/null +++ b/redash-visualizations/.babelrc @@ -0,0 +1,15 @@ +{ + "presets": ["@babel/preset-env", "@babel/preset-react"], + "plugins": [ + "@babel/plugin-proposal-class-properties", + [ + "module-resolver", + { + "root": ["./src"], + "alias": { + "@": "./src" + } + } + ] + ] +} diff --git a/redash-visualizations/.gitignore b/redash-visualizations/.gitignore new file mode 100644 index 0000000000..64fcced46b --- /dev/null +++ b/redash-visualizations/.gitignore @@ -0,0 +1,20 @@ +# dependencies +node_modules + +# builds +/build +/dist +/lib +.rpt2_cache + +# misc +.DS_Store +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* \ No newline at end of file diff --git a/redash-visualizations/package.json b/redash-visualizations/package.json new file mode 100644 index 0000000000..4ff6621085 --- /dev/null +++ b/redash-visualizations/package.json @@ -0,0 +1,38 @@ +{ + "name": "redash-visualizations", + "version": "1.0.0", + "description": "Redash visualizations", + "main": "lib/index.js", + "scripts": { + "clean": "rm -rf lib", + "build": "npm run clean && babel src --out-dir lib --source-maps --copy-files", + "watch": "babel src --watch --out-dir lib --source-maps --copy-files" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/getredash/redash.git" + }, + "author": "Redash", + "license": "BSD-2-Clause", + "peerDependencies": { + "antd": ">=3.19.0", + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + }, + "devDependencies": { + "@babel/cli": "^7.8.4", + "@babel/core": "^7.9.0", + "@babel/plugin-proposal-class-properties": "^7.8.3", + "@babel/preset-env": "^7.9.0", + "@babel/preset-react": "^7.9.4", + "babel-plugin-module-resolver": "^4.0.0", + "prop-types": "^15.7.2" + }, + "files": [ + "lib" + ], + "dependencies": { + "chroma-js": "^2.1.0", + "numeral": "^2.0.6" + } +} From d95e9494669e1ef907fd0816185dcac196e32458 Mon Sep 17 00:00:00 2001 From: Gabriel Dutra Date: Mon, 6 Apr 2020 18:06:01 -0300 Subject: [PATCH 2/6] Copy visualizations with its dependencies for Counter --- .../src/components/BigMessage.jsx | 30 ++ .../src/components/ColorPicker/Input.jsx | 94 +++++ .../src/components/ColorPicker/Label.jsx | 31 ++ .../src/components/ColorPicker/Swatch.jsx | 36 ++ .../src/components/ColorPicker/index.jsx | 161 ++++++++ .../src/components/ColorPicker/index.less | 40 ++ .../src/components/ColorPicker/input.less | 19 + .../src/components/ColorPicker/label.less | 7 + .../src/components/ColorPicker/swatch.less | 30 ++ .../src/components/ColorPicker/utils.js | 14 + .../src/components/DynamicComponent.jsx | 50 +++ .../visualizations/editor/ContextHelp.jsx | 59 +++ .../visualizations/editor/Section.jsx | 45 +++ .../visualizations/editor/Switch.jsx | 40 ++ .../visualizations/editor/context-help.less | 12 + .../visualizations/editor/control-label.less | 7 + .../editor/createTabbedEditor.jsx | 51 +++ .../components/visualizations/editor/index.js | 21 ++ .../editor/withControlLabel.jsx | 82 ++++ redash-visualizations/src/index.js | 3 + .../src/lib/chooseTextColorForBackground.js | 11 + .../src/services/resizeObserver.js | 32 ++ .../src/visualizations/ColorPalette.js | 38 ++ .../src/visualizations/box-plot/Editor.jsx | 39 ++ .../src/visualizations/box-plot/Renderer.jsx | 197 ++++++++++ .../src/visualizations/box-plot/d3box.js | 328 ++++++++++++++++ .../src/visualizations/box-plot/index.js | 14 + .../src/visualizations/box-plot/renderer.less | 4 + .../chart/Editor/AxisSettings.jsx | 113 ++++++ .../chart/Editor/ChartTypeSelect.jsx | 36 ++ .../chart/Editor/ColorsSettings.jsx | 18 + .../chart/Editor/ColorsSettings.test.js | 124 ++++++ .../chart/Editor/ColumnMappingSelect.jsx | 55 +++ .../chart/Editor/CustomChartSettings.jsx | 49 +++ .../chart/Editor/DataLabelsSettings.jsx | 114 ++++++ .../chart/Editor/DataLabelsSettings.test.js | 97 +++++ .../chart/Editor/DefaultColorsSettings.jsx | 67 ++++ .../chart/Editor/GeneralSettings.jsx | 244 ++++++++++++ .../chart/Editor/GeneralSettings.test.js | 195 ++++++++++ .../chart/Editor/HeatmapColorsSettings.jsx | 82 ++++ .../chart/Editor/PieColorsSettings.jsx | 77 ++++ .../chart/Editor/SeriesSettings.jsx | 148 ++++++++ .../chart/Editor/SeriesSettings.test.js | 81 ++++ .../chart/Editor/XAxisSettings.jsx | 47 +++ .../chart/Editor/XAxisSettings.test.js | 99 +++++ .../chart/Editor/YAxisSettings.jsx | 65 ++++ .../chart/Editor/YAxisSettings.test.js | 141 +++++++ .../__snapshots__/ColorsSettings.test.js.snap | 39 ++ .../DataLabelsSettings.test.js.snap | 31 ++ .../GeneralSettings.test.js.snap | 60 +++ .../__snapshots__/SeriesSettings.test.js.snap | 31 ++ .../__snapshots__/XAxisSettings.test.js.snap | 48 +++ .../__snapshots__/YAxisSettings.test.js.snap | 74 ++++ .../visualizations/chart/Editor/editor.less | 33 ++ .../src/visualizations/chart/Editor/index.jsx | 59 +++ .../visualizations/chart/Editor/index.test.js | 48 +++ .../chart/Renderer/CustomPlotlyChart.jsx | 40 ++ .../chart/Renderer/PlotlyChart.jsx | 76 ++++ .../visualizations/chart/Renderer/index.jsx | 17 + .../chart/Renderer/renderer.less | 4 + .../getChartData/multiple-series-grouped.json | 40 ++ .../multiple-series-multiple-y.json | 41 ++ .../getChartData/multiple-series-sorted.json | 43 +++ .../fixtures/getChartData/single-series.json | 32 ++ .../src/visualizations/chart/getChartData.js | 97 +++++ .../visualizations/chart/getChartData.test.js | 32 ++ .../src/visualizations/chart/getOptions.js | 46 +++ .../src/visualizations/chart/index.js | 17 + .../chart/plotly/applyLayoutFixes.js | 103 +++++ .../chart/plotly/customChartUtils.js | 40 ++ .../fixtures/prepareData/bar/default.json | 56 +++ .../fixtures/prepareData/bar/normalized.json | 81 ++++ .../fixtures/prepareData/bar/stacked.json | 81 ++++ .../fixtures/prepareData/box/default.json | 57 +++ .../fixtures/prepareData/box/with-points.json | 60 +++ .../fixtures/prepareData/bubble/default.json | 55 +++ .../fixtures/prepareData/heatmap/default.json | 33 ++ .../prepareData/heatmap/reversed.json | 35 ++ .../prepareData/heatmap/sorted-reversed.json | 37 ++ .../fixtures/prepareData/heatmap/sorted.json | 35 ++ .../prepareData/heatmap/with-labels.json | 44 +++ .../prepareData/line-area/default.json | 55 +++ .../line-area/keep-missing-values.json | 77 ++++ .../line-area/missing-values-0.json | 77 ++++ .../line-area/normalized-stacked.json | 79 ++++ .../prepareData/line-area/normalized.json | 79 ++++ .../prepareData/line-area/stacked.json | 79 ++++ .../prepareData/pie/custom-tooltip.json | 57 +++ .../fixtures/prepareData/pie/default.json | 57 +++ .../prepareData/pie/without-labels.json | 57 +++ .../fixtures/prepareData/pie/without-x.json | 53 +++ .../fixtures/prepareData/scatter/default.json | 56 +++ .../prepareData/scatter/without-labels.json | 56 +++ .../prepareLayout/box-single-axis.json | 38 ++ .../prepareLayout/box-with-second-axis.json | 46 +++ .../prepareLayout/default-single-axis.json | 36 ++ .../default-with-second-axis.json | 44 +++ .../prepareLayout/default-with-stacking.json | 38 ++ .../prepareLayout/default-without-legend.json | 37 ++ .../prepareLayout/pie-multiple-series.json | 48 +++ .../pie-without-annotations.json | 21 ++ .../plotly/fixtures/prepareLayout/pie.json | 30 ++ .../src/visualizations/chart/plotly/index.js | 27 ++ .../chart/plotly/prepareData.js | 15 + .../chart/plotly/prepareData.test.js | 160 ++++++++ .../chart/plotly/prepareDefaultData.js | 158 ++++++++ .../chart/plotly/prepareHeatmapData.js | 109 ++++++ .../chart/plotly/prepareLayout.js | 136 +++++++ .../chart/plotly/prepareLayout.test.js | 64 ++++ .../chart/plotly/preparePieData.js | 116 ++++++ .../visualizations/chart/plotly/updateData.js | 229 +++++++++++ .../src/visualizations/chart/plotly/utils.js | 25 ++ .../visualizations/choropleth/ColorPalette.js | 11 + .../choropleth/Editor/BoundsSettings.jsx | 67 ++++ .../choropleth/Editor/ColorsSettings.jsx | 118 ++++++ .../choropleth/Editor/FormatSettings.jsx | 189 ++++++++++ .../choropleth/Editor/GeneralSettings.jsx | 106 ++++++ .../visualizations/choropleth/Editor/index.js | 13 + .../visualizations/choropleth/Editor/utils.js | 38 ++ .../choropleth/Renderer/Legend.jsx | 32 ++ .../choropleth/Renderer/index.jsx | 86 +++++ .../choropleth/Renderer/initChoropleth.js | 178 +++++++++ .../choropleth/Renderer/renderer.less | 9 + .../choropleth/Renderer/utils.js | 109 ++++++ .../visualizations/choropleth/getOptions.js | 37 ++ .../src/visualizations/choropleth/index.js | 15 + .../choropleth/maps/countries.geo.json | 1 + .../maps/japan.prefectures.geo.json | 54 +++ .../src/visualizations/cohort/Cornelius.jsx | 225 +++++++++++ .../cohort/Editor/AppearanceSettings.jsx | 99 +++++ .../cohort/Editor/ColorsSettings.jsx | 61 +++ .../cohort/Editor/ColumnsSettings.jsx | 76 ++++ .../cohort/Editor/OptionsSettings.jsx | 55 +++ .../src/visualizations/cohort/Editor/index.js | 13 + .../src/visualizations/cohort/Renderer.jsx | 44 +++ .../src/visualizations/cohort/cornelius.less | 53 +++ .../src/visualizations/cohort/getOptions.js | 32 ++ .../src/visualizations/cohort/index.js | 14 + .../src/visualizations/cohort/prepareData.js | 135 +++++++ .../src/visualizations/cohort/renderer.less | 18 + .../components/EditVisualizationDialog.jsx | 228 +++++++++++ .../components/EditVisualizationDialog.less | 18 + .../components/TestRenderer.jsx | 41 ++ .../components/VisualizationName.jsx | 20 + .../components/VisualizationName.less | 14 + .../components/VisualizationRenderer.jsx | 107 ++++++ .../counter/Editor/FormatSettings.jsx | 83 ++++ .../counter/Editor/GeneralSettings.jsx | 90 +++++ .../visualizations/counter/Editor/index.js | 9 + .../src/visualizations/counter/Renderer.jsx | 79 ++++ .../src/visualizations/counter/index.js | 24 ++ .../src/visualizations/counter/render.less | 46 +++ .../src/visualizations/counter/utils.js | 133 +++++++ .../src/visualizations/counter/utils.test.js | 168 +++++++++ .../details/DetailsRenderer.jsx | 59 +++ .../src/visualizations/details/details.less | 5 + .../src/visualizations/details/index.js | 12 + .../funnel/Editor/AppearanceSettings.jsx | 82 ++++ .../funnel/Editor/GeneralSettings.jsx | 122 ++++++ .../src/visualizations/funnel/Editor/index.js | 9 + .../funnel/Renderer/FunnelBar.jsx | 30 ++ .../funnel/Renderer/funnel-bar.less | 32 ++ .../visualizations/funnel/Renderer/index.jsx | 103 +++++ .../visualizations/funnel/Renderer/index.less | 38 ++ .../funnel/Renderer/prepareData.js | 38 ++ .../src/visualizations/funnel/getOptions.js | 42 +++ .../src/visualizations/funnel/index.js | 13 + .../src/visualizations/index.js | 99 +++++ .../map/Editor/FormatSettings.jsx | 71 ++++ .../map/Editor/GeneralSettings.jsx | 72 ++++ .../map/Editor/GroupsSettings.jsx | 64 ++++ .../map/Editor/StyleSettings.jsx | 244 ++++++++++++ .../src/visualizations/map/Editor/index.js | 13 + .../src/visualizations/map/Renderer.jsx | 59 +++ .../src/visualizations/map/getOptions.js | 37 ++ .../src/visualizations/map/index.js | 15 + .../src/visualizations/map/initMap.js | 223 +++++++++++ .../src/visualizations/map/prepareData.js | 35 ++ .../src/visualizations/pivot/Editor.jsx | 42 +++ .../src/visualizations/pivot/Renderer.jsx | 65 ++++ .../src/visualizations/pivot/index.js | 28 ++ .../src/visualizations/pivot/renderer.less | 88 +++++ .../src/visualizations/prop-types.js | 32 ++ .../src/visualizations/sankey/Editor.jsx | 29 ++ .../src/visualizations/sankey/Renderer.jsx | 26 ++ .../src/visualizations/sankey/d3sankey.js | 293 ++++++++++++++ .../src/visualizations/sankey/index.js | 12 + .../src/visualizations/sankey/initSankey.js | 243 ++++++++++++ .../src/visualizations/sankey/renderer.less | 19 + .../src/visualizations/sunburst/Editor.jsx | 54 +++ .../src/visualizations/sunburst/Renderer.jsx | 26 ++ .../src/visualizations/sunburst/index.js | 12 + .../visualizations/sunburst/initSunburst.js | 357 ++++++++++++++++++ .../src/visualizations/sunburst/renderer.less | 36 ++ .../table/Editor/ColumnEditor.jsx | 82 ++++ .../table/Editor/ColumnsSettings.jsx | 78 ++++ .../table/Editor/ColumnsSettings.test.js | 87 +++++ .../table/Editor/GridSettings.jsx | 27 ++ .../table/Editor/GridSettings.test.js | 43 +++ .../ColumnsSettings.test.js.snap | 166 ++++++++ .../__snapshots__/GridSettings.test.js.snap | 7 + .../visualizations/table/Editor/editor.less | 23 ++ .../src/visualizations/table/Editor/index.jsx | 11 + .../src/visualizations/table/Renderer.jsx | 133 +++++++ .../__snapshots__/boolean.test.js.snap | 19 + .../__snapshots__/datetime.test.js.snap | 7 + .../columns/__snapshots__/image.test.js.snap | 25 ++ .../columns/__snapshots__/link.test.js.snap | 25 ++ .../columns/__snapshots__/number.test.js.snap | 7 + .../columns/__snapshots__/text.test.js.snap | 13 + .../visualizations/table/columns/boolean.jsx | 76 ++++ .../table/columns/boolean.test.js | 55 +++ .../visualizations/table/columns/datetime.jsx | 56 +++ .../table/columns/datetime.test.js | 40 ++ .../visualizations/table/columns/image.jsx | 131 +++++++ .../table/columns/image.test.js | 85 +++++ .../src/visualizations/table/columns/index.js | 18 + .../src/visualizations/table/columns/json.jsx | 38 ++ .../src/visualizations/table/columns/link.jsx | 117 ++++++ .../visualizations/table/columns/link.test.js | 85 +++++ .../visualizations/table/columns/number.jsx | 56 +++ .../table/columns/number.test.js | 40 ++ .../src/visualizations/table/columns/text.jsx | 63 ++++ .../visualizations/table/columns/text.test.js | 57 +++ .../src/visualizations/table/getOptions.js | 107 ++++++ .../src/visualizations/table/index.js | 16 + .../src/visualizations/table/renderer.less | 139 +++++++ .../src/visualizations/table/utils.js | 190 ++++++++++ .../src/visualizations/word-cloud/Editor.jsx | 101 +++++ .../visualizations/word-cloud/Renderer.jsx | 174 +++++++++ .../src/visualizations/word-cloud/index.js | 21 ++ .../visualizations/word-cloud/renderer.less | 12 + 232 files changed, 15388 insertions(+) create mode 100644 redash-visualizations/src/components/BigMessage.jsx create mode 100644 redash-visualizations/src/components/ColorPicker/Input.jsx create mode 100644 redash-visualizations/src/components/ColorPicker/Label.jsx create mode 100644 redash-visualizations/src/components/ColorPicker/Swatch.jsx create mode 100644 redash-visualizations/src/components/ColorPicker/index.jsx create mode 100644 redash-visualizations/src/components/ColorPicker/index.less create mode 100644 redash-visualizations/src/components/ColorPicker/input.less create mode 100644 redash-visualizations/src/components/ColorPicker/label.less create mode 100644 redash-visualizations/src/components/ColorPicker/swatch.less create mode 100644 redash-visualizations/src/components/ColorPicker/utils.js create mode 100644 redash-visualizations/src/components/DynamicComponent.jsx create mode 100644 redash-visualizations/src/components/visualizations/editor/ContextHelp.jsx create mode 100644 redash-visualizations/src/components/visualizations/editor/Section.jsx create mode 100644 redash-visualizations/src/components/visualizations/editor/Switch.jsx create mode 100644 redash-visualizations/src/components/visualizations/editor/context-help.less create mode 100644 redash-visualizations/src/components/visualizations/editor/control-label.less create mode 100644 redash-visualizations/src/components/visualizations/editor/createTabbedEditor.jsx create mode 100644 redash-visualizations/src/components/visualizations/editor/index.js create mode 100644 redash-visualizations/src/components/visualizations/editor/withControlLabel.jsx create mode 100644 redash-visualizations/src/index.js create mode 100644 redash-visualizations/src/lib/chooseTextColorForBackground.js create mode 100644 redash-visualizations/src/services/resizeObserver.js create mode 100644 redash-visualizations/src/visualizations/ColorPalette.js create mode 100644 redash-visualizations/src/visualizations/box-plot/Editor.jsx create mode 100644 redash-visualizations/src/visualizations/box-plot/Renderer.jsx create mode 100644 redash-visualizations/src/visualizations/box-plot/d3box.js create mode 100644 redash-visualizations/src/visualizations/box-plot/index.js create mode 100644 redash-visualizations/src/visualizations/box-plot/renderer.less create mode 100644 redash-visualizations/src/visualizations/chart/Editor/AxisSettings.jsx create mode 100644 redash-visualizations/src/visualizations/chart/Editor/ChartTypeSelect.jsx create mode 100644 redash-visualizations/src/visualizations/chart/Editor/ColorsSettings.jsx create mode 100644 redash-visualizations/src/visualizations/chart/Editor/ColorsSettings.test.js create mode 100644 redash-visualizations/src/visualizations/chart/Editor/ColumnMappingSelect.jsx create mode 100644 redash-visualizations/src/visualizations/chart/Editor/CustomChartSettings.jsx create mode 100644 redash-visualizations/src/visualizations/chart/Editor/DataLabelsSettings.jsx create mode 100644 redash-visualizations/src/visualizations/chart/Editor/DataLabelsSettings.test.js create mode 100644 redash-visualizations/src/visualizations/chart/Editor/DefaultColorsSettings.jsx create mode 100644 redash-visualizations/src/visualizations/chart/Editor/GeneralSettings.jsx create mode 100644 redash-visualizations/src/visualizations/chart/Editor/GeneralSettings.test.js create mode 100644 redash-visualizations/src/visualizations/chart/Editor/HeatmapColorsSettings.jsx create mode 100644 redash-visualizations/src/visualizations/chart/Editor/PieColorsSettings.jsx create mode 100644 redash-visualizations/src/visualizations/chart/Editor/SeriesSettings.jsx create mode 100644 redash-visualizations/src/visualizations/chart/Editor/SeriesSettings.test.js create mode 100644 redash-visualizations/src/visualizations/chart/Editor/XAxisSettings.jsx create mode 100644 redash-visualizations/src/visualizations/chart/Editor/XAxisSettings.test.js create mode 100644 redash-visualizations/src/visualizations/chart/Editor/YAxisSettings.jsx create mode 100644 redash-visualizations/src/visualizations/chart/Editor/YAxisSettings.test.js create mode 100644 redash-visualizations/src/visualizations/chart/Editor/__snapshots__/ColorsSettings.test.js.snap create mode 100644 redash-visualizations/src/visualizations/chart/Editor/__snapshots__/DataLabelsSettings.test.js.snap create mode 100644 redash-visualizations/src/visualizations/chart/Editor/__snapshots__/GeneralSettings.test.js.snap create mode 100644 redash-visualizations/src/visualizations/chart/Editor/__snapshots__/SeriesSettings.test.js.snap create mode 100644 redash-visualizations/src/visualizations/chart/Editor/__snapshots__/XAxisSettings.test.js.snap create mode 100644 redash-visualizations/src/visualizations/chart/Editor/__snapshots__/YAxisSettings.test.js.snap create mode 100644 redash-visualizations/src/visualizations/chart/Editor/editor.less create mode 100644 redash-visualizations/src/visualizations/chart/Editor/index.jsx create mode 100644 redash-visualizations/src/visualizations/chart/Editor/index.test.js create mode 100644 redash-visualizations/src/visualizations/chart/Renderer/CustomPlotlyChart.jsx create mode 100644 redash-visualizations/src/visualizations/chart/Renderer/PlotlyChart.jsx create mode 100644 redash-visualizations/src/visualizations/chart/Renderer/index.jsx create mode 100644 redash-visualizations/src/visualizations/chart/Renderer/renderer.less create mode 100644 redash-visualizations/src/visualizations/chart/fixtures/getChartData/multiple-series-grouped.json create mode 100644 redash-visualizations/src/visualizations/chart/fixtures/getChartData/multiple-series-multiple-y.json create mode 100644 redash-visualizations/src/visualizations/chart/fixtures/getChartData/multiple-series-sorted.json create mode 100644 redash-visualizations/src/visualizations/chart/fixtures/getChartData/single-series.json create mode 100644 redash-visualizations/src/visualizations/chart/getChartData.js create mode 100644 redash-visualizations/src/visualizations/chart/getChartData.test.js create mode 100644 redash-visualizations/src/visualizations/chart/getOptions.js create mode 100644 redash-visualizations/src/visualizations/chart/index.js create mode 100644 redash-visualizations/src/visualizations/chart/plotly/applyLayoutFixes.js create mode 100644 redash-visualizations/src/visualizations/chart/plotly/customChartUtils.js create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareData/bar/default.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareData/bar/normalized.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareData/bar/stacked.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareData/box/default.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareData/box/with-points.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareData/bubble/default.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareData/heatmap/default.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareData/heatmap/reversed.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareData/heatmap/sorted-reversed.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareData/heatmap/sorted.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareData/heatmap/with-labels.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareData/line-area/default.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareData/line-area/keep-missing-values.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareData/line-area/missing-values-0.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareData/line-area/normalized-stacked.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareData/line-area/normalized.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareData/line-area/stacked.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareData/pie/custom-tooltip.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareData/pie/default.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareData/pie/without-labels.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareData/pie/without-x.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareData/scatter/default.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareData/scatter/without-labels.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareLayout/box-single-axis.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareLayout/box-with-second-axis.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareLayout/default-single-axis.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareLayout/default-with-second-axis.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareLayout/default-with-stacking.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareLayout/default-without-legend.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareLayout/pie-multiple-series.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareLayout/pie-without-annotations.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/fixtures/prepareLayout/pie.json create mode 100644 redash-visualizations/src/visualizations/chart/plotly/index.js create mode 100644 redash-visualizations/src/visualizations/chart/plotly/prepareData.js create mode 100644 redash-visualizations/src/visualizations/chart/plotly/prepareData.test.js create mode 100644 redash-visualizations/src/visualizations/chart/plotly/prepareDefaultData.js create mode 100644 redash-visualizations/src/visualizations/chart/plotly/prepareHeatmapData.js create mode 100644 redash-visualizations/src/visualizations/chart/plotly/prepareLayout.js create mode 100644 redash-visualizations/src/visualizations/chart/plotly/prepareLayout.test.js create mode 100644 redash-visualizations/src/visualizations/chart/plotly/preparePieData.js create mode 100644 redash-visualizations/src/visualizations/chart/plotly/updateData.js create mode 100644 redash-visualizations/src/visualizations/chart/plotly/utils.js create mode 100644 redash-visualizations/src/visualizations/choropleth/ColorPalette.js create mode 100644 redash-visualizations/src/visualizations/choropleth/Editor/BoundsSettings.jsx create mode 100644 redash-visualizations/src/visualizations/choropleth/Editor/ColorsSettings.jsx create mode 100644 redash-visualizations/src/visualizations/choropleth/Editor/FormatSettings.jsx create mode 100644 redash-visualizations/src/visualizations/choropleth/Editor/GeneralSettings.jsx create mode 100644 redash-visualizations/src/visualizations/choropleth/Editor/index.js create mode 100644 redash-visualizations/src/visualizations/choropleth/Editor/utils.js create mode 100644 redash-visualizations/src/visualizations/choropleth/Renderer/Legend.jsx create mode 100644 redash-visualizations/src/visualizations/choropleth/Renderer/index.jsx create mode 100644 redash-visualizations/src/visualizations/choropleth/Renderer/initChoropleth.js create mode 100644 redash-visualizations/src/visualizations/choropleth/Renderer/renderer.less create mode 100644 redash-visualizations/src/visualizations/choropleth/Renderer/utils.js create mode 100644 redash-visualizations/src/visualizations/choropleth/getOptions.js create mode 100644 redash-visualizations/src/visualizations/choropleth/index.js create mode 100644 redash-visualizations/src/visualizations/choropleth/maps/countries.geo.json create mode 100644 redash-visualizations/src/visualizations/choropleth/maps/japan.prefectures.geo.json create mode 100644 redash-visualizations/src/visualizations/cohort/Cornelius.jsx create mode 100644 redash-visualizations/src/visualizations/cohort/Editor/AppearanceSettings.jsx create mode 100644 redash-visualizations/src/visualizations/cohort/Editor/ColorsSettings.jsx create mode 100644 redash-visualizations/src/visualizations/cohort/Editor/ColumnsSettings.jsx create mode 100644 redash-visualizations/src/visualizations/cohort/Editor/OptionsSettings.jsx create mode 100644 redash-visualizations/src/visualizations/cohort/Editor/index.js create mode 100644 redash-visualizations/src/visualizations/cohort/Renderer.jsx create mode 100644 redash-visualizations/src/visualizations/cohort/cornelius.less create mode 100644 redash-visualizations/src/visualizations/cohort/getOptions.js create mode 100644 redash-visualizations/src/visualizations/cohort/index.js create mode 100644 redash-visualizations/src/visualizations/cohort/prepareData.js create mode 100644 redash-visualizations/src/visualizations/cohort/renderer.less create mode 100644 redash-visualizations/src/visualizations/components/EditVisualizationDialog.jsx create mode 100644 redash-visualizations/src/visualizations/components/EditVisualizationDialog.less create mode 100644 redash-visualizations/src/visualizations/components/TestRenderer.jsx create mode 100644 redash-visualizations/src/visualizations/components/VisualizationName.jsx create mode 100644 redash-visualizations/src/visualizations/components/VisualizationName.less create mode 100644 redash-visualizations/src/visualizations/components/VisualizationRenderer.jsx create mode 100644 redash-visualizations/src/visualizations/counter/Editor/FormatSettings.jsx create mode 100644 redash-visualizations/src/visualizations/counter/Editor/GeneralSettings.jsx create mode 100644 redash-visualizations/src/visualizations/counter/Editor/index.js create mode 100644 redash-visualizations/src/visualizations/counter/Renderer.jsx create mode 100644 redash-visualizations/src/visualizations/counter/index.js create mode 100755 redash-visualizations/src/visualizations/counter/render.less create mode 100644 redash-visualizations/src/visualizations/counter/utils.js create mode 100644 redash-visualizations/src/visualizations/counter/utils.test.js create mode 100644 redash-visualizations/src/visualizations/details/DetailsRenderer.jsx create mode 100644 redash-visualizations/src/visualizations/details/details.less create mode 100644 redash-visualizations/src/visualizations/details/index.js create mode 100644 redash-visualizations/src/visualizations/funnel/Editor/AppearanceSettings.jsx create mode 100644 redash-visualizations/src/visualizations/funnel/Editor/GeneralSettings.jsx create mode 100644 redash-visualizations/src/visualizations/funnel/Editor/index.js create mode 100644 redash-visualizations/src/visualizations/funnel/Renderer/FunnelBar.jsx create mode 100644 redash-visualizations/src/visualizations/funnel/Renderer/funnel-bar.less create mode 100644 redash-visualizations/src/visualizations/funnel/Renderer/index.jsx create mode 100644 redash-visualizations/src/visualizations/funnel/Renderer/index.less create mode 100644 redash-visualizations/src/visualizations/funnel/Renderer/prepareData.js create mode 100644 redash-visualizations/src/visualizations/funnel/getOptions.js create mode 100644 redash-visualizations/src/visualizations/funnel/index.js create mode 100644 redash-visualizations/src/visualizations/index.js create mode 100644 redash-visualizations/src/visualizations/map/Editor/FormatSettings.jsx create mode 100644 redash-visualizations/src/visualizations/map/Editor/GeneralSettings.jsx create mode 100644 redash-visualizations/src/visualizations/map/Editor/GroupsSettings.jsx create mode 100644 redash-visualizations/src/visualizations/map/Editor/StyleSettings.jsx create mode 100644 redash-visualizations/src/visualizations/map/Editor/index.js create mode 100644 redash-visualizations/src/visualizations/map/Renderer.jsx create mode 100644 redash-visualizations/src/visualizations/map/getOptions.js create mode 100644 redash-visualizations/src/visualizations/map/index.js create mode 100644 redash-visualizations/src/visualizations/map/initMap.js create mode 100644 redash-visualizations/src/visualizations/map/prepareData.js create mode 100644 redash-visualizations/src/visualizations/pivot/Editor.jsx create mode 100644 redash-visualizations/src/visualizations/pivot/Renderer.jsx create mode 100644 redash-visualizations/src/visualizations/pivot/index.js create mode 100644 redash-visualizations/src/visualizations/pivot/renderer.less create mode 100644 redash-visualizations/src/visualizations/prop-types.js create mode 100644 redash-visualizations/src/visualizations/sankey/Editor.jsx create mode 100644 redash-visualizations/src/visualizations/sankey/Renderer.jsx create mode 100644 redash-visualizations/src/visualizations/sankey/d3sankey.js create mode 100644 redash-visualizations/src/visualizations/sankey/index.js create mode 100644 redash-visualizations/src/visualizations/sankey/initSankey.js create mode 100644 redash-visualizations/src/visualizations/sankey/renderer.less create mode 100644 redash-visualizations/src/visualizations/sunburst/Editor.jsx create mode 100644 redash-visualizations/src/visualizations/sunburst/Renderer.jsx create mode 100644 redash-visualizations/src/visualizations/sunburst/index.js create mode 100644 redash-visualizations/src/visualizations/sunburst/initSunburst.js create mode 100644 redash-visualizations/src/visualizations/sunburst/renderer.less create mode 100644 redash-visualizations/src/visualizations/table/Editor/ColumnEditor.jsx create mode 100644 redash-visualizations/src/visualizations/table/Editor/ColumnsSettings.jsx create mode 100644 redash-visualizations/src/visualizations/table/Editor/ColumnsSettings.test.js create mode 100644 redash-visualizations/src/visualizations/table/Editor/GridSettings.jsx create mode 100644 redash-visualizations/src/visualizations/table/Editor/GridSettings.test.js create mode 100644 redash-visualizations/src/visualizations/table/Editor/__snapshots__/ColumnsSettings.test.js.snap create mode 100644 redash-visualizations/src/visualizations/table/Editor/__snapshots__/GridSettings.test.js.snap create mode 100644 redash-visualizations/src/visualizations/table/Editor/editor.less create mode 100644 redash-visualizations/src/visualizations/table/Editor/index.jsx create mode 100644 redash-visualizations/src/visualizations/table/Renderer.jsx create mode 100644 redash-visualizations/src/visualizations/table/columns/__snapshots__/boolean.test.js.snap create mode 100644 redash-visualizations/src/visualizations/table/columns/__snapshots__/datetime.test.js.snap create mode 100644 redash-visualizations/src/visualizations/table/columns/__snapshots__/image.test.js.snap create mode 100644 redash-visualizations/src/visualizations/table/columns/__snapshots__/link.test.js.snap create mode 100644 redash-visualizations/src/visualizations/table/columns/__snapshots__/number.test.js.snap create mode 100644 redash-visualizations/src/visualizations/table/columns/__snapshots__/text.test.js.snap create mode 100644 redash-visualizations/src/visualizations/table/columns/boolean.jsx create mode 100644 redash-visualizations/src/visualizations/table/columns/boolean.test.js create mode 100644 redash-visualizations/src/visualizations/table/columns/datetime.jsx create mode 100644 redash-visualizations/src/visualizations/table/columns/datetime.test.js create mode 100644 redash-visualizations/src/visualizations/table/columns/image.jsx create mode 100644 redash-visualizations/src/visualizations/table/columns/image.test.js create mode 100644 redash-visualizations/src/visualizations/table/columns/index.js create mode 100644 redash-visualizations/src/visualizations/table/columns/json.jsx create mode 100644 redash-visualizations/src/visualizations/table/columns/link.jsx create mode 100644 redash-visualizations/src/visualizations/table/columns/link.test.js create mode 100644 redash-visualizations/src/visualizations/table/columns/number.jsx create mode 100644 redash-visualizations/src/visualizations/table/columns/number.test.js create mode 100644 redash-visualizations/src/visualizations/table/columns/text.jsx create mode 100644 redash-visualizations/src/visualizations/table/columns/text.test.js create mode 100644 redash-visualizations/src/visualizations/table/getOptions.js create mode 100644 redash-visualizations/src/visualizations/table/index.js create mode 100644 redash-visualizations/src/visualizations/table/renderer.less create mode 100644 redash-visualizations/src/visualizations/table/utils.js create mode 100644 redash-visualizations/src/visualizations/word-cloud/Editor.jsx create mode 100644 redash-visualizations/src/visualizations/word-cloud/Renderer.jsx create mode 100644 redash-visualizations/src/visualizations/word-cloud/index.js create mode 100644 redash-visualizations/src/visualizations/word-cloud/renderer.less diff --git a/redash-visualizations/src/components/BigMessage.jsx b/redash-visualizations/src/components/BigMessage.jsx new file mode 100644 index 0000000000..bbd4ccf9c9 --- /dev/null +++ b/redash-visualizations/src/components/BigMessage.jsx @@ -0,0 +1,30 @@ +import React from "react"; +import PropTypes from "prop-types"; + +function BigMessage({ message, icon, children, className }) { + return ( +
+

+ +

+
+ {message} + {children} +
+ ); +} + +BigMessage.propTypes = { + message: PropTypes.string, + icon: PropTypes.string.isRequired, + children: PropTypes.node, + className: PropTypes.string, +}; + +BigMessage.defaultProps = { + message: "", + children: null, + className: "tiled bg-white", +}; + +export default BigMessage; diff --git a/redash-visualizations/src/components/ColorPicker/Input.jsx b/redash-visualizations/src/components/ColorPicker/Input.jsx new file mode 100644 index 0000000000..47b89fd6ad --- /dev/null +++ b/redash-visualizations/src/components/ColorPicker/Input.jsx @@ -0,0 +1,94 @@ +import { isNil, isArray, chunk, map, filter, toPairs } from "lodash"; +import React, { useState, useEffect } from "react"; +import PropTypes from "prop-types"; +import tinycolor from "tinycolor2"; +import TextInput from "antd/lib/input"; +import Typography from "antd/lib/typography"; +import Swatch from "./Swatch"; + +import "./input.less"; + +function preparePresets(presetColors, presetColumns) { + presetColors = isArray(presetColors) ? map(presetColors, v => [null, v]) : toPairs(presetColors); + presetColors = map(presetColors, ([title, value]) => { + if (isNil(value)) { + return [title, null]; + } + value = tinycolor(value); + if (value.isValid()) { + return [title, "#" + value.toHex().toUpperCase()]; + } + return null; + }); + return chunk(filter(presetColors), presetColumns); +} + +function validateColor(value, callback, prefix = "#") { + if (isNil(value)) { + callback(null); + } + value = tinycolor(value); + if (value.isValid()) { + callback(prefix + value.toHex().toUpperCase()); + } +} + +export default function Input({ color, presetColors, presetColumns, onChange, onPressEnter }) { + const [inputValue, setInputValue] = useState(""); + const [isInputFocused, setIsInputFocused] = useState(false); + + const presets = preparePresets(presetColors, presetColumns); + + function handleInputChange(value) { + setInputValue(value); + validateColor(value, onChange); + } + + useEffect(() => { + if (!isInputFocused) { + validateColor(color, setInputValue, ""); + } + }, [color, isInputFocused]); + + return ( + + {map(presets, (group, index) => ( +
+ {map(group, ([title, value]) => ( + validateColor(value, onChange)} /> + ))} +
+ ))} +
+ #} + value={inputValue} + onChange={e => handleInputChange(e.target.value)} + onFocus={() => setIsInputFocused(true)} + onBlur={() => setIsInputFocused(false)} + onPressEnter={onPressEnter} + /> +
+
+ ); +} + +Input.propTypes = { + color: PropTypes.string, + presetColors: PropTypes.oneOfType([ + PropTypes.arrayOf(PropTypes.string), // array of colors (no tooltips) + PropTypes.objectOf(PropTypes.string), // color name => color value + ]), + presetColumns: PropTypes.number, + onChange: PropTypes.func, + onPressEnter: PropTypes.func, +}; + +Input.defaultProps = { + color: "#FFFFFF", + presetColors: null, + presetColumns: 8, + onChange: () => {}, + onPressEnter: () => {}, +}; diff --git a/redash-visualizations/src/components/ColorPicker/Label.jsx b/redash-visualizations/src/components/ColorPicker/Label.jsx new file mode 100644 index 0000000000..1cd8a4decf --- /dev/null +++ b/redash-visualizations/src/components/ColorPicker/Label.jsx @@ -0,0 +1,31 @@ +import React, { useMemo } from "react"; +import PropTypes from "prop-types"; +import cx from "classnames"; + +import { validateColor, getColorName } from "./utils"; +import "./label.less"; + +export default function Label({ className, color, presetColors, ...props }) { + const name = useMemo(() => getColorName(validateColor(color), presetColors), [color, presetColors]); + + return ( + + {name} + + ); +} + +Label.propTypes = { + className: PropTypes.string, + color: PropTypes.string, + presetColors: PropTypes.oneOfType([ + PropTypes.arrayOf(PropTypes.string), // array of colors (no tooltips) + PropTypes.objectOf(PropTypes.string), // color name => color value + ]), +}; + +Label.defaultProps = { + className: null, + color: "#FFFFFF", + presetColors: null, +}; diff --git a/redash-visualizations/src/components/ColorPicker/Swatch.jsx b/redash-visualizations/src/components/ColorPicker/Swatch.jsx new file mode 100644 index 0000000000..6d3df9f5ef --- /dev/null +++ b/redash-visualizations/src/components/ColorPicker/Swatch.jsx @@ -0,0 +1,36 @@ +import { isString } from "lodash"; +import React from "react"; +import PropTypes from "prop-types"; +import cx from "classnames"; +import Tooltip from "antd/lib/tooltip"; + +import "./swatch.less"; + +export default function Swatch({ className, color, title, size, ...props }) { + const result = ( + + ); + + if (isString(title) && title !== "") { + return ( + + {result} + + ); + } + return result; +} + +Swatch.propTypes = { + className: PropTypes.string, + title: PropTypes.string, + color: PropTypes.string, + size: PropTypes.number, +}; + +Swatch.defaultProps = { + className: null, + title: null, + color: "transparent", + size: 12, +}; diff --git a/redash-visualizations/src/components/ColorPicker/index.jsx b/redash-visualizations/src/components/ColorPicker/index.jsx new file mode 100644 index 0000000000..4c86f22042 --- /dev/null +++ b/redash-visualizations/src/components/ColorPicker/index.jsx @@ -0,0 +1,161 @@ +import { toString } from "lodash"; +import React, { useState, useEffect, useMemo } from "react"; +import PropTypes from "prop-types"; +import cx from "classnames"; +import Popover from "antd/lib/popover"; +import Card from "antd/lib/card"; +import Tooltip from "antd/lib/tooltip"; +import Icon from "antd/lib/icon"; +import chooseTextColorForBackground from "@/lib/chooseTextColorForBackground"; + +import ColorInput from "./Input"; +import Swatch from "./Swatch"; +import Label from "./Label"; +import { validateColor } from "./utils"; + +import "./index.less"; + +export default function ColorPicker({ + color, + placement, + presetColors, + presetColumns, + interactive, + children, + onChange, + triggerProps, + addonBefore, + addonAfter, +}) { + const [visible, setVisible] = useState(false); + const validatedColor = useMemo(() => validateColor(color), [color]); + const [currentColor, setCurrentColor] = useState(""); + + function handleApply() { + setVisible(false); + if (!interactive) { + onChange(currentColor); + } + } + + function handleCancel() { + setVisible(false); + } + + const actions = []; + if (!interactive) { + actions.push( + + + + ); + actions.push( + + + + ); + } + + function handleInputChange(newColor) { + setCurrentColor(newColor); + if (interactive) { + onChange(newColor); + } + } + + useEffect(() => { + if (visible) { + setCurrentColor(validatedColor); + } + }, [validatedColor, visible]); + + return ( + + {addonBefore} + + + + } + trigger="click" + placement={placement} + visible={visible} + onVisibleChange={setVisible}> + {children || ( + + )} + + {addonAfter} + + ); +} + +ColorPicker.propTypes = { + color: PropTypes.string, + placement: PropTypes.oneOf([ + "top", + "left", + "right", + "bottom", + "topLeft", + "topRight", + "bottomLeft", + "bottomRight", + "leftTop", + "leftBottom", + "rightTop", + "rightBottom", + ]), + presetColors: PropTypes.oneOfType([ + PropTypes.arrayOf(PropTypes.string), // array of colors (no tooltips) + PropTypes.objectOf(PropTypes.string), // color name => color value + ]), + presetColumns: PropTypes.number, + interactive: PropTypes.bool, + triggerProps: PropTypes.object, // eslint-disable-line react/forbid-prop-types + children: PropTypes.node, + addonBefore: PropTypes.node, + addonAfter: PropTypes.node, + onChange: PropTypes.func, +}; + +ColorPicker.defaultProps = { + color: "#FFFFFF", + placement: "top", + presetColors: null, + presetColumns: 8, + interactive: false, + triggerProps: {}, + children: null, + addonBefore: null, + addonAfter: null, + onChange: () => {}, +}; + +ColorPicker.Input = ColorInput; +ColorPicker.Swatch = Swatch; +ColorPicker.Label = Label; diff --git a/redash-visualizations/src/components/ColorPicker/index.less b/redash-visualizations/src/components/ColorPicker/index.less new file mode 100644 index 0000000000..00bf5768e2 --- /dev/null +++ b/redash-visualizations/src/components/ColorPicker/index.less @@ -0,0 +1,40 @@ +.color-picker { + &.color-picker-with-actions { + &.ant-popover-placement-top, + &.ant-popover-placement-topLeft, + &.ant-popover-placement-topRight, + &.ant-popover-placement-leftBottom, + &.ant-popover-placement-rightBottom { + > .ant-popover-content > .ant-popover-arrow { + border-color: #fafafa; // same as card actions + } + } + } + + &.ant-popover-placement-bottom, + &.ant-popover-placement-bottomLeft, + &.ant-popover-placement-bottomRight, + &.ant-popover-placement-leftTop, + &.ant-popover-placement-rightTop { + > .ant-popover-content > .ant-popover-arrow { + border-color: var(--color-picker-selected-color); + } + } + + .ant-popover-inner-content { + padding: 0; + } + + .ant-card-head { + text-align: center; + border-bottom-color: rgba(0, 0, 0, 0.1); + } + + .ant-card-body { + padding: 10px; + } +} + +.color-picker-trigger { + cursor: pointer; +} diff --git a/redash-visualizations/src/components/ColorPicker/input.less b/redash-visualizations/src/components/ColorPicker/input.less new file mode 100644 index 0000000000..56f9d7ec58 --- /dev/null +++ b/redash-visualizations/src/components/ColorPicker/input.less @@ -0,0 +1,19 @@ +.color-picker-input-swatches { + margin: 0 0 10px 0; + text-align: left; + white-space: nowrap; + + .color-swatch { + cursor: pointer; + margin: 0 10px 0 0; + + &:last-child { + margin-right: 0; + } + } +} + +.color-picker-input { + text-align: left; + white-space: nowrap; +} diff --git a/redash-visualizations/src/components/ColorPicker/label.less b/redash-visualizations/src/components/ColorPicker/label.less new file mode 100644 index 0000000000..e8aa009f30 --- /dev/null +++ b/redash-visualizations/src/components/ColorPicker/label.less @@ -0,0 +1,7 @@ +.color-label { + vertical-align: middle; + + .color-swatch + & { + margin-left: 7px; + } +} diff --git a/redash-visualizations/src/components/ColorPicker/swatch.less b/redash-visualizations/src/components/ColorPicker/swatch.less new file mode 100644 index 0000000000..4dea312c44 --- /dev/null +++ b/redash-visualizations/src/components/ColorPicker/swatch.less @@ -0,0 +1,30 @@ +.color-swatch { + display: inline-block; + box-sizing: border-box; + vertical-align: middle; + border-radius: 2px; + overflow: hidden; + width: 12px; + + @cell-size: 12px; + @cell-color: rgba(0, 0, 0, 0.1); + + background-color: transparent; + background-image: + linear-gradient(45deg, @cell-color 25%, transparent 25%), + linear-gradient(-45deg, @cell-color 25%, transparent 25%), + linear-gradient(45deg, transparent 75%, @cell-color 75%), + linear-gradient(-45deg, transparent 75%, @cell-color 75%); + background-size: @cell-size @cell-size; + background-position: 0 0, 0 @cell-size/2, @cell-size/2 -@cell-size/2, -@cell-size/2 0px; + + &:before { + content: ""; + display: block; + padding-top: ~"calc(100% - 2px)"; + background-color: inherit; + border: 1px solid rgba(0, 0, 0, 0.1); + border-radius: 2px; + overflow: hidden; + } +} diff --git a/redash-visualizations/src/components/ColorPicker/utils.js b/redash-visualizations/src/components/ColorPicker/utils.js new file mode 100644 index 0000000000..1af3670437 --- /dev/null +++ b/redash-visualizations/src/components/ColorPicker/utils.js @@ -0,0 +1,14 @@ +import { isArray, findKey } from "lodash"; +import tinycolor from "tinycolor2"; + +export function validateColor(value, fallback = null) { + value = tinycolor(value); + return value.isValid() ? "#" + value.toHex().toUpperCase() : fallback; +} + +export function getColorName(color, presetColors) { + if (isArray(presetColors)) { + return color; + } + return findKey(presetColors, v => validateColor(v) === color) || color; +} diff --git a/redash-visualizations/src/components/DynamicComponent.jsx b/redash-visualizations/src/components/DynamicComponent.jsx new file mode 100644 index 0000000000..98e2d78c28 --- /dev/null +++ b/redash-visualizations/src/components/DynamicComponent.jsx @@ -0,0 +1,50 @@ +import { isFunction, isString } from "lodash"; +import React from "react"; +import PropTypes from "prop-types"; + +const componentsRegistry = new Map(); +const activeInstances = new Set(); + +export function registerComponent(name, component) { + if (isString(name) && name !== "") { + componentsRegistry.set(name, isFunction(component) ? component : null); + // Refresh active DynamicComponent instances which use this component + activeInstances.forEach(dynamicComponent => { + if (dynamicComponent.props.name === name) { + dynamicComponent.forceUpdate(); + } + }); + } +} + +export function unregisterComponent(name) { + registerComponent(name, null); +} + +export default class DynamicComponent extends React.Component { + static propTypes = { + name: PropTypes.string.isRequired, + children: PropTypes.node, + }; + + static defaultProps = { + children: null, + }; + + componentDidMount() { + activeInstances.add(this); + } + + componentWillUnmount() { + activeInstances.delete(this); + } + + render() { + const { name, children, ...props } = this.props; + const RealComponent = componentsRegistry.get(name); + if (!RealComponent) { + return children; + } + return {children}; + } +} diff --git a/redash-visualizations/src/components/visualizations/editor/ContextHelp.jsx b/redash-visualizations/src/components/visualizations/editor/ContextHelp.jsx new file mode 100644 index 0000000000..32196cddef --- /dev/null +++ b/redash-visualizations/src/components/visualizations/editor/ContextHelp.jsx @@ -0,0 +1,59 @@ +import React from "react"; +import PropTypes from "prop-types"; +import Popover from "antd/lib/popover"; +import Tooltip from "antd/lib/tooltip"; +import Icon from "antd/lib/icon"; +import HelpTrigger from "@/components/HelpTrigger"; + +import "./context-help.less"; + +export default function ContextHelp({ icon, children, ...props }) { + return ( + + {icon || ContextHelp.defaultIcon} + + ); +} + +ContextHelp.propTypes = { + icon: PropTypes.node, + children: PropTypes.node, +}; + +ContextHelp.defaultProps = { + icon: null, + children: null, +}; + +ContextHelp.defaultIcon = ; + +function NumberFormatSpecs() { + return ( + + {ContextHelp.defaultIcon} + + ); +} + +function DateTimeFormatSpecs() { + return ( + + Formatting Dates and Times + + + }> + + {ContextHelp.defaultIcon} + + + ); +} + +ContextHelp.NumberFormatSpecs = NumberFormatSpecs; +ContextHelp.DateTimeFormatSpecs = DateTimeFormatSpecs; diff --git a/redash-visualizations/src/components/visualizations/editor/Section.jsx b/redash-visualizations/src/components/visualizations/editor/Section.jsx new file mode 100644 index 0000000000..8784ee7ba3 --- /dev/null +++ b/redash-visualizations/src/components/visualizations/editor/Section.jsx @@ -0,0 +1,45 @@ +import React from "react"; +import PropTypes from "prop-types"; +import cx from "classnames"; + +function SectionTitle({ className, children, ...props }) { + if (!children) { + return null; + } + + return ( +

+ {children} +

+ ); +} + +SectionTitle.propTypes = { + className: PropTypes.string, + children: PropTypes.node, +}; + +SectionTitle.defaultProps = { + className: null, + children: null, +}; + +export default function Section({ className, children, ...props }) { + return ( +
+ {children} +
+ ); +} + +Section.propTypes = { + className: PropTypes.string, + children: PropTypes.node, +}; + +Section.defaultProps = { + className: null, + children: null, +}; + +Section.Title = SectionTitle; diff --git a/redash-visualizations/src/components/visualizations/editor/Switch.jsx b/redash-visualizations/src/components/visualizations/editor/Switch.jsx new file mode 100644 index 0000000000..0f27803328 --- /dev/null +++ b/redash-visualizations/src/components/visualizations/editor/Switch.jsx @@ -0,0 +1,40 @@ +import React, { useMemo } from "react"; +import PropTypes from "prop-types"; +import AntSwitch from "antd/lib/switch"; +import Typography from "antd/lib/typography"; + +export default function Switch({ id, children, disabled, ...props }) { + const fallbackId = useMemo( + () => + `visualization-editor-control-${Math.random() + .toString(36) + .substr(2, 10)}`, + [] + ); + id = id || fallbackId; + + if (children) { + return ( + + ); + } + + return ; +} + +Switch.propTypes = { + id: PropTypes.string, + disabled: PropTypes.bool, + children: PropTypes.node, +}; + +Switch.defaultProps = { + id: null, + disabled: false, + children: null, +}; diff --git a/redash-visualizations/src/components/visualizations/editor/context-help.less b/redash-visualizations/src/components/visualizations/editor/context-help.less new file mode 100644 index 0000000000..287267fbba --- /dev/null +++ b/redash-visualizations/src/components/visualizations/editor/context-help.less @@ -0,0 +1,12 @@ +@import (reference, less) '~@/assets/less/main.less'; + +a.visualization-editor-context-help { + &, .ant-typography & { + font: inherit; + color: inherit; + + &:hover, &:active { + color: @link-hover-color; + } + } +} diff --git a/redash-visualizations/src/components/visualizations/editor/control-label.less b/redash-visualizations/src/components/visualizations/editor/control-label.less new file mode 100644 index 0000000000..acb2f79757 --- /dev/null +++ b/redash-visualizations/src/components/visualizations/editor/control-label.less @@ -0,0 +1,7 @@ +.visualization-editor-control-label { + &.visualization-editor-control-label-horizontal { + label { + margin-bottom: 0; + } + } +} diff --git a/redash-visualizations/src/components/visualizations/editor/createTabbedEditor.jsx b/redash-visualizations/src/components/visualizations/editor/createTabbedEditor.jsx new file mode 100644 index 0000000000..62f767d437 --- /dev/null +++ b/redash-visualizations/src/components/visualizations/editor/createTabbedEditor.jsx @@ -0,0 +1,51 @@ +import { isFunction, map, filter, extend, merge } from "lodash"; +import React from "react"; +import PropTypes from "prop-types"; +import Tabs from "antd/lib/tabs"; +import { EditorPropTypes } from "@/visualizations/prop-types"; + +export const UpdateOptionsStrategy = { + replace: (existingOptions, newOptions) => merge({}, newOptions), + shallowMerge: (existingOptions, newOptions) => extend({}, existingOptions, newOptions), + deepMerge: (existingOptions, newOptions) => merge({}, existingOptions, newOptions), +}; + +export function TabbedEditor({ tabs, options, data, onOptionsChange, ...restProps }) { + const optionsChanged = (newOptions, updateStrategy = UpdateOptionsStrategy.deepMerge) => { + onOptionsChange(updateStrategy(options, newOptions)); + }; + + tabs = filter(tabs, tab => (isFunction(tab.isAvailable) ? tab.isAvailable(options, data) : true)); + + return ( + + {map(tabs, ({ key, title, component: Component }) => ( + {title}
}> + + + ))} + + ); +} + +TabbedEditor.propTypes = { + ...EditorPropTypes, + tabs: PropTypes.arrayOf( + PropTypes.shape({ + key: PropTypes.string.isRequired, + title: PropTypes.string.isRequired, + isAvailable: PropTypes.func, // (options) => boolean + component: PropTypes.func.isRequired, + }) + ), +}; + +TabbedEditor.defaultProps = { + tabs: [], +}; + +export default function createTabbedEditor(tabs) { + return function TabbedEditorWrapper(props) { + return ; + }; +} diff --git a/redash-visualizations/src/components/visualizations/editor/index.js b/redash-visualizations/src/components/visualizations/editor/index.js new file mode 100644 index 0000000000..07e81411a0 --- /dev/null +++ b/redash-visualizations/src/components/visualizations/editor/index.js @@ -0,0 +1,21 @@ +import AntSelect from "antd/lib/select"; +import AntInput from "antd/lib/input"; +import AntInputNumber from "antd/lib/input-number"; +import Checkbox from "antd/lib/checkbox"; + +import RedashColorPicker from "@/components/ColorPicker"; +import RedashTextAlignmentSelect from "@/components/TextAlignmentSelect"; + +import withControlLabel, { ControlLabel } from "./withControlLabel"; +import createTabbedEditor from "./createTabbedEditor"; +import Section from "./Section"; +import Switch from "./Switch"; +import ContextHelp from "./ContextHelp"; + +export { Section, ControlLabel, Checkbox, Switch, ContextHelp, withControlLabel, createTabbedEditor }; +export const Select = withControlLabel(AntSelect); +export const Input = withControlLabel(AntInput); +export const TextArea = withControlLabel(AntInput.TextArea); +export const InputNumber = withControlLabel(AntInputNumber); +export const ColorPicker = withControlLabel(RedashColorPicker); +export const TextAlignmentSelect = withControlLabel(RedashTextAlignmentSelect); diff --git a/redash-visualizations/src/components/visualizations/editor/withControlLabel.jsx b/redash-visualizations/src/components/visualizations/editor/withControlLabel.jsx new file mode 100644 index 0000000000..15edaba37d --- /dev/null +++ b/redash-visualizations/src/components/visualizations/editor/withControlLabel.jsx @@ -0,0 +1,82 @@ +import React, { useMemo } from "react"; +import PropTypes from "prop-types"; +import hoistNonReactStatics from "hoist-non-react-statics"; +import * as Grid from "antd/lib/grid"; +import Typography from "antd/lib/typography"; + +import "./control-label.less"; + +export function ControlLabel({ layout, label, labelProps, disabled, children }) { + if (layout === "vertical" && label) { + return ( +
+ + {children} +
+ ); + } + + if (layout === "horizontal" && label) { + return ( + + + + + {children} + + ); + } + + return children; +} + +ControlLabel.propTypes = { + layout: PropTypes.oneOf(["vertical", "horizontal"]), + label: PropTypes.node, + labelProps: PropTypes.object, // eslint-disable-line react/forbid-prop-types + disabled: PropTypes.bool, + children: PropTypes.node, +}; + +ControlLabel.defaultProps = { + layout: "vertical", + label: null, + disabled: false, + children: null, +}; + +export default function withControlLabel(WrappedControl) { + // eslint-disable-next-line react/prop-types + function ControlWrapper({ id, layout, label, labelProps, disabled, ...props }) { + const fallbackId = useMemo( + () => + `visualization-editor-control-${Math.random() + .toString(36) + .substr(2, 10)}`, + [] + ); + labelProps = { + ...labelProps, + htmlFor: id || fallbackId, + }; + + return ( + + + + ); + } + + // Copy static methods from `WrappedComponent` + hoistNonReactStatics(ControlWrapper, WrappedControl); + + return ControlWrapper; +} diff --git a/redash-visualizations/src/index.js b/redash-visualizations/src/index.js new file mode 100644 index 0000000000..275e3c5a4c --- /dev/null +++ b/redash-visualizations/src/index.js @@ -0,0 +1,3 @@ +import TestRenderer from "./visualizations/components/TestRenderer"; + +export { TestRenderer }; diff --git a/redash-visualizations/src/lib/chooseTextColorForBackground.js b/redash-visualizations/src/lib/chooseTextColorForBackground.js new file mode 100644 index 0000000000..dd84870f28 --- /dev/null +++ b/redash-visualizations/src/lib/chooseTextColorForBackground.js @@ -0,0 +1,11 @@ +import { maxBy } from "lodash"; +import chroma from "chroma-js"; + +export default function chooseTextColorForBackground(backgroundColor, textColors = ["#ffffff", "#333333"]) { + try { + backgroundColor = chroma(backgroundColor); + return maxBy(textColors, color => chroma.contrast(backgroundColor, color)); + } catch (e) { + return null; + } +} diff --git a/redash-visualizations/src/services/resizeObserver.js b/redash-visualizations/src/services/resizeObserver.js new file mode 100644 index 0000000000..c27b3bbae2 --- /dev/null +++ b/redash-visualizations/src/services/resizeObserver.js @@ -0,0 +1,32 @@ +const items = new Map(); + +function checkItems() { + if (items.size > 0) { + items.forEach((item, node) => { + const bounds = node.getBoundingClientRect(); + // convert to int (because these numbers needed for comparisons), but preserve 1 decimal point + const width = Math.round(bounds.width * 10); + const height = Math.round(bounds.height * 10); + + if (item.width !== width || item.height !== height) { + item.width = width; + item.height = height; + item.callback(node); + } + }); + + setTimeout(checkItems, 100); + } +} + +export default function observe(node, callback) { + if (node && !items.has(node)) { + const shouldTrigger = items.size === 0; + items.set(node, { callback }); + if (shouldTrigger) { + checkItems(); + } + return () => items.delete(node); + } + return () => {}; +} diff --git a/redash-visualizations/src/visualizations/ColorPalette.js b/redash-visualizations/src/visualizations/ColorPalette.js new file mode 100644 index 0000000000..3663a68218 --- /dev/null +++ b/redash-visualizations/src/visualizations/ColorPalette.js @@ -0,0 +1,38 @@ +import { values } from "lodash"; + +// The following colors will be used if you pick "Automatic" color +export const BaseColors = { + Blue: "#356AFF", + Red: "#E92828", + Green: "#3BD973", + Purple: "#604FE9", + Cyan: "#50F5ED", + Orange: "#FB8D3D", + "Light Blue": "#799CFF", + Lilac: "#B554FF", + "Light Green": "#8CFFB4", + Brown: "#A55F2A", + Black: "#000000", + Gray: "#494949", + Pink: "#FF7DE3", + "Dark Blue": "#002FB4", +}; + +// Additional colors for the user to choose from +export const AdditionalColors = { + "Indian Red": "#981717", + "Green 2": "#17BF51", + "Green 3": "#049235", + "Dark Turquoise": "#00B6EB", + "Dark Violet": "#A58AFF", + "Pink 2": "#C63FA9", +}; + +export const ColorPaletteArray = values(BaseColors); + +const ColorPalette = { + ...BaseColors, + ...AdditionalColors, +}; + +export default ColorPalette; diff --git a/redash-visualizations/src/visualizations/box-plot/Editor.jsx b/redash-visualizations/src/visualizations/box-plot/Editor.jsx new file mode 100644 index 0000000000..02155a84c8 --- /dev/null +++ b/redash-visualizations/src/visualizations/box-plot/Editor.jsx @@ -0,0 +1,39 @@ +import React from "react"; +import { Section, Input } from "@/components/visualizations/editor"; +import { EditorPropTypes } from "@/visualizations/prop-types"; + +export default function Editor({ options, onOptionsChange }) { + const onXAxisLabelChanged = xAxisLabel => { + const newOptions = { ...options, xAxisLabel }; + onOptionsChange(newOptions); + }; + + const onYAxisLabelChanged = yAxisLabel => { + const newOptions = { ...options, yAxisLabel }; + onOptionsChange(newOptions); + }; + + return ( + +
+ onXAxisLabelChanged(event.target.value)} + /> +
+ +
+ onYAxisLabelChanged(event.target.value)} + /> +
+
+ ); +} + +Editor.propTypes = EditorPropTypes; diff --git a/redash-visualizations/src/visualizations/box-plot/Renderer.jsx b/redash-visualizations/src/visualizations/box-plot/Renderer.jsx new file mode 100644 index 0000000000..f6343a8fb2 --- /dev/null +++ b/redash-visualizations/src/visualizations/box-plot/Renderer.jsx @@ -0,0 +1,197 @@ +import { map, each } from "lodash"; +import d3 from "d3"; +import React, { useState, useEffect } from "react"; +import resizeObserver from "@/services/resizeObserver"; +import { RendererPropTypes } from "@/visualizations/prop-types"; +import box from "./d3box"; +import "./renderer.less"; + +function calcIqr(k) { + return d => { + const q1 = d.quartiles[0]; + const q3 = d.quartiles[2]; + const iqr = (q3 - q1) * k; + + let i = -1; + let j = d.length; + + i += 1; + while (d[i] < q1 - iqr) { + i += 1; + } + + j -= 1; + while (d[j] > q3 + iqr) { + j -= 1; + } + + return [i, j]; + }; +} + +function render(container, data, { xAxisLabel, yAxisLabel }) { + container = d3.select(container); + + const containerBounds = container.node().getBoundingClientRect(); + const containerWidth = Math.floor(containerBounds.width); + const containerHeight = Math.floor(containerBounds.height); + + const margin = { + top: 10, + right: 50, + bottom: 40, + left: 50, + inner: 25, + }; + const width = containerWidth - margin.right - margin.left; + const height = containerHeight - margin.top - margin.bottom; + + let min = Infinity; + let max = -Infinity; + const mydata = []; + let value = 0; + let d = []; + + const columns = map(data.columns, col => col.name); + const xscale = d3.scale + .ordinal() + .domain(columns) + .rangeBands([0, containerWidth - margin.left - margin.right]); + + let boxWidth; + if (columns.length > 1) { + boxWidth = Math.min(xscale(columns[1]), 120.0); + } else { + boxWidth = 120.0; + } + margin.inner = boxWidth / 3.0; + + each(columns, (column, i) => { + d = mydata[i] = []; + each(data.rows, row => { + value = row[column]; + d.push(value); + if (value > max) max = Math.ceil(value); + if (value < min) min = Math.floor(value); + }); + }); + + const yscale = d3.scale + .linear() + .domain([min * 0.99, max * 1.01]) + .range([height, 0]); + + const chart = box() + .whiskers(calcIqr(1.5)) + .width(boxWidth - 2 * margin.inner) + .height(height) + .domain([min * 0.99, max * 1.01]); + const xAxis = d3.svg + .axis() + .scale(xscale) + .orient("bottom"); + + const yAxis = d3.svg + .axis() + .scale(yscale) + .orient("left"); + + const xLines = d3.svg + .axis() + .scale(xscale) + .tickSize(height) + .orient("bottom"); + + const yLines = d3.svg + .axis() + .scale(yscale) + .tickSize(width) + .orient("right"); + + function barOffset(i) { + return xscale(columns[i]) + (xscale(columns[1]) - margin.inner) / 2.0; + } + + container.selectAll("*").remove(); + + const svg = container + .append("svg") + .attr("width", containerWidth) + .attr("height", height + margin.bottom + margin.top); + + const plot = svg + .append("g") + .attr("width", containerWidth - margin.left - margin.right) + .attr("transform", `translate(${margin.left},${margin.top})`); + + svg + .append("text") + .attr("class", "box") + .attr("x", containerWidth / 2.0) + .attr("text-anchor", "middle") + .attr("y", height + margin.bottom) + .text(xAxisLabel); + + svg + .append("text") + .attr("class", "box") + .attr("transform", `translate(10,${(height + margin.top + margin.bottom) / 2.0})rotate(-90)`) + .attr("text-anchor", "middle") + .text(yAxisLabel); + + plot + .append("rect") + .attr("class", "grid-background") + .attr("width", width) + .attr("height", height); + + plot + .append("g") + .attr("class", "grid") + .call(yLines); + + plot + .append("g") + .attr("class", "grid") + .call(xLines); + + plot + .append("g") + .attr("class", "x axis") + .attr("transform", `translate(0,${height})`) + .call(xAxis); + + plot + .append("g") + .attr("class", "y axis") + .call(yAxis); + + plot + .selectAll(".box") + .data(mydata) + .enter() + .append("g") + .attr("class", "box") + .attr("width", boxWidth) + .attr("height", height) + .attr("transform", (_, i) => `translate(${barOffset(i)},${0})`) + .call(chart); +} + +export default function Renderer({ data, options }) { + const [container, setContainer] = useState(null); + + useEffect(() => { + if (container) { + render(container, data, options); + const unwatch = resizeObserver(container, () => { + render(container, data, options); + }); + return unwatch; + } + }, [container, data, options]); + + return
; +} + +Renderer.propTypes = RendererPropTypes; diff --git a/redash-visualizations/src/visualizations/box-plot/d3box.js b/redash-visualizations/src/visualizations/box-plot/d3box.js new file mode 100644 index 0000000000..41a27b9ea9 --- /dev/null +++ b/redash-visualizations/src/visualizations/box-plot/d3box.js @@ -0,0 +1,328 @@ +/* eslint-disable */ +// Inspired by http://informationandvisualization.de/blog/box-plot +function box() { + let width = 1, + height = 1, + duration = 0, + domain = null, + value = Number, + whiskers = boxWhiskers, + quartiles = boxQuartiles, + tickFormat = null; + + // For each small multiple… + function box(g) { + g.each(function(d, i) { + d = d.map(value).sort(d3.ascending); + let g = d3.select(this), + n = d.length, + min = d[0], + max = d[n - 1]; + + // Compute quartiles. Must return exactly 3 elements. + const quartileData = (d.quartiles = quartiles(d)); + + // Compute whiskers. Must return exactly 2 elements, or null. + let whiskerIndices = whiskers && whiskers.call(this, d, i), + whiskerData = whiskerIndices && whiskerIndices.map(i => d[i]); + + // Compute outliers. If no whiskers are specified, all data are "outliers". + // We compute the outliers as indices, so that we can join across transitions! + const outlierIndices = whiskerIndices + ? d3.range(0, whiskerIndices[0]).concat(d3.range(whiskerIndices[1] + 1, n)) + : d3.range(n); + + // Compute the new x-scale. + const x1 = d3.scale + .linear() + .domain((domain && domain.call(this, d, i)) || [min, max]) + .range([height, 0]); + + // Retrieve the old x-scale, if this is an update. + const x0 = + this.__chart__ || + d3.scale + .linear() + .domain([0, Infinity]) + .range(x1.range()); + + // Stash the new scale. + this.__chart__ = x1; + + // Note: the box, median, and box tick elements are fixed in number, + // so we only have to handle enter and update. In contrast, the outliers + // and other elements are variable, so we need to exit them! Variable + // elements also fade in and out. + + // Update center line: the vertical line spanning the whiskers. + const center = g.selectAll("line.center").data(whiskerData ? [whiskerData] : []); + + center + .enter() + .insert("line", "rect") + .attr("class", "center") + .attr("x1", width / 2) + .attr("y1", d => x0(d[0])) + .attr("x2", width / 2) + .attr("y2", d => x0(d[1])) + .style("opacity", 1e-6) + .transition() + .duration(duration) + .style("opacity", 1) + .attr("y1", d => x1(d[0])) + .attr("y2", d => x1(d[1])); + + center + .transition() + .duration(duration) + .style("opacity", 1) + .attr("y1", d => x1(d[0])) + .attr("y2", d => x1(d[1])); + + center + .exit() + .transition() + .duration(duration) + .style("opacity", 1e-6) + .attr("y1", d => x1(d[0])) + .attr("y2", d => x1(d[1])) + .remove(); + + // Update innerquartile box. + const box = g.selectAll("rect.box").data([quartileData]); + + box + .enter() + .append("rect") + .attr("class", "box") + .attr("x", 0) + .attr("y", d => x0(d[2])) + .attr("width", width) + .attr("height", d => x0(d[0]) - x0(d[2])) + .transition() + .duration(duration) + .attr("y", d => x1(d[2])) + .attr("height", d => x1(d[0]) - x1(d[2])); + + box + .transition() + .duration(duration) + .attr("y", d => x1(d[2])) + .attr("height", d => x1(d[0]) - x1(d[2])); + + box.exit().remove(); + + // Update median line. + const medianLine = g.selectAll("line.median").data([quartileData[1]]); + + medianLine + .enter() + .append("line") + .attr("class", "median") + .attr("x1", 0) + .attr("y1", x0) + .attr("x2", width) + .attr("y2", x0) + .transition() + .duration(duration) + .attr("y1", x1) + .attr("y2", x1); + + medianLine + .transition() + .duration(duration) + .attr("y1", x1) + .attr("y2", x1); + + medianLine.exit().remove(); + + // Update whiskers. + const whisker = g.selectAll("line.whisker").data(whiskerData || []); + + whisker + .enter() + .insert("line", "circle, text") + .attr("class", "whisker") + .attr("x1", 0) + .attr("y1", x0) + .attr("x2", width) + .attr("y2", x0) + .style("opacity", 1e-6) + .transition() + .duration(duration) + .attr("y1", x1) + .attr("y2", x1) + .style("opacity", 1); + + whisker + .transition() + .duration(duration) + .attr("y1", x1) + .attr("y2", x1) + .style("opacity", 1); + + whisker + .exit() + .transition() + .duration(duration) + .attr("y1", x1) + .attr("y2", x1) + .style("opacity", 1e-6) + .remove(); + + // Update outliers. + const outlier = g.selectAll("circle.outlier").data(outlierIndices, Number); + + outlier + .enter() + .insert("circle", "text") + .attr("class", "outlier") + .attr("r", 5) + .attr("cx", width / 2) + .attr("cy", i => x0(d[i])) + .style("opacity", 1e-6) + .transition() + .duration(duration) + .attr("cy", i => x1(d[i])) + .style("opacity", 1); + + outlier + .transition() + .duration(duration) + .attr("cy", i => x1(d[i])) + .style("opacity", 1); + + outlier + .exit() + .transition() + .duration(duration) + .attr("cy", i => x1(d[i])) + .style("opacity", 1e-6) + .remove(); + + // Compute the tick format. + const format = tickFormat || x1.tickFormat(8); + + // Update box ticks. + const boxTick = g.selectAll("text.box").data(quartileData); + + boxTick + .enter() + .append("text") + .attr("class", "box") + .attr("dy", ".3em") + .attr("dx", (d, i) => (i & 1 ? 6 : -6)) + .attr("x", (d, i) => (i & 1 ? width : 0)) + .attr("y", x0) + .attr("text-anchor", (d, i) => (i & 1 ? "start" : "end")) + .text(format) + .transition() + .duration(duration) + .attr("y", x1); + + boxTick + .transition() + .duration(duration) + .text(format) + .attr("y", x1); + + boxTick.exit().remove(); + + // Update whisker ticks. These are handled separately from the box + // ticks because they may or may not exist, and we want don't want + // to join box ticks pre-transition with whisker ticks post-. + const whiskerTick = g.selectAll("text.whisker").data(whiskerData || []); + + whiskerTick + .enter() + .append("text") + .attr("class", "whisker") + .attr("dy", ".3em") + .attr("dx", 6) + .attr("x", width) + .attr("y", x0) + .text(format) + .style("opacity", 1e-6) + .transition() + .duration(duration) + .attr("y", x1) + .style("opacity", 1); + + whiskerTick + .transition() + .duration(duration) + .text(format) + .attr("y", x1) + .style("opacity", 1); + + whiskerTick + .exit() + .transition() + .duration(duration) + .attr("y", x1) + .style("opacity", 1e-6) + .remove(); + }); + d3.timer.flush(); + } + + box.width = function(x) { + if (!arguments.length) return width; + width = x; + return box; + }; + + box.height = function(x) { + if (!arguments.length) return height; + height = x; + return box; + }; + + box.tickFormat = function(x) { + if (!arguments.length) return tickFormat; + tickFormat = x; + return box; + }; + + box.duration = function(x) { + if (!arguments.length) return duration; + duration = x; + return box; + }; + + box.domain = function(x) { + if (!arguments.length) return domain; + domain = x == null ? x : d3.functor(x); + return box; + }; + + box.value = function(x) { + if (!arguments.length) return value; + value = x; + return box; + }; + + box.whiskers = function(x) { + if (!arguments.length) return whiskers; + whiskers = x; + return box; + }; + + box.quartiles = function(x) { + if (!arguments.length) return quartiles; + quartiles = x; + return box; + }; + + return box; +} + +function boxWhiskers(d) { + return [0, d.length - 1]; +} + +function boxQuartiles(d) { + return [d3.quantile(d, 0.25), d3.quantile(d, 0.5), d3.quantile(d, 0.75)]; +} + +export default box; diff --git a/redash-visualizations/src/visualizations/box-plot/index.js b/redash-visualizations/src/visualizations/box-plot/index.js new file mode 100644 index 0000000000..d65e24f081 --- /dev/null +++ b/redash-visualizations/src/visualizations/box-plot/index.js @@ -0,0 +1,14 @@ +import Renderer from "./Renderer"; +import Editor from "./Editor"; + +export default { + type: "BOXPLOT", + name: "Boxplot (Deprecated)", + isDeprecated: true, + getOptions: options => ({ ...options }), + Renderer, + Editor, + + defaultRows: 8, + minRows: 5, +}; diff --git a/redash-visualizations/src/visualizations/box-plot/renderer.less b/redash-visualizations/src/visualizations/box-plot/renderer.less new file mode 100644 index 0000000000..385ca7b48d --- /dev/null +++ b/redash-visualizations/src/visualizations/box-plot/renderer.less @@ -0,0 +1,4 @@ +.box-plot-deprecated-visualization-container { + overflow: hidden; + height: 500px; +} diff --git a/redash-visualizations/src/visualizations/chart/Editor/AxisSettings.jsx b/redash-visualizations/src/visualizations/chart/Editor/AxisSettings.jsx new file mode 100644 index 0000000000..ea266a9b49 --- /dev/null +++ b/redash-visualizations/src/visualizations/chart/Editor/AxisSettings.jsx @@ -0,0 +1,113 @@ +import { isString, isObject, isFinite, isNumber, merge } from "lodash"; +import React from "react"; +import PropTypes from "prop-types"; +import { useDebouncedCallback } from "use-debounce"; +import * as Grid from "antd/lib/grid"; +import { Section, Select, Input, InputNumber } from "@/components/visualizations/editor"; + +function toNumber(value) { + value = isNumber(value) ? value : parseFloat(value); + return isFinite(value) ? value : null; +} + +export default function AxisSettings({ id, options, features, onChange }) { + function optionsChanged(newOptions) { + onChange(merge({}, options, newOptions)); + } + + const [handleNameChange] = useDebouncedCallback(text => { + const title = isString(text) && text !== "" ? { text } : null; + optionsChanged({ title }); + }, 200); + + const [handleMinMaxChange] = useDebouncedCallback(opts => optionsChanged(opts), 200); + + return ( + +
+ +
+ +
+ handleNameChange(event.target.value)} + /> +
+ + {features.range && ( +
+ + + handleMinMaxChange({ rangeMin: toNumber(value) })} + /> + + + handleMinMaxChange({ rangeMax: toNumber(value) })} + /> + + +
+ )} +
+ ); +} + +AxisSettings.propTypes = { + id: PropTypes.string.isRequired, + options: PropTypes.shape({ + type: PropTypes.string.isRequired, + title: PropTypes.shape({ + text: PropTypes.string, + }), + rangeMin: PropTypes.number, + rangeMax: PropTypes.number, + }).isRequired, + features: PropTypes.shape({ + autoDetectType: PropTypes.bool, + range: PropTypes.bool, + }), + onChange: PropTypes.func, +}; + +AxisSettings.defaultProps = { + features: {}, + onChange: () => {}, +}; diff --git a/redash-visualizations/src/visualizations/chart/Editor/ChartTypeSelect.jsx b/redash-visualizations/src/visualizations/chart/Editor/ChartTypeSelect.jsx new file mode 100644 index 0000000000..b4dc589643 --- /dev/null +++ b/redash-visualizations/src/visualizations/chart/Editor/ChartTypeSelect.jsx @@ -0,0 +1,36 @@ +import { map } from "lodash"; +import React, { useMemo } from "react"; +import { Select } from "@/components/visualizations/editor"; +import { clientConfig } from "@/services/auth"; + +export default function ChartTypeSelect(props) { + const chartTypes = useMemo(() => { + const result = [ + { type: "line", name: "Line", icon: "line-chart" }, + { type: "column", name: "Bar", icon: "bar-chart" }, + { type: "area", name: "Area", icon: "area-chart" }, + { type: "pie", name: "Pie", icon: "pie-chart" }, + { type: "scatter", name: "Scatter", icon: "circle-o" }, + { type: "bubble", name: "Bubble", icon: "circle-o" }, + { type: "heatmap", name: "Heatmap", icon: "th" }, + { type: "box", name: "Box", icon: "square-o" }, + ]; + + if (clientConfig.allowCustomJSVisualizations) { + result.push({ type: "custom", name: "Custom", icon: "code" }); + } + + return result; + }, []); + + return ( + + ); +} diff --git a/redash-visualizations/src/visualizations/chart/Editor/ColorsSettings.jsx b/redash-visualizations/src/visualizations/chart/Editor/ColorsSettings.jsx new file mode 100644 index 0000000000..0a1d3e36cb --- /dev/null +++ b/redash-visualizations/src/visualizations/chart/Editor/ColorsSettings.jsx @@ -0,0 +1,18 @@ +import React from "react"; +import { EditorPropTypes } from "@/visualizations/prop-types"; + +import PieColorsSettings from "./PieColorsSettings"; +import HeatmapColorsSettings from "./HeatmapColorsSettings"; +import DefaultColorsSettings from "./DefaultColorsSettings"; + +const components = { + pie: PieColorsSettings, + heatmap: HeatmapColorsSettings, +}; + +export default function ColorsSettings({ options, ...props }) { + const Component = components[options.globalSeriesType] || DefaultColorsSettings; + return ; +} + +ColorsSettings.propTypes = EditorPropTypes; diff --git a/redash-visualizations/src/visualizations/chart/Editor/ColorsSettings.test.js b/redash-visualizations/src/visualizations/chart/Editor/ColorsSettings.test.js new file mode 100644 index 0000000000..b09f2a733a --- /dev/null +++ b/redash-visualizations/src/visualizations/chart/Editor/ColorsSettings.test.js @@ -0,0 +1,124 @@ +import { after } from "lodash"; +import React from "react"; +import enzyme from "enzyme"; + +import getOptions from "../getOptions"; +import ColorsSettings from "./ColorsSettings"; + +function findByTestID(wrapper, testId) { + return wrapper.find(`[data-test="${testId}"]`); +} + +function mount(options, done) { + options = getOptions(options); + return enzyme.mount( + { + expect(changedOptions).toMatchSnapshot(); + done(); + }} + /> + ); +} + +describe("Visualizations -> Chart -> Editor -> Colors Settings", () => { + describe("for pie", () => { + test("Changes series color", done => { + const el = mount( + { + globalSeriesType: "pie", + columnMapping: { a: "x", b: "y" }, + }, + done + ); + + findByTestID(el, "Chart.Series.v.Color") + .find(".color-picker-trigger") + .last() + .simulate("click"); + findByTestID(el, "ColorPicker") + .last() + .find("input") + .simulate("change", { target: { value: "red" } }); + }); + }); + + describe("for heatmap", () => { + test("Changes color scheme", done => { + const el = mount( + { + globalSeriesType: "heatmap", + columnMapping: { a: "x", b: "y" }, + }, + done + ); + + findByTestID(el, "Chart.Colors.Heatmap.ColorScheme") + .last() + .simulate("click"); + findByTestID(el, "Chart.Colors.Heatmap.ColorScheme.RdBu") + .last() + .simulate("click"); + }); + + test("Sets custom color scheme", async done => { + const el = mount( + { + globalSeriesType: "heatmap", + columnMapping: { a: "x", b: "y" }, + colorScheme: "Custom...", + }, + after(2, done) + ); // we will perform 2 actions, so call `done` after all of them completed + + findByTestID(el, "Chart.Colors.Heatmap.MinColor") + .find(".color-picker-trigger") + .last() + .simulate("click"); + findByTestID(el, "ColorPicker") + .last() + .find("input") + .simulate("change", { target: { value: "yellow" } }); + + findByTestID(el, "Chart.Colors.Heatmap.MaxColor") + .find(".color-picker-trigger") + .last() + .simulate("click"); + findByTestID(el, "ColorPicker") + .last() + .find("input") + .simulate("change", { target: { value: "red" } }); + }); + }); + + describe("for all except of pie and heatmap", () => { + test("Changes series color", done => { + const el = mount( + { + globalSeriesType: "column", + columnMapping: { a: "x", b: "y" }, + }, + done + ); + + findByTestID(el, "Chart.Series.b.Color") + .find(".color-picker-trigger") + .last() + .simulate("click"); + + findByTestID(el, "ColorPicker") + .last() + .find("input") + .simulate("change", { target: { value: "red" } }); + }); + }); +}); diff --git a/redash-visualizations/src/visualizations/chart/Editor/ColumnMappingSelect.jsx b/redash-visualizations/src/visualizations/chart/Editor/ColumnMappingSelect.jsx new file mode 100644 index 0000000000..46df03979c --- /dev/null +++ b/redash-visualizations/src/visualizations/chart/Editor/ColumnMappingSelect.jsx @@ -0,0 +1,55 @@ +import { isString, map, uniq, flatten, filter, sortBy, keys } from "lodash"; +import React from "react"; +import PropTypes from "prop-types"; +import { Section, Select } from "@/components/visualizations/editor"; + +const MappingTypes = { + x: { label: "X Column" }, + y: { label: "Y Columns", multiple: true }, + series: { label: "Group by" }, + yError: { label: "Errors column" }, + size: { label: "Bubble Size Column" }, + zVal: { label: "Color Column" }, +}; + +export default function ColumnMappingSelect({ value, availableColumns, type, onChange }) { + const options = sortBy(filter(uniq(flatten([availableColumns, value])), v => isString(v) && v !== "")); + const { label, multiple } = MappingTypes[type]; + + return ( +
+ +
+ ); +} + +ColumnMappingSelect.propTypes = { + value: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]), + availableColumns: PropTypes.arrayOf(PropTypes.string), + type: PropTypes.oneOf(keys(MappingTypes)), + onChange: PropTypes.func, +}; + +ColumnMappingSelect.defaultProps = { + value: null, + availableColumns: [], + type: null, + onChange: () => {}, +}; + +ColumnMappingSelect.MappingTypes = MappingTypes; diff --git a/redash-visualizations/src/visualizations/chart/Editor/CustomChartSettings.jsx b/redash-visualizations/src/visualizations/chart/Editor/CustomChartSettings.jsx new file mode 100644 index 0000000000..fddff413e8 --- /dev/null +++ b/redash-visualizations/src/visualizations/chart/Editor/CustomChartSettings.jsx @@ -0,0 +1,49 @@ +import { isNil, trimStart } from "lodash"; +import React from "react"; +import { Section, Switch, TextArea } from "@/components/visualizations/editor"; +import { EditorPropTypes } from "@/visualizations/prop-types"; + +const defaultCustomCode = trimStart(` +// Available variables are x, ys, element, and Plotly +// Type console.log(x, ys); for more info about x and ys +// To plot your graph call Plotly.plot(element, ...) +// Plotly examples and docs: https://plot.ly/javascript/ +`); + +export default function CustomChartSettings({ options, onOptionsChange }) { + return ( + +
+