diff --git a/__pycache__/run.cpython-37.pyc b/__pycache__/run.cpython-37.pyc index 6db7701cc..82a321aab 100644 Binary files a/__pycache__/run.cpython-37.pyc and b/__pycache__/run.cpython-37.pyc differ diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 1a2b1d802..b5cb667e9 100755 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -23,16 +23,16 @@ } }, "@babel/core": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.6.0.tgz", - "integrity": "sha512-FuRhDRtsd6IptKpHXAa+4WPZYY2ZzgowkbLBecEDDSje1X/apG7jQM33or3NdOmjXBKWGOg4JmSiRfUfuTtHXw==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.6.2.tgz", + "integrity": "sha512-l8zto/fuoZIbncm+01p8zPSDZu/VuuJhAfA7d/AbzM09WR7iVhavvfNDYCNpo1VvLk6E6xgAoP9P+/EMJHuRkQ==", "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.0", - "@babel/helpers": "^7.6.0", - "@babel/parser": "^7.6.0", + "@babel/generator": "^7.6.2", + "@babel/helpers": "^7.6.2", + "@babel/parser": "^7.6.2", "@babel/template": "^7.6.0", - "@babel/traverse": "^7.6.0", + "@babel/traverse": "^7.6.2", "@babel/types": "^7.6.0", "convert-source-map": "^1.1.0", "debug": "^4.1.0", @@ -52,21 +52,20 @@ } }, "@babel/generator": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.0.tgz", - "integrity": "sha512-Ms8Mo7YBdMMn1BYuNtKuP/z0TgEIhbcyB8HVR6PPNYp4P61lMsABiS4A3VG1qznjXVCf3r+fVHhm4efTYVsySA==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.2.tgz", + "integrity": "sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==", "requires": { "@babel/types": "^7.6.0", "jsesc": "^2.5.1", "lodash": "^4.17.13", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" + "source-map": "^0.5.0" } }, "@babel/parser": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.0.tgz", - "integrity": "sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ==" + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.2.tgz", + "integrity": "sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==" }, "@babel/template": { "version": "7.6.0", @@ -79,15 +78,15 @@ } }, "@babel/traverse": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.0.tgz", - "integrity": "sha512-93t52SaOBgml/xY74lsmt7xOR4ufYvhb5c5qiM6lu4J/dWGMAfAh6eKw4PjLes6DI6nQgearoxnFJk60YchpvQ==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.2.tgz", + "integrity": "sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==", "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.0", + "@babel/generator": "^7.6.2", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.0", + "@babel/parser": "^7.6.2", "@babel/types": "^7.6.0", "debug": "^4.1.0", "globals": "^11.1.0", @@ -491,31 +490,30 @@ } }, "@babel/helpers": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.6.0.tgz", - "integrity": "sha512-W9kao7OBleOjfXtFGgArGRX6eCP0UEcA2ZWEWNkJdRZnHhW4eEbeswbG3EwaRsnQUAEGWYgMq1HsIXuNNNy2eQ==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.6.2.tgz", + "integrity": "sha512-3/bAUL8zZxYs1cdX2ilEE0WobqbCmKWr/889lf2SS0PpDcpEIY8pb1CCyz0pEcX3pEb+MCbks1jIokz2xLtGTA==", "requires": { "@babel/template": "^7.6.0", - "@babel/traverse": "^7.6.0", + "@babel/traverse": "^7.6.2", "@babel/types": "^7.6.0" }, "dependencies": { "@babel/generator": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.0.tgz", - "integrity": "sha512-Ms8Mo7YBdMMn1BYuNtKuP/z0TgEIhbcyB8HVR6PPNYp4P61lMsABiS4A3VG1qznjXVCf3r+fVHhm4efTYVsySA==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.2.tgz", + "integrity": "sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==", "requires": { "@babel/types": "^7.6.0", "jsesc": "^2.5.1", "lodash": "^4.17.13", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" + "source-map": "^0.5.0" } }, "@babel/parser": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.0.tgz", - "integrity": "sha512-+o2q111WEx4srBs7L9eJmcwi655eD8sXniLqMB93TBK9GrNzGrxDWSjiqz2hLU0Ha8MTXFIP0yd9fNdP+m43ZQ==" + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.2.tgz", + "integrity": "sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==" }, "@babel/template": { "version": "7.6.0", @@ -528,15 +526,15 @@ } }, "@babel/traverse": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.0.tgz", - "integrity": "sha512-93t52SaOBgml/xY74lsmt7xOR4ufYvhb5c5qiM6lu4J/dWGMAfAh6eKw4PjLes6DI6nQgearoxnFJk60YchpvQ==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.2.tgz", + "integrity": "sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==", "requires": { "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.0", + "@babel/generator": "^7.6.2", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.0", + "@babel/parser": "^7.6.2", "@babel/types": "^7.6.0", "debug": "^4.1.0", "globals": "^11.1.0", @@ -803,9 +801,9 @@ } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz", - "integrity": "sha512-F2DxJJSQ7f64FyTVl5cw/9MWn6naXGdk3Q3UhDbFEEHv+EilCPoeRD3Zh/Utx1CJz4uyKlQ4uH+bJPbEhMV7Zw==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.6.2.tgz", + "integrity": "sha512-LDBXlmADCsMZV1Y9OQwMc0MyGZ8Ta/zlD9N67BfQT8uYwkRswiu2hU6nJKrjrt/58aH/vqfQlR/9yId/7A2gWw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -833,14 +831,30 @@ } }, "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz", - "integrity": "sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.6.2.tgz", + "integrity": "sha512-NxHETdmpeSCtiatMRYWVJo7266rrvAC3DTeG5exQBIH/fMIUK7ejDNznBbn3HQl/o9peymRRg7Yqkx6PdUXmMw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.5.4" + "regexpu-core": "^4.6.0" + }, + "dependencies": { + "regexpu-core": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.6.0.tgz", + "integrity": "sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.1.0", + "regjsgen": "^0.5.0", + "regjsparser": "^0.6.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.1.0" + } + } } }, "@babel/plugin-syntax-async-generators": { @@ -981,9 +995,9 @@ } }, "@babel/plugin-transform-block-scoping": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.0.tgz", - "integrity": "sha512-tIt4E23+kw6TgL/edACZwP1OUKrjOTyMrFMLoT5IOFrfMRabCgekjqFd5o6PaAMildBu46oFkekIdMuGkkPEpA==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.6.2.tgz", + "integrity": "sha512-zZT8ivau9LOQQaOGC7bQLQOT4XPkPXgN2ERfUgk1X8ql+mVkLc4E8eKk+FO3o0154kxzqenWCorfmEXpEZcrSQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", @@ -1025,14 +1039,30 @@ } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz", - "integrity": "sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.6.2.tgz", + "integrity": "sha512-KGKT9aqKV+9YMZSkowzYoYEiHqgaDhGmPNZlZxX6UeHC4z30nC1J9IrZuGqbYFB1jaIGdv91ujpze0exiVK8bA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.5.4" + "regexpu-core": "^4.6.0" + }, + "dependencies": { + "regexpu-core": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.6.0.tgz", + "integrity": "sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.1.0", + "regjsgen": "^0.5.0", + "regjsparser": "^0.6.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.1.0" + } + } } }, "@babel/plugin-transform-duplicate-keys": { @@ -1136,12 +1166,28 @@ } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.6.0.tgz", - "integrity": "sha512-jem7uytlmrRl3iCAuQyw8BpB4c4LWvSpvIeXKpMb+7j84lkx4m4mYr5ErAcmN5KM7B6BqrAvRGjBIbbzqCczew==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.6.2.tgz", + "integrity": "sha512-xBdB+XOs+lgbZc2/4F5BVDVcDNS4tcSKQc96KmlqLEAwz6tpYPEvPdmDfvVG0Ssn8lAhronaRs6Z6KSexIpK5g==", "dev": true, "requires": { - "regexp-tree": "^0.1.13" + "regexpu-core": "^4.6.0" + }, + "dependencies": { + "regexpu-core": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.6.0.tgz", + "integrity": "sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.1.0", + "regjsgen": "^0.5.0", + "regjsparser": "^0.6.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.1.0" + } + } } }, "@babel/plugin-transform-new-target": { @@ -1202,9 +1248,9 @@ } }, "@babel/plugin-transform-runtime": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.6.0.tgz", - "integrity": "sha512-Da8tMf7uClzwUm/pnJ1S93m/aRXmoYNDD7TkHua8xBDdaAs54uZpTWvEt6NGwmoVMb9mZbntfTqmG2oSzN/7Vg==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.6.2.tgz", + "integrity": "sha512-cqULw/QB4yl73cS5Y0TZlQSjDvNkzDbu0FurTZyHlJpWE5T3PCMdnyV+xXoH1opr1ldyHODe3QAX3OMAii5NxA==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", @@ -1231,9 +1277,9 @@ } }, "@babel/plugin-transform-spread": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz", - "integrity": "sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.6.2.tgz", + "integrity": "sha512-DpSvPFryKdK1x+EDJYCy28nmAaIMdxmhot62jAXF/o99iA33Zj2Lmcp3vDmz+MUh0LNYVPvfj5iC3feb3/+PFg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" @@ -1269,20 +1315,36 @@ } }, "@babel/plugin-transform-unicode-regex": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz", - "integrity": "sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.6.2.tgz", + "integrity": "sha512-orZI6cWlR3nk2YmYdb0gImrgCUwb5cBUwjf6Ks6dvNVvXERkwtJWOQaEOjPiu0Gu1Tq6Yq/hruCZZOOi9F34Dw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/helper-regex": "^7.4.4", - "regexpu-core": "^4.5.4" + "regexpu-core": "^4.6.0" + }, + "dependencies": { + "regexpu-core": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.6.0.tgz", + "integrity": "sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.1.0", + "regjsgen": "^0.5.0", + "regjsparser": "^0.6.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.1.0" + } + } } }, "@babel/preset-env": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.6.0.tgz", - "integrity": "sha512-1efzxFv/TcPsNXlRhMzRnkBFMeIqBBgzwmZwlFDw5Ubj0AGLeufxugirwZmkkX/ayi3owsSqoQ4fw8LkfK9SYg==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.6.2.tgz", + "integrity": "sha512-Ru7+mfzy9M1/YTEtlDS8CD45jd22ngb9tXnn64DvQK3ooyqSw9K4K9DUWmYknTTVk4TqygL9dqCrZgm1HMea/Q==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", @@ -1290,9 +1352,9 @@ "@babel/plugin-proposal-async-generator-functions": "^7.2.0", "@babel/plugin-proposal-dynamic-import": "^7.5.0", "@babel/plugin-proposal-json-strings": "^7.2.0", - "@babel/plugin-proposal-object-rest-spread": "^7.5.5", + "@babel/plugin-proposal-object-rest-spread": "^7.6.2", "@babel/plugin-proposal-optional-catch-binding": "^7.2.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-proposal-unicode-property-regex": "^7.6.2", "@babel/plugin-syntax-async-generators": "^7.2.0", "@babel/plugin-syntax-dynamic-import": "^7.2.0", "@babel/plugin-syntax-json-strings": "^7.2.0", @@ -1301,11 +1363,11 @@ "@babel/plugin-transform-arrow-functions": "^7.2.0", "@babel/plugin-transform-async-to-generator": "^7.5.0", "@babel/plugin-transform-block-scoped-functions": "^7.2.0", - "@babel/plugin-transform-block-scoping": "^7.6.0", + "@babel/plugin-transform-block-scoping": "^7.6.2", "@babel/plugin-transform-classes": "^7.5.5", "@babel/plugin-transform-computed-properties": "^7.2.0", "@babel/plugin-transform-destructuring": "^7.6.0", - "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.6.2", "@babel/plugin-transform-duplicate-keys": "^7.5.0", "@babel/plugin-transform-exponentiation-operator": "^7.2.0", "@babel/plugin-transform-for-of": "^7.4.4", @@ -1316,7 +1378,7 @@ "@babel/plugin-transform-modules-commonjs": "^7.6.0", "@babel/plugin-transform-modules-systemjs": "^7.5.0", "@babel/plugin-transform-modules-umd": "^7.2.0", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.6.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.6.2", "@babel/plugin-transform-new-target": "^7.4.4", "@babel/plugin-transform-object-super": "^7.5.5", "@babel/plugin-transform-parameters": "^7.4.4", @@ -1324,11 +1386,11 @@ "@babel/plugin-transform-regenerator": "^7.4.5", "@babel/plugin-transform-reserved-words": "^7.2.0", "@babel/plugin-transform-shorthand-properties": "^7.2.0", - "@babel/plugin-transform-spread": "^7.2.0", + "@babel/plugin-transform-spread": "^7.6.2", "@babel/plugin-transform-sticky-regex": "^7.2.0", "@babel/plugin-transform-template-literals": "^7.4.4", "@babel/plugin-transform-typeof-symbol": "^7.2.0", - "@babel/plugin-transform-unicode-regex": "^7.4.4", + "@babel/plugin-transform-unicode-regex": "^7.6.2", "@babel/types": "^7.6.0", "browserslist": "^4.6.0", "core-js-compat": "^3.1.1", @@ -1357,9 +1419,9 @@ } }, "@babel/runtime": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.0.tgz", - "integrity": "sha512-89eSBLJsxNxOERC0Op4vd+0Bqm6wRMqMbFtV3i0/fbaWw/mJ8Q3eBvgX0G4SyrOOLCtbu98HspF8o09MRT+KzQ==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.2.tgz", + "integrity": "sha512-EXxN64agfUqqIGeEjI5dL5z0Sw0ZwWo1mLTi4mQowCZ42O59b7DRpZAnTC6OqdF28wMBMFKNb/4uFGrVaigSpg==", "requires": { "regenerator-runtime": "^0.13.2" }, @@ -1447,29 +1509,29 @@ } }, "@fortawesome/fontawesome-common-types": { - "version": "0.2.24", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.24.tgz", - "integrity": "sha512-IPBT/1LdUVQpHcqdrh8uI2/86Fbu7933hkA/HweiCmP5QgF/8PecFM00gYvykxf0RZud8bg8zu+YfggDFUc1Kw==" + "version": "0.2.25", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.25.tgz", + "integrity": "sha512-3RuZPDuuPELd7RXtUqTCfed14fcny9UiPOkdr2i+cYxBoTOfQgxcDoq77fHiiHcgWuo1LoBUpvGxFF1H/y7s3Q==" }, "@fortawesome/fontawesome-free": { - "version": "5.11.1", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.11.1.tgz", - "integrity": "sha512-DtXLVYAkDU0ce1cFUgLvZaMd1R2J/LviBYih9xr4ZLhQMrgvYX7w2vOxlpKLRALfIj5GyC5zoVrcACOkLcFgvg==" + "version": "5.11.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.11.2.tgz", + "integrity": "sha512-XiUPoS79r1G7PcpnNtq85TJ7inJWe0v+b5oZJZKb0pGHNIV6+UiNeQWiFGmuQ0aj7GEhnD/v9iqxIsjuRKtEnQ==" }, "@fortawesome/fontawesome-svg-core": { - "version": "1.2.24", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.24.tgz", - "integrity": "sha512-9uVGOEZwviZKbkOVX8nn8cErVqOHBAd1Fqd2OH7Iwu0vxGWdb3fFOMhaAyMXUHZpq1u5C9/HClCV49ci4WmJAg==", + "version": "1.2.25", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.25.tgz", + "integrity": "sha512-MotKnn53JKqbkLQiwcZSBJVYtTgIKFbh7B8+kd05TSnfKYPFmjKKI59o2fpz5t0Hzl35vVGU6+N4twoOpZUrqA==", "requires": { - "@fortawesome/fontawesome-common-types": "^0.2.24" + "@fortawesome/fontawesome-common-types": "^0.2.25" } }, "@fortawesome/free-solid-svg-icons": { - "version": "5.11.1", - "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.11.1.tgz", - "integrity": "sha512-bB3hXON1K6mVOetTTg5VXZ4CAHg866p7MqenDkJ/eVcbWbGQRE45ojHEwkf37tWx3E8z6lcEameRwU9r5tGwjg==", + "version": "5.11.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.11.2.tgz", + "integrity": "sha512-zBue4i0PAZJUXOmLBBvM7L0O7wmsDC8dFv9IhpW5QL4kT9xhhVUsYg/LX1+5KaukWq4/cbDcKT+RT1aRe543sg==", "requires": { - "@fortawesome/fontawesome-common-types": "^0.2.24" + "@fortawesome/fontawesome-common-types": "^0.2.25" } }, "@fortawesome/vue-fontawesome": { @@ -1745,9 +1807,9 @@ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" }, "@types/node": { - "version": "12.7.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.5.tgz", - "integrity": "sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w==" + "version": "12.7.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.9.tgz", + "integrity": "sha512-P57oKTJ/vYivL2BCfxCC5tQjlS8qW31pbOL6qt99Yrjm95YdHgNZwjrTTjMBh+C2/y6PXIX4oz253+jUzxKKfQ==" }, "@types/q": { "version": "1.5.2", @@ -2018,6 +2080,11 @@ "negotiator": "0.6.2" } }, + "accessor-fn": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/accessor-fn/-/accessor-fn-1.2.2.tgz", + "integrity": "sha1-3VLCcUZTiLKXZKt58iIt7dEeSbI=" + }, "accounting-js": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/accounting-js/-/accounting-js-1.1.1.tgz", @@ -5138,9 +5205,9 @@ "integrity": "sha1-K4hTT8G5mGdPh3+Yug2LW3Q+lv4=" }, "bootstrap-vue": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/bootstrap-vue/-/bootstrap-vue-2.0.1.tgz", - "integrity": "sha512-mb2MP0f3KNRi/D8W0cItX2joM+XbwciFx1JKjtdKzt4uIXNx2SpOwF/wle26CszB1S35ArXJ/ZVN0dX8ry4yng==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bootstrap-vue/-/bootstrap-vue-2.0.2.tgz", + "integrity": "sha512-hbGJjc/om9JfVNUFK76dnh+YutlZdZlKbpWw6OE9gHTkmbwstP/KxxELpZZgK/4SYtdxUPt/6W1CvdaeT1bNvQ==", "requires": { "@nuxt/opencollective": "^0.3.0", "bootstrap": ">=4.3.1 <5.0.0", @@ -5723,6 +5790,36 @@ "safe-buffer": "^5.0.1" } }, + "circlepack-chart": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/circlepack-chart/-/circlepack-chart-1.3.0.tgz", + "integrity": "sha512-FQBRRw672SeeUO6ZIO/AC6RLG4YWsnsrB14ez+6g1iwAINZLLaoKn8CuH6oiBS+8u9zDG4wnRpRF7FRa9fr4RA==", + "requires": { + "accessor-fn": "^1.2.2", + "d3-hierarchy": "^1.1.8", + "d3-interpolate": "^1.3.2", + "d3-scale": "^3.1.0", + "d3-selection": "^1.4.0", + "d3-transition": "^1.2.0", + "d3-zoomable": "^1.1.1", + "kapsule": "^1.10.1", + "tinycolor2": "^1.4.1" + }, + "dependencies": { + "d3-scale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.1.0.tgz", + "integrity": "sha512-3edyEBwbwQG400VbgaepQC9ZYFX3h92flLHIUa1+nvZp/mqCYdxNM9zGTjKtPcSAuBCyPePdMQOapsD0qNALrg==", + "requires": { + "d3-array": "1.2.0 - 2", + "d3-format": "1", + "d3-interpolate": "1", + "d3-time": "1", + "d3-time-format": "2" + } + } + } + }, "circumcenter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/circumcenter/-/circumcenter-1.0.0.tgz", @@ -6650,21 +6747,21 @@ } }, "caniuse-lite": { - "version": "1.0.30000989", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz", - "integrity": "sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw==", + "version": "1.0.30000997", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000997.tgz", + "integrity": "sha512-BQLFPIdj2ntgBNWp9Q64LGUIEmvhKkzzHhUHR3CD5A9Lb7ZKF20/+sgadhFap69lk5XmK1fTUleDclaRFvgVUA==", "dev": true }, "electron-to-chromium": { - "version": "1.3.255", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.255.tgz", - "integrity": "sha512-SZ6NlaNw3h4WR5kA1BK8XltdJCax02P+lW+z78RYoLDqmpyYuDQ5bS+/O6MCJ/j761qoZIFox2qYYt+UwqGA5w==", + "version": "1.3.267", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.267.tgz", + "integrity": "sha512-9Q2ixAJC+oHjWNtJV0MQ4vJMCWSowIrC6V6vcr+bwPddTDHj2ddv9xxXCzf4jT/fy6HP7maPoW0gifXkRxCttQ==", "dev": true }, "node-releases": { - "version": "1.1.30", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.30.tgz", - "integrity": "sha512-BHcr1g6NeUH12IL+X3Flvs4IOnl1TL0JczUhEZjDE+FXXPQcVCNr8NEPb01zqGxzhTpdyJL5GXemaCW7aw6Khw==", + "version": "1.1.32", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.32.tgz", + "integrity": "sha512-VhVknkitq8dqtWoluagsGPn3dxTvN9fwgR59fV3D7sLBHe0JfDramsMI8n8mY//ccq/Kkrf8ZRHRpsyVZ3qw1A==", "dev": true, "requires": { "semver": "^5.3.0" @@ -7503,6 +7600,18 @@ "d3-transition": "1" } }, + "d3-zoomable": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/d3-zoomable/-/d3-zoomable-1.1.1.tgz", + "integrity": "sha512-wF0YkDhdRNcJSC6f3u+uNmGG5TfKqIq9SMqrOtEJ2EuzrMJD9f/kW06L8cuRpFSL1ynlj/EClcDdyaJqAbTAVg==", + "requires": { + "d3-interpolate": "^1.3.2", + "d3-selection": "^1.4.0", + "d3-transition": "^1.2.0", + "d3-zoom": "^1.7.3", + "kapsule": "^1.10.1" + } + }, "d3_exploding_boxplot": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/d3_exploding_boxplot/-/d3_exploding_boxplot-0.2.1.tgz", @@ -7797,6 +7906,11 @@ "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=", "dev": true }, + "debounce": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.0.tgz", + "integrity": "sha512-mYtLl1xfZLi1m4RtQYlZgJUNQjl4ZxVnHzIR8nLLgi4q1YT8o/WM+MK/f8yfcc9s5Ir5zRaPZyZU6xs1Syoocg==" + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -8784,9 +8898,9 @@ } }, "eslint": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.4.0.tgz", - "integrity": "sha512-WTVEzK3lSFoXUovDHEbkJqCVPEPwbhCq4trDktNI6ygs7aO41d4cDT0JFAT5MivzZeVLWlg7vHL+bgrQv/t3vA==", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.5.1.tgz", + "integrity": "sha512-32h99BoLYStT1iq1v2P9uwpyznQ4M2jRiFB6acitKz52Gqn+vPaMDUTB1bYi1WN4Nquj2w+t+bimYUG83DC55A==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -8871,9 +8985,9 @@ "dev": true }, "glob-parent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", - "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", "dev": true, "requires": { "is-glob": "^4.0.1" @@ -8962,25 +9076,32 @@ } }, "eslint-loader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-3.0.0.tgz", - "integrity": "sha512-rdxyQ0i9VlhwVlR6oEzrIft8WNKYSD2/cOAJ1YVH/F76gAta7Zv1Dr5xJOUyx0fAsHB5cKNz9hwlUVLMFsQlPA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-3.0.2.tgz", + "integrity": "sha512-S5VnD+UpVY1PyYRqeBd/4pgsmkvSokbHqTXAQMpvCyRr3XN2tvSLo9spm2nEpqQqh9dezw3os/0zWihLeOg2Rw==", "dev": true, "requires": { + "fs-extra": "^8.1.0", "loader-fs-cache": "^1.0.2", "loader-utils": "^1.2.3", "object-hash": "^1.3.1", - "schema-utils": "^2.1.0" + "schema-utils": "^2.2.0" }, "dependencies": { + "ajv-keywords": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", + "dev": true + }, "schema-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.1.0.tgz", - "integrity": "sha512-g6SViEZAfGNrToD82ZPUjq52KUPDYc+fN5+g6Euo5mLokl/9Yx14z0Cu4RR1m55HtBXejO0sBt+qw79axN+Fiw==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.4.1.tgz", + "integrity": "sha512-RqYLpkPZX5Oc3fw/kHHHyP56fg5Y+XBpIpV8nCg0znIALfq3OH+Ea9Hfeac9BAMwG5IICltiZ0vxFvJQONfA5w==", "dev": true, "requires": { - "ajv": "^6.1.0", - "ajv-keywords": "^3.1.0" + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1" } } } @@ -9129,9 +9250,9 @@ }, "dependencies": { "acorn": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz", - "integrity": "sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", + "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", "dev": true }, "acorn-jsx": { @@ -10322,6 +10443,17 @@ "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=" }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, "fs-minipass": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.6.tgz", @@ -13194,6 +13326,12 @@ "is-path-inside": "^1.0.0" } }, + "is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true + }, "is-mobile": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-mobile/-/is-mobile-2.1.0.tgz", @@ -13539,11 +13677,28 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=" }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, "jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=" }, + "kapsule": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/kapsule/-/kapsule-1.12.1.tgz", + "integrity": "sha512-vFbJfsDOU0I96UsRIMUHzI5CbHoy+X8ddzY19Llv7qI+eHX0AAqZVk/WfS6xqwcR4X/glnqLY9zjqAiz+C3vhw==", + "requires": { + "debounce": "^1.2.0" + } + }, "kdbush": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-3.0.0.tgz", @@ -14247,12 +14402,12 @@ } }, "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", "dev": true, "requires": { - "chalk": "^2.0.1" + "chalk": "^2.4.2" } }, "log-utils": { @@ -14883,9 +15038,9 @@ } }, "mdbvue": { - "version": "5.8.2", - "resolved": "https://registry.npmjs.org/mdbvue/-/mdbvue-5.8.2.tgz", - "integrity": "sha512-2U2vx1YYctmQEj/L52DdzpRTmft0QlCIe/i0AdjlxTdFWen7AVZJBWACC7ancEIPNYhLh/JjLfaOlUay+6eIAg==", + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/mdbvue/-/mdbvue-5.8.3.tgz", + "integrity": "sha512-bKleYiLCE1wiONd60GC7XfWmlZz98WaMujI2dZL7VeXsPj3IrQNEKsX9lRsnElWNTVAQyACrga6sDI5bfNzT0A==", "requires": { "@fortawesome/fontawesome-free": "^5.8.2", "axios": "^0.18.0", @@ -14931,9 +15086,9 @@ } }, "is-buffer": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", - "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" } } }, @@ -15710,22 +15865,22 @@ } }, "node-notifier": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz", - "integrity": "sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-6.0.0.tgz", + "integrity": "sha512-SVfQ/wMw+DesunOm5cKqr6yDcvUTDl/yc97ybGHMrteNEY6oekXpNpS3lZwgLlwz0FLgHoiW28ZpmBHUDg37cw==", "dev": true, "requires": { "growly": "^1.3.0", - "is-wsl": "^1.1.0", - "semver": "^5.5.0", + "is-wsl": "^2.1.1", + "semver": "^6.3.0", "shellwords": "^0.1.1", - "which": "^1.3.0" + "which": "^1.3.1" }, "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "is-wsl": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.1.1.tgz", + "integrity": "sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog==", "dev": true } } @@ -16366,15 +16521,16 @@ } }, "ora": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz", - "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/ora/-/ora-4.0.2.tgz", + "integrity": "sha512-YUOZbamht5mfLxPmk4M35CD/5DuOkAacxlEUbStVXpBAt4fyhBf+vZHI/HRkI++QUp3sNoeA2Gw4C+hi4eGSig==", "dev": true, "requires": { "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-spinners": "^2.0.0", - "log-symbols": "^2.2.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.2.0", + "is-interactive": "^1.0.0", + "log-symbols": "^3.0.0", "strip-ansi": "^5.2.0", "wcwidth": "^1.0.1" }, @@ -16385,6 +16541,40 @@ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", @@ -16760,9 +16950,9 @@ "integrity": "sha512-iMtu+HCbLXVrpf6Ys/4YKhcFxbux3xK4ZVB9r+a2kMSqeeQWQoDNYlXIsOjwlT2ldYXZ3k5PVeBnYn7fbAo/Bg==" }, "parse-asn1": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz", - "integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", + "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", "dev": true, "requires": { "asn1.js": "^4.0.0", @@ -18038,6 +18228,16 @@ "sisteransi": "^1.0.3" } }, + "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" + } + }, "protocol-buffers-schema": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.3.2.tgz", @@ -18502,6 +18702,32 @@ } } }, + "react": { + "version": "16.10.1", + "resolved": "https://registry.npmjs.org/react/-/react-16.10.1.tgz", + "integrity": "sha512-2bisHwMhxQ3XQz4LiJJwG3360pY965pTl/MRrZYxIBKVj4fOHoDs5aZAkYXGxDRO1Li+SyjTAilQEbOmtQJHzA==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + } + }, + "react-dom": { + "version": "16.10.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.10.1.tgz", + "integrity": "sha512-SmM4ZW0uug0rn95U8uqr52I7UdNf6wdGLeXDmNLfg3y5q5H9eAbdjF5ubQc3bjDyRrvdAB2IKG7X0GzSpnn5Mg==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.16.1" + } + }, + "react-is": { + "version": "16.10.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.10.1.tgz", + "integrity": "sha512-BXUMf9sIOPXXZWqr7+c5SeOKJykyVr2u0UDzEf4LNGc6taGkQe1A9DFD07umCIXz45RLr9oAAwZbAJ0Pkknfaw==" + }, "read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -18722,12 +18948,6 @@ "resolved": "https://registry.npmjs.org/regex-regex/-/regex-regex-1.0.0.tgz", "integrity": "sha1-kEih6uuHD01IDavHb8Qs3MC8OnI=" }, - "regexp-tree": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.13.tgz", - "integrity": "sha512-hwdV/GQY5F8ReLZWO+W1SRoN5YfpOKY6852+tBFcma72DKBIcHjPRIlIvQN35bCOljuAfP2G2iB0FC/w236mUw==", - "dev": true - }, "regexpp": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", @@ -19450,9 +19670,9 @@ "integrity": "sha512-bJILrpBboQfabG3BNnHI2hZl52pbt80BE09u4WhnrmzuF2JbMKZdl62G5glXskJ46p+gxE2IzOwGj/awR4g8AA==" }, "sass": { - "version": "1.22.12", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.22.12.tgz", - "integrity": "sha512-u5Rxn+dKTPCW5/11kMNxtmqKsxCjcpnqj9CaJoru1NqeJ0DOa9rOM00e0HqmseTAatGkKoLY+jaNecMYevu1gg==", + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.23.0.tgz", + "integrity": "sha512-W4HT8+WE31Rzk3EPQC++CXjD5O+lOxgYBIB8Ohvt7/zeE2UzYW+TOczDrRU3KcEy3+xwXXbmDsOZFkoqgD4TKw==", "dev": true, "requires": { "chokidar": ">=2.0.0 <4.0.0" @@ -19488,6 +19708,15 @@ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, + "scheduler": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.16.1.tgz", + "integrity": "sha512-MIuie7SgsqMYOdCXVFZa8SKoNorJZUWHW8dPgto7uEHn1lX3fg2Gu0TzgK8USj76uxV7vB5eRMnZs/cdEHg+cg==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, "schema-utils": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", @@ -20353,6 +20582,26 @@ "integrity": "sha512-to7oADIniaYwS3MhtCa/sQhrxidCCQiF/qp4/m5iN3ipf0Y7Xlri0f6eG29r08aL7JYl8n32AF3Q5GYBZ7K8vw==", "dev": true }, + "stardust": { + "version": "0.52.5", + "resolved": "https://registry.npmjs.org/stardust/-/stardust-0.52.5.tgz", + "integrity": "sha1-ilnEKnLLVRor61806kqBr92cpDM=", + "requires": { + "classnames": "^2.1.5", + "debug": "^2.2.0", + "lodash": "^4.6.1" + } + }, + "stardust-core": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/stardust-core/-/stardust-core-0.2.4.tgz", + "integrity": "sha512-7csLT8lEuLuikfln7O5VOxwFRSTbE6IvMrhsb2etWpNWhSg2eZZbcGeLI1CHH56qzK7yew4YFrKrDqNNfF8RUg==" + }, + "stardust-webgl": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/stardust-webgl/-/stardust-webgl-0.2.4.tgz", + "integrity": "sha512-3ipuWlhKPH45uYAJ5RV7yvtkuKUNZNIxyIy6jhVb/5M5h3m3kme4Ptdx9QLsJbDZEarDoc6ryIyaT8GL98+NtA==" + }, "static-eval": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz", @@ -21140,9 +21389,9 @@ } }, "terser": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.3.1.tgz", - "integrity": "sha512-pnzH6dnFEsR2aa2SJaKb1uSCl3QmIsJ8dEkj0Fky+2AwMMcC9doMqLOQIH6wVTEKaVfKVvLSk5qxPBEZT9mywg==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.3.3.tgz", + "integrity": "sha512-Nzr7dpRjSzMEUS+z2UYQBtzE0LDm5k0Yy8RgLRPy85QUo1TjU5lIOBwzS5/FVAMaVyHZ3WTTU2BuQcMn8KXnNQ==", "dev": true, "requires": { "commander": "^2.20.0", @@ -21238,9 +21487,9 @@ } }, "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.0.tgz", + "integrity": "sha512-6gpP93MR+VOOehKbCPchro3wFZNSNmek8A2kbkOAZLIZAYx1KP/zAqwO0sOHi3xJEb+UBz8NaYt/17UNit1Q9w==", "dev": true } } @@ -21655,7 +21904,8 @@ "trim-right": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true }, "tryer": { "version": "1.0.1", @@ -21981,6 +22231,12 @@ "crypto-random-string": "^1.0.0" } }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -22483,32 +22739,32 @@ } }, "vega": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/vega/-/vega-5.6.0.tgz", - "integrity": "sha512-CE0tSL94q7PORs+4vVhGpFcKDLvtx4nBSbJUWDhtYD6Wus8M3jTg2G/bE6Ode/5WodWk6hFXOy/Ay3oPaHz7Gw==", + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/vega/-/vega-5.7.0.tgz", + "integrity": "sha512-AxvSF9LfkRzM5ommt9cnuuzeFpHYOqcr2zH3kPHiOlBidTIE1CkQ3z3g4Ff2mM35ln20EmWoT2bsC+J7uLCpHg==", "requires": { "vega-crossfilter": "^4.0.1", "vega-dataflow": "^5.4.0", - "vega-encode": "^4.3.3", + "vega-encode": "^4.4.0", "vega-event-selector": "^2.0.1", "vega-expression": "^2.6.1", "vega-force": "^4.0.2", - "vega-functions": "^5.3.2", - "vega-geo": "^4.0.4", + "vega-functions": "^5.4.0", + "vega-geo": "^4.1.0", "vega-hierarchy": "^4.0.3", "vega-loader": "^4.1.1", - "vega-parser": "^5.8.3", + "vega-parser": "^5.9.0", "vega-projection": "^1.3.0", "vega-regression": "^1.0.1", "vega-runtime": "^5.0.2", "vega-scale": "^4.1.2", - "vega-scenegraph": "^4.2.1", - "vega-statistics": "^1.5.0", - "vega-transforms": "^4.3.0", - "vega-typings": "^0.9.0", + "vega-scenegraph": "^4.3.0", + "vega-statistics": "^1.6.0", + "vega-transforms": "^4.4.0", + "vega-typings": "^0.10.0", "vega-util": "^1.11.2", "vega-view": "^5.3.1", - "vega-view-transforms": "^4.3.2", + "vega-view-transforms": "^4.4.0", "vega-voronoi": "^4.1.1", "vega-wordcloud": "^4.0.2" } @@ -22545,17 +22801,17 @@ } }, "vega-encode": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/vega-encode/-/vega-encode-4.3.3.tgz", - "integrity": "sha512-lhySA4qhsevYrjFgjQn0iyy0ZivrgYbYrjusLZxZ5niJQrCfDqETVl3tjWN9F6vm6HfusBxLWa4cy/zyvK+SOA==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/vega-encode/-/vega-encode-4.4.0.tgz", + "integrity": "sha512-MLofR0XUZzwStyio8V0igS47X1qf06p3XxJKSxcmlPAcaf7SCtaxlSUxkTs9D1i8XApr44riFRtdtEtDzGP3AQ==", "requires": { "d3-array": "^2.3.1", "d3-format": "^1.4.1", "d3-interpolate": "^1.3.2", "d3-time-format": "^2.1.3", "vega-dataflow": "^5.4.0", - "vega-scale": "^4.1.1", - "vega-util": "^1.11.0" + "vega-scale": "^4.1.2", + "vega-util": "^1.11.2" }, "dependencies": { "d3-array": { @@ -22606,9 +22862,9 @@ } }, "vega-functions": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/vega-functions/-/vega-functions-5.3.2.tgz", - "integrity": "sha512-R62p2pTuQh/493fvUO3xI8lxeIQOWMxUxQhASRxIO4YGRUcSVjZiSvbD7qsm7bp34COkmBWTqUzmZMW2fNGZpA==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/vega-functions/-/vega-functions-5.4.0.tgz", + "integrity": "sha512-CK0LyeeGXsM+z3d6F8d8B+qqXsPqrJnfvEb3j93Mkc/H0m4cWIlSqIJ+YqO7FjUyWUE971XKcsTlfYoXlnL8Cg==", "requires": { "d3-array": "^2.3.1", "d3-color": "^1.3.0", @@ -22621,7 +22877,7 @@ "vega-scenegraph": "^4.0.0", "vega-selections": "^5.0.1", "vega-statistics": "^1.3.0", - "vega-util": "^1.11.0" + "vega-util": "^1.11.2" }, "dependencies": { "d3-array": { @@ -22630,9 +22886,9 @@ "integrity": "sha512-YlOh8kwqIz0pDECEdCeqVNelaLQXznD0g6yidhhklMgKxKqbNDrYfoudLMkk9THlqvFll+pXMmXYAyN49yWsmg==" }, "d3-color": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.3.0.tgz", - "integrity": "sha512-NHODMBlj59xPAwl2BDiO2Mog6V+PrGRtBfWKqKRrs9MCqlSkIEb0Z/SfY7jW29ReHTDC/j+vwXhnZcXI3+3fbg==" + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.0.tgz", + "integrity": "sha512-TzNPeJy2+iEepfiL92LAAB7fvnp/dV2YwANPVHdDWmYMm23qIJBYww3qT8I8C1wXrmrg4UWs7BKc2tKIgyjzHg==" }, "d3-format": { "version": "1.4.1", @@ -22642,16 +22898,16 @@ } }, "vega-geo": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/vega-geo/-/vega-geo-4.0.4.tgz", - "integrity": "sha512-YA1iLF0nljkl+WcnURTLYyECxOuIFcw6230TCFTTphMWQuq3oJYF+ENg36z08eMFDgvXTfWDH4mEwOJEb0l/8Q==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/vega-geo/-/vega-geo-4.1.0.tgz", + "integrity": "sha512-3xo0hpmfVdhbdB0MWAppBu/DGTHn7+4g+psUVBu9LRii4XUNlmi+YmJzO4Ph6tv2zxrfZfIKMXid9+V5MzWn+g==", "requires": { "d3-array": "^2.3.1", "d3-contour": "^1.3.2", "d3-geo": "^1.11.6", "vega-dataflow": "^5.1.1", - "vega-projection": "^1.2.1", - "vega-util": "^1.11.0" + "vega-projection": "^1.3.0", + "vega-util": "^1.11.2" }, "dependencies": { "d3-array": { @@ -22694,16 +22950,16 @@ } }, "vega-parser": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/vega-parser/-/vega-parser-5.8.3.tgz", - "integrity": "sha512-SI8tZWumouBKLz/IXRtfHgTr2sWV9jjK7Bb1XKki76MLvqJfmpaU+leIhGztrqX2cJQGxaKjkelRVZUjn6tjMQ==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/vega-parser/-/vega-parser-5.9.0.tgz", + "integrity": "sha512-PtbB3ZMYVYDGdRyzSka208ofAWXm9a+xEPvCObAEe2BbJO48+BZBf8lgRtWborxjf60IaNorZBVxI9gUzSXi+A==", "requires": { "vega-dataflow": "^5.4.0", "vega-event-selector": "^2.0.1", "vega-expression": "^2.6.1", - "vega-functions": "^5.3.1", - "vega-scale": "^4.1.1", - "vega-util": "^1.11.0" + "vega-functions": "^5.4.0", + "vega-scale": "^4.1.2", + "vega-util": "^1.11.2" } }, "vega-projection": { @@ -22773,15 +23029,15 @@ } }, "vega-scenegraph": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/vega-scenegraph/-/vega-scenegraph-4.2.1.tgz", - "integrity": "sha512-qk3L4P/xcWIDnsuB6E9I/akwbneNaUEsZiYWr8CvpE7BjsIgYqklflCx85UbrqdHte5vFwPWiSiHDEuaNrvWgA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/vega-scenegraph/-/vega-scenegraph-4.3.0.tgz", + "integrity": "sha512-QBP7OdLhG8kLV5zHC0TLR1RrGvagy9X+9XGVu8KYuFBRTyNbGX2wD3Eve4uko/1Fkfj35JG/DVq4iBFIXCWbGQ==", "requires": { "d3-path": "^1.0.8", "d3-shape": "^1.3.5", "vega-canvas": "^1.2.1", "vega-loader": "^4.1.1", - "vega-util": "^1.11.0" + "vega-util": "^1.11.2" }, "dependencies": { "d3-path": { @@ -22801,11 +23057,11 @@ } }, "vega-statistics": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/vega-statistics/-/vega-statistics-1.5.0.tgz", - "integrity": "sha512-sbDbLHdPGcEsz3E6Rnqolt5hUxStjrGUehyequHNx/+43MIBvONHLdHMtUm9YLJmj/LChkfLShJ+ObwMVH2aWQ==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vega-statistics/-/vega-statistics-1.6.0.tgz", + "integrity": "sha512-8ECaQ9/q8gnMpDLxYEDLCFxqoUmsW1AV1Qho5Iiryq41CoYhSVmg3DzelZRLutmnE8LYsIW6ysQdZw4tOMbhRQ==", "requires": { - "d3-array": "^2.0.3" + "d3-array": "^2.3.1" }, "dependencies": { "d3-array": { @@ -22816,14 +23072,14 @@ } }, "vega-transforms": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/vega-transforms/-/vega-transforms-4.3.0.tgz", - "integrity": "sha512-a3mtG3/d+DIfrqyMVTe5jythRqbiJd/WoRXQQCJpbe4XyPE75huo0VHdcvqmMPrF4dUQPFkp38JHSXTParj2yw==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/vega-transforms/-/vega-transforms-4.4.0.tgz", + "integrity": "sha512-BzvVE1yuKHv+pbLSGKQjHZR9BBpAQoD2+ns0ce46sLkN0FKty5iy+TO/AOIoss8tNA6769UHxgc7ou1+QO1Ctw==", "requires": { "d3-array": "^2.3.1", "vega-dataflow": "^5.4.0", - "vega-statistics": "^1.5.0", - "vega-util": "^1.11.0" + "vega-statistics": "^1.6.0", + "vega-util": "^1.11.2" }, "dependencies": { "d3-array": { @@ -22834,9 +23090,9 @@ } }, "vega-typings": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/vega-typings/-/vega-typings-0.9.0.tgz", - "integrity": "sha512-auHUUKq/18jk+NGUfR4m/0eil1ufN7sFaYjPOTFu4xhGlULAMriyGQHFaFqPuucNfDCpXMLAQhm31fj67ZPabw==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/vega-typings/-/vega-typings-0.10.0.tgz", + "integrity": "sha512-hrhv871TpPklR8Kq1ooeydUFmbJ+DItJ4va2sEx56w44VpNKTUuWS8IRubCrTHPm1GqZ0VMO4n+u+XM2t2b60g==", "requires": { "vega-util": "^1.11.0" } @@ -22868,13 +23124,13 @@ } }, "vega-view-transforms": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/vega-view-transforms/-/vega-view-transforms-4.3.2.tgz", - "integrity": "sha512-wBDiTS8O5v9J7szalGdsLMjsl3ndIvCGygRWOO8oqFJYboNi6aDEbJMdBkNxxVJ20nNBzT1Ipa2bhYDD0IkylQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/vega-view-transforms/-/vega-view-transforms-4.4.0.tgz", + "integrity": "sha512-Y3n2ovXAz4R+fwwRF/A63Y8FAC2H4xrIHkF43PnjEo/tQ2T5eoksoRSC7iNiFeHbo95Ks6Si/sVmyE8xhT+J2Q==", "requires": { "vega-dataflow": "^5.1.1", - "vega-scenegraph": "^4.1.0", - "vega-util": "^1.11.0" + "vega-scenegraph": "^4.3.0", + "vega-util": "^1.11.2" } }, "vega-voronoi": { @@ -23363,9 +23619,9 @@ "integrity": "sha512-8iSa4mGNXBjyuSZFCCO4fiKfvzqk+mhL0lnKuGcQtO1eoj8nq3CmbEG8FwK5QqoqwDgsjsf1GDuisDX4cdb/aQ==" }, "vue-slider-component": { - "version": "3.0.40", - "resolved": "https://registry.npmjs.org/vue-slider-component/-/vue-slider-component-3.0.40.tgz", - "integrity": "sha512-8obhszDPC34b43h/dd0Gh+oQmUD402X+yo129K3m1EiqAlQ5Imr12XAOQ+RcwCKSOLigLW/flZ0H3dvmhk2ZWQ==", + "version": "3.0.41", + "resolved": "https://registry.npmjs.org/vue-slider-component/-/vue-slider-component-3.0.41.tgz", + "integrity": "sha512-TVLwAJtDInkYp3KYUqptvyLg9Ppx4WqCeVlbbqCS10MpLItq10yRhObWVAGcN07n2++Vv7h5y//4hLGZkauBZA==", "requires": { "vue-property-decorator": "^8.0.0" } @@ -23497,9 +23753,9 @@ } }, "webpack": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.40.2.tgz", - "integrity": "sha512-5nIvteTDCUws2DVvP9Qe+JPla7kWPPIDFZv55To7IycHWZ+Z5qBdaBYPyuXWdhggTufZkQwfIK+5rKQTVovm2A==", + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.41.0.tgz", + "integrity": "sha512-yNV98U4r7wX1VJAj5kyMsu36T8RPPQntcb5fJLOsMz/pt/WrKC0Vp1bAlqPLkA1LegSwQwf6P+kAbyhRKVQ72g==", "dev": true, "requires": { "@webassemblyjs/ast": "1.8.5", @@ -23573,9 +23829,9 @@ } }, "webpack-bundle-analyzer": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.5.0.tgz", - "integrity": "sha512-NzueflueLSJxWGzDlMq5oUV+P8Qoq6yiaQlXGCbDYUpHEKlmzWdPLBJ4k/B6HTdAP/vHM8ply1Fx08mDnY+S8Q==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.5.2.tgz", + "integrity": "sha512-g9spCNe25QYUVqHRDkwG414GTok2m7pTTP0wr6l0J50Z3YLS04+BGodTqqoVBL7QfU/U/9p/oiI5XFOyfZ7S/A==", "dev": true, "requires": { "acorn": "^6.0.7", diff --git a/frontend/package.json b/frontend/package.json index 2f7a9462e..0672619c1 100755 --- a/frontend/package.json +++ b/frontend/package.json @@ -11,15 +11,15 @@ "start": "npm run dev" }, "dependencies": { - "@babel/core": "^7.6.0", - "@babel/runtime": "^7.6.0", - "@fortawesome/fontawesome-free": "^5.11.1", - "@fortawesome/fontawesome-svg-core": "^1.2.24", - "@fortawesome/free-solid-svg-icons": "^5.11.1", + "@babel/core": "^7.6.2", + "@babel/runtime": "^7.6.2", + "@fortawesome/fontawesome-free": "^5.11.2", + "@fortawesome/fontawesome-svg-core": "^1.2.25", + "@fortawesome/free-solid-svg-icons": "^5.11.2", "@fortawesome/vue-fontawesome": "^0.1.7", "@statnett/vue-plotly": "^0.3.2", "@types/d3-drag": "^1.2.3", - "@types/node": "^12.7.5", + "@types/node": "^12.7.9", "ajv": "^6.10.2", "audit": "0.0.6", "axios": "^0.19.0", @@ -28,7 +28,8 @@ "blob": "0.0.5", "bootstrap": "^4.3.1", "bootstrap-toggle": "^2.2.2", - "bootstrap-vue": "^2.0.1", + "bootstrap-vue": "^2.0.2", + "circlepack-chart": "^1.3.0", "clean-webpack-plugin": "^3.0.0", "colorbrewer": "^1.3.0", "d3": "^5.12.0", @@ -47,24 +48,29 @@ "ify-loader": "^1.1.0", "interactjs": "^1.6.2", "jquery": "^3.4.1", - "mdbvue": "^5.8.2", + "mdbvue": "^5.8.3", "mini-css-extract-plugin": "^0.8.0", "npm-check-updates": "^3.1.23", "papaparse": "^5.1.0", "parcoord-es": "^2.2.10", "plotly.js": "^1.49.5", "popper.js": "^1.15.0", + "react": "^16.10.1", + "react-dom": "^16.10.1", + "stardust": "^0.52.5", + "stardust-core": "^0.2.4", + "stardust-webgl": "^0.2.4", "strip-loader": "^0.1.2", "toposort": "^2.0.2", "transform-loader": "^0.2.4", "update": "^0.7.4", - "vega": "^5.6.0", + "vega": "^5.7.0", "vue": "^2.6.10", "vue-bootstrap-slider": "^2.1.8", "vue-papa-parse": "^1.2.2", "vue-plotly": "^1.0.1", "vue-router": "^3.1.3", - "vue-slider-component": "^3.0.40", + "vue-slider-component": "^3.0.41", "vue2-simplert-plugin": "^0.5.3", "webpack-cli": "^3.3.9", "webpack-require": "0.0.16" @@ -80,8 +86,8 @@ "@babel/plugin-syntax-dynamic-import": "^7.2.0", "@babel/plugin-syntax-import-meta": "^7.2.0", "@babel/plugin-syntax-jsx": "^7.2.0", - "@babel/plugin-transform-runtime": "^7.6.0", - "@babel/preset-env": "^7.6.0", + "@babel/plugin-transform-runtime": "^7.6.2", + "@babel/preset-env": "^7.6.2", "autoprefixer": "^9.6.1", "babel-eslint": "^10.0.3", "babel-helper-vue-jsx-merge-props": "^2.0.3", @@ -90,10 +96,10 @@ "chalk": "^2.4.2", "copy-webpack-plugin": "^5.0.4", "css-loader": "^3.2.0", - "eslint": "^6.4.0", + "eslint": "^6.5.1", "eslint-config-standard": "^14.1.0", "eslint-friendly-formatter": "^4.0.1", - "eslint-loader": "^3.0.0", + "eslint-loader": "^3.0.2", "eslint-plugin-import": "^2.18.2", "eslint-plugin-node": "^10.0.0", "eslint-plugin-promise": "^4.2.1", @@ -103,15 +109,15 @@ "file-loader": "^4.2.0", "friendly-errors-webpack-plugin": "^1.7.0", "html-webpack-plugin": "^3.2.0", - "node-notifier": "^5.4.3", + "node-notifier": "^6.0.0", "optimize-css-assets-webpack-plugin": "^5.0.3", - "ora": "^3.4.0", + "ora": "^4.0.2", "portfinder": "^1.0.24", "postcss-import": "^12.0.1", "postcss-loader": "^3.0.0", "postcss-url": "^8.0.0", "rimraf": "^3.0.0", - "sass": "^1.22.12", + "sass": "^1.23.0", "sass-loader": "^8.0.0", "semver": "^6.3.0", "shelljs": "^0.8.3", @@ -125,8 +131,8 @@ "vue-template-compiler": "^2.6.10", "vue2-simplert": "^1.0.0", "vuetify-loader": "^1.3.0", - "webpack": "^4.40.2", - "webpack-bundle-analyzer": "^3.5.0", + "webpack": "^4.41.0", + "webpack-bundle-analyzer": "^3.5.2", "webpack-dev-server": "^3.8.1", "webpack-merge": "^4.2.2" }, diff --git a/frontend/src/components/AlgorithmHyperParam.vue b/frontend/src/components/AlgorithmHyperParam.vue index d66034cea..a089f0e13 100644 --- a/frontend/src/components/AlgorithmHyperParam.vue +++ b/frontend/src/components/AlgorithmHyperParam.vue @@ -18,7 +18,8 @@ export default { return { ModelsPerformance: 0, selAlgorithm: 0, - pc: 0 + pc: 0, + KNNModels: 576 //KNN models } }, methods: { @@ -33,20 +34,22 @@ export default { Combined = JSON.parse(this.ModelsPerformance[0]) colorGiv = colors[0] } else { - Combined = JSON.parse(this.ModelsPerformance[1]) + Combined = JSON.parse(this.ModelsPerformance[2]) colorGiv = colors[1] } - var valuesPerf = Object.values(Combined['mean_test_score']) + var valuesPerf = Object.values(Combined['0']) var ObjectsParams = Combined['params'] var newObjectsParams = [] - var ArrayCombined = new Array(valuesPerf.length) - for (let i = 0; i < valuesPerf.length; i++) { - if (this.selAlgorithm == 'KNN') { + var ArrayCombined = [] + var temp + for (var i = 0; i < valuesPerf.length; i++) { + if (this.selAlgorithm === 'KNN') { + // There is a problem here! newObjectsParams.push({'weights':ObjectsParams[i].weights, 'algorithm':ObjectsParams[i].algorithm,'metric':ObjectsParams[i].metric,'n_neighbors':ObjectsParams[i].n_neighbors}) Object.assign(newObjectsParams[i], {performance: valuesPerf[i]}, {model: i}) ArrayCombined[i] = newObjectsParams[i] } else { - Object.assign(ObjectsParams[i], {performance: valuesPerf[i]}, {model: i}) + Object.assign(ObjectsParams[i], {performance: valuesPerf[i]}, {model: this.KNNModels + i}) ArrayCombined[i] = ObjectsParams[i] } } @@ -54,7 +57,7 @@ export default { this.pc = ParCoords()("#PCP") .data(ArrayCombined) .color(colorGiv) - .hideAxis(['model','performance']) + .hideAxis(['model']) .bundlingStrength(0) // set bundling strength .smoothness(0) .showControlPoints(false) @@ -63,7 +66,7 @@ export default { .reorderable() .interactive(); - this.pc.on("brush", function(d) { + this.pc.on("brushend", function(d) { EventBus.$emit('AllSelModels', d.length) EventBus.$emit('UpdateBoxPlot', d) }); @@ -72,32 +75,18 @@ export default { sliders () { }, - brushed () { - if (this.pc.brushed()) { - EventBus.$emit('ReturningBrushedPoints', this.pc.brushed()) - } else { - EventBus.$emit('ReturningBrushedPoints', this.pc.data()) - } - }, + clear () { d3.selectAll("#PCP > *").remove(); }, - None () { - document.getElementById('PCP').style.cssText='display:none'; - }, - Reveal () { - document.getElementById('PCP').style.cssText='height:200px;display:""'; - } }, mounted() { - EventBus.$on('emittedEventCallingModelBrushed', this.brushed) + EventBus.$on('ReturningBrushedPointsModels', this.brushed) EventBus.$on('emittedEventCallingModelSelect', data => { this.selAlgorithm = data }) EventBus.$on('emittedEventCallingModel', data => { this.ModelsPerformance = data }) EventBus.$on('emittedEventCallingModel', this.PCPView) EventBus.$on('ResponsiveandChange', this.PCPView) EventBus.$on('emittedEventCallingModelClear', this.clear) - EventBus.$on('slidersOn', this.None) - EventBus.$on('PCPCall', this.Reveal) } } \ No newline at end of file diff --git a/frontend/src/components/Algorithms.vue b/frontend/src/components/Algorithms.vue index 84c8f144a..c2ef5db8a 100644 --- a/frontend/src/components/Algorithms.vue +++ b/frontend/src/components/Algorithms.vue @@ -5,7 +5,6 @@ + \ No newline at end of file diff --git a/frontend/src/components/BalancePredictions.vue b/frontend/src/components/BalancePredictions.vue new file mode 100644 index 000000000..5407031a1 --- /dev/null +++ b/frontend/src/components/BalancePredictions.vue @@ -0,0 +1,41 @@ + + + + + \ No newline at end of file diff --git a/frontend/src/components/BarChart.vue b/frontend/src/components/BarChart.vue index c067e3301..00ae89837 100644 --- a/frontend/src/components/BarChart.vue +++ b/frontend/src/components/BarChart.vue @@ -1,19 +1,7 @@ @@ -26,208 +14,127 @@ export default { name: 'BarChart', data () { return { - BarChartResults: '', - ClassNamesOverview: '' + PerformanceResults: '', + ClassNamesOverview: '', + PerformanceResultsSel: [] } }, methods: { BarChartView () { - const PerClassMetrics = JSON.parse(this.BarChartResults[3]) - var ClassNames = JSON.parse(this.BarChartResults[4]) - this.ClassNamesOverview = ClassNames - let ClassifierswithoutFI = JSON.parse(this.BarChartResults[7]) - let ClassifierswithFI = JSON.parse(this.BarChartResults[8]) - const limit = JSON.parse(this.BarChartResults[14]) - for (let j = 0; j < this.ClassNamesOverview.length; j++) { - Plotly.purge('barChartf1Score' + j) - Plotly.purge('barChartPrecision' + j) - Plotly.purge('barChartRecall' + j) + const PerClassMetrics = JSON.parse(this.PerformanceResults[1]) + const PerClassMetrics2 = JSON.parse(this.PerformanceResults[3]) + var UpdateFeatures = 0 + UpdateFeatures = JSON.parse(this.PerformanceResultsSel[0]) + var UpdateFeatures2 = 0 + UpdateFeatures2 = JSON.parse(this.PerformanceResultsSel[1]) + var target_names + target_names = Object.keys(PerClassMetrics) + var sum = [] + var temp = 0 + for (var i=0;i precisionPerClass[j][a] ? 1 : 0 }) - precisionPerClass[j].sort((function(a, b){return b-a})) - precisionData = [ - { - x: indices.map(String), - y: precisionPerClass[j], - type: 'bar', - marker: { - color: 'rgb(158,202,225)', - opacity: 0.6, - line: { - color: 'rgb(8,48,107)', - width: 1.5 - } - } - } - ] - - Plotly.newPlot('barChartPrecision' + j, precisionData, layoutPrec) - } - for (let j = 0; j < ClassNames.length; j++) { - let len = recallPerClass[j].length - let indices = new Array(len) - for (let i = 0; i < len; ++i) indices[i] = i - indices.sort(function (a, b) { return recallPerClass[j][b] < recallPerClass[j][a] ? -1 : recallPerClass[j][b] > recallPerClass[j][a] ? 1 : 0 }) - recallPerClass[j].sort((function(a, b){return b-a})) - recallData = [ - { - x: indices.map(String), - y: recallPerClass[j], - type: 'bar', - marker: { - color: 'rgb(158,202,225)', - opacity: 0.6, - line: { - color: 'rgb(8,48,107)', - width: 1.5 + yaxis: { + title: 'Per Class Performance', + titlefont: { + family: 'Arial, sans-serif', + size: 18, + color: 'grey' } + }, + xaxis2: { + overlaying: 'x', + type:"category", + titlefont: { + family: 'Arial, sans-serif', + size: 18, + color: 'grey' + }, + showticklabels: true, + tickangle: 'auto', + tickfont: { + family: 'Old Standard TT, serif', + size: 14, + color: 'black' + }, + exponentformat: 'e', + showexponent: 'all' } - } - ] - - Plotly.newPlot('barChartRecall' + j, recallData, layoutRec) } - for (let j = 0; j < ClassNames.length; j++) { + /*for (let j = 0; j < ClassNames.length; j++) { let len = f1ScorePerClass[j].length let indices = new Array(len) for (let i = 0; i < len; ++i) indices[i] = i @@ -247,22 +154,106 @@ export default { } } } - ] + ]*/ - Plotly.newPlot('barChartf1Score' + j, f1ScoreData, layoutf1Score) - } + var colors = ['#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a'] + + var trace1 = { + x: ['KNN', 'RF'], + y: [sum[0],sum[1]], + name: target_names[0], + opacity: 0.5, + marker: { + opacity: 0.5, + color: colors[0] + }, + type: 'bar' + }; + + var trace2 = { + x: ['KNN', 'RF'], + y: [sum[2],sum[3]], + name: target_names[1], + opacity: 0.5, + marker: { + opacity: 0.5, + color: colors[1] + }, + type: 'bar' + }; + + var trace3 = { + x: ['KNN', 'RF'], + y: [sum[4],sum[5]], + name: target_names[2], + opacity: 0.5, + marker: { + opacity: 0.5, + color: colors[2] + }, + type: 'bar' + }; + + var trace4 = { + type: 'bar', + x: ['KNN', 'RF'], + y: [sumLine[0],sumLine[1]], + name: target_names[0]+' (Sel)', + xaxis: 'x2', + mode: 'markers', + marker: { + opacity: 1.0, + color: colors[0], + }, + width: [0.1, 0.1] + }; + + var trace5 = { + type: 'bar', + x: ['KNN', 'RF'], + y: [sumLine[2],sumLine[3]], + name: target_names[1]+' (Sel)', + xaxis: 'x2', + mode: 'markers', + marker: { + opacity: 1.0, + color: colors[1], + }, + width: [0.1, 0.1] + }; + + var trace6 = { + type: 'bar', + x: ['KNN', 'RF'], + y: [sumLine[4],sumLine[5]], + name: target_names[2]+' (Sel)', + xaxis: 'x2', + mode: 'markers', + marker: { + opacity: 1.0, + color: colors[2], + }, + width: [0.1, 0.1] + }; + + var data = [trace1, trace4, trace2, trace5, trace3, trace6]; + + Plotly.newPlot('barChart', data, layout) }, - reset () { - for (let j = 0; j < this.ClassNamesOverview.length; j++) { - Plotly.purge('barChartf1Score' + j) - Plotly.purge('barChartPrecision' + j) - Plotly.purge('barChartRecall' + j) - } + reset () + { + Plotly.purge('barChart') } }, mounted() { - EventBus.$on('emittedEventCallingBarChart', data => { this.BarChartResults = data }) + this.PerformanceResultsSel[0] = 0 + this.PerformanceResultsSel[1] = 0 + EventBus.$on('emittedEventCallingBarChartUpdatedFeatures', data => { this.PerformanceResultsSel = data }) + EventBus.$on('emittedEventCallingBarChartUpdatedFeatures', this.BarChartView) + EventBus.$on('emittedEventCallingBarChart', data => { this.PerformanceResults = data }) EventBus.$on('emittedEventCallingBarChart', this.BarChartView) + EventBus.$on('emittedEventCallingUpdateBarChart', data => { this.ModelsChosen = data }) + EventBus.$on('emittedEventCallingUpdateBarChart', this.BarChartView) EventBus.$on('resetViews', this.reset) } } diff --git a/frontend/src/components/Controller.vue b/frontend/src/components/Controller.vue new file mode 100644 index 000000000..fcc20b92e --- /dev/null +++ b/frontend/src/components/Controller.vue @@ -0,0 +1,31 @@ + + + \ No newline at end of file diff --git a/frontend/src/components/CurrentStack.vue b/frontend/src/components/CurrentStack.vue new file mode 100644 index 000000000..387c2512e --- /dev/null +++ b/frontend/src/components/CurrentStack.vue @@ -0,0 +1,53 @@ + + + \ No newline at end of file diff --git a/frontend/src/components/DataSetExecController.vue b/frontend/src/components/DataSetExecController.vue index 58282e38e..a83103c95 100644 --- a/frontend/src/components/DataSetExecController.vue +++ b/frontend/src/components/DataSetExecController.vue @@ -14,14 +14,14 @@ Upload @@ -37,9 +37,8 @@ export default { data () { return { RetrieveValueCSV: 'IrisC', - value: 'Execute', + value: 'Confirm', valueReset: 'Reset', - InitializeEnsemble: false } }, methods: { @@ -52,10 +51,11 @@ export default { this.RetrieveValueCSV = this.RetrieveValueCSV.split('.')[0] EventBus.$emit('SendToServerDataSetConfirmation', this.RetrieveValueCSV) }, - execute () { - this.InitializeEnsemble = true - this.value = 'ReExecute' - this.$emit('InitializeEnsembleLearningEvent') + reset () { + EventBus.$emit('reset') + }, + confirm () { + EventBus.$emit('ConfirmDataSet') } } } diff --git a/frontend/src/components/DataSpace.vue b/frontend/src/components/DataSpace.vue index 7d279f4c9..2f0facb4e 100644 --- a/frontend/src/components/DataSpace.vue +++ b/frontend/src/components/DataSpace.vue @@ -16,7 +16,7 @@ export default { }, methods: { ScatterPlotDataView () { - const XandYCoordinates = JSON.parse(this.DataSpace[9]) + const XandYCoordinates = JSON.parse(this.DataSpace[7]) var result = XandYCoordinates.reduce(function(r, a) { a.forEach(function(s, i) { diff --git a/frontend/src/components/FinalResultsLinePlot.vue b/frontend/src/components/FinalResultsLinePlot.vue index 50b651904..0428e5994 100644 --- a/frontend/src/components/FinalResultsLinePlot.vue +++ b/frontend/src/components/FinalResultsLinePlot.vue @@ -70,7 +70,7 @@ export default { plot_bgcolor: "rgb(229,229,229)", xaxis: { gridcolor: "rgb(255,255,255)", - title: 'Number of Execution', + title: 'Step of Execution', tickformat: '.0f', range: [0, this.scoresMean.length + 2], showgrid: true, @@ -82,8 +82,7 @@ export default { }, yaxis: { gridcolor: "rgb(255,255,255)", - title: 'Accuracy (%)', - range: [0, 100], + title: 'Performance (%)', showgrid: true, showline: false, showticklabels: true, diff --git a/frontend/src/components/Heatmap.vue b/frontend/src/components/Heatmap.vue index b944eea83..68bfb6011 100644 --- a/frontend/src/components/Heatmap.vue +++ b/frontend/src/components/Heatmap.vue @@ -21,7 +21,9 @@ export default { limitation: 0, flag: false, classesNumber: 10, - cellSize: 24 + cellSize: 24, + indicestoRem: [], + modelIds: [] } }, methods: { @@ -29,69 +31,58 @@ export default { EventBus.$emit('SendSelectedFeaturesEvent', '') }, Heatmap () { + // Clear Heatmap first var svg = d3.select("#Heatmap"); svg.selectAll("*").remove(); - //svg.selectAll("*").remove(); - //var FeaturesImportance = JSON.parse(this.GetResultsAll[3]) var FeaturesAccuracy = JSON.parse(this.GetResultsAll[5]) var Features= JSON.parse(this.GetResultsAll[6]) - var ClassifierswithoutFI = JSON.parse(this.GetResultsAll[7]) - var ClassifierswithFI = JSON.parse(this.GetResultsAll[8]) - var Classifiers - Classifiers = ClassifierswithoutFI.concat(ClassifierswithFI) - //var RFEList = JSON.parse(this.GetResultsAll[13]) - var PermImpEli = JSON.parse(this.GetResultsAll[12]) - var featureUni = JSON.parse(this.GetResultsAll[13]) - var limit - if (this.flag) { - limit = this.limitation; - } else { - limit = JSON.parse(this.GetResultsAll[14]) - this.limitation = limit; - } - + var Classifiers = this.modelIds + var keepingArrayIndices = this.indicestoRem + var PermImpEli = JSON.parse(this.GetResultsAll[10]) + var featureUni = JSON.parse(this.GetResultsAll[11]) - if (Classifiers != '') { - var limitList = [] - if (limit == '') { - for (let i = 0; i < Classifiers.length; i++) { - limitList.push(Classifiers[i]) + var lengthInitial = PermImpEli.length + var counter = 0 + var flag + for (var i = 0; i < lengthInitial; i++) { + flag = 0 + for (var j = 0; j < keepingArrayIndices.length; j++) { + if (i == parseInt(keepingArrayIndices[j])) { + flag = 1 } - } else { - limitList = [] - for (let i = 0; i < limit.length; i++) { - for (let j = 0; j < Classifiers.length; j++) { - if (Number(limit[i].match(/\d+/)[0]) == Classifiers[j]) { - limitList.push(Number(limit[i].match(/\d+/)[0])) - } - } - } } - + if (flag == 0) { + PermImpEli.splice(i-counter, 1) + counter++ + } + } + var len2 = Classifiers.length + console.log(len2) var maxUni = Math.max.apply(Math, featureUni.map(function(o) { return o.Score; })) var minUni = Math.min.apply(Math, featureUni.map(function(o) { return o.Score; })) let len = Features.length + console.log(len) let indicesYAxis = new Array(len) for (let i = 0; i < len; i++) { indicesYAxis[i] = [Features[i]] } - var len2 = limitList.length + console.log(indicesYAxis) let indicesXAxis = new Array(len) var temp = [] for (let i = 0; i < len2; i++) { temp = [] temp.push("R") - temp.push("Model "+i.toString()) + temp.push("Model "+Classifiers[i].toString()) indicesXAxis[i] = temp } + console.log(indicesXAxis) temp = [] temp.push("R") temp.push("Average") indicesXAxis[len2] = temp - let withoutfilength = ClassifierswithoutFI.length var values = [] var msg = false var counter = 0 @@ -140,19 +131,7 @@ export default { } var dataAll = {"columns":indicesXAxis,"index":indicesYAxis,"data":transposedArray} this.heatmap_display(dataAll, "#Heatmap"); -/* - // add the squares - svg.selectAll() - .data(data, function(d) {return d.group+':'+d.variable;}) - .enter() - .append("rect") - .attr("x", function(d) { return x(d.group) }) - .attr("y", function(d) { return y(d.variable) }) - .attr("width", x.bandwidth() ) - .attr("height", y.bandwidth() ) - .style("fill", function(d) { return myColor(d.value)} ) - */ - } + }, heatmap_display(data, heatmapId) { var cellSize = this.cellSize @@ -190,8 +169,8 @@ export default { svg.attr('transform', d3.event.transform) // updated for d3 v4 }) //================================================== - var viewerWidth = $(document).width()/4.5; - var viewerHeight = $(document).height()/6; + var viewerWidth = $(document).width()/2; + var viewerHeight = $(document).height()/5.5; var viewerPosTop = 125; var viewerPosLeft = 100; @@ -572,6 +551,8 @@ export default { EventBus.$on('emittedEventCallingTogglesUpdate', this.Refresh) EventBus.$on('emittedEventCallingTogglesUpdate', this.Heatmap) EventBus.$on('resetViews', this.reset) + EventBus.$on('sendModelsIDs', data => { this.modelIds = data }) + EventBus.$on('sendIndicestoRemove', data => { this.indicestoRem = data }) } } diff --git a/frontend/src/components/Main.vue b/frontend/src/components/Main.vue index dbb858b8d..11bacf4c0 100755 --- a/frontend/src/components/Main.vue +++ b/frontend/src/components/Main.vue @@ -6,30 +6,48 @@ - Basic Operations Control Panel + Data and Performance Metrics Selection - + + - + + + Data Space Visualization + + + + + + + + - Diverse Models Exploration + Models Space Visualization + [Sel.:{{OverSelLength}}/All:{{OverAllLength}}] + + - + + - Data Space Visualization + Predictions Space Visualization - + + @@ -38,11 +56,13 @@ - Algorithms Selection and HyperParameters Search [Sel.:{{valueSel}}/All:{{valueAll}}] + Best Algorithms and HyperParameters Search [Sel.:{{valueSel}}/All:{{valueAll}}] - + + + @@ -56,46 +76,44 @@ - - - - - Predictions Space Visualization - - - - - + + Meta-Model Performance + + + + - Base Models Overview - - [Sel.:{{OverSelLength}}/All:{{OverAllLength}}] - + Diverse Algorithms Exploration - + - + - Meta-Model Performance + Current Stacking Ensemble - + + + + + + + Provenance Visualization + + @@ -110,14 +128,19 @@ import Vue from 'vue' import DataSetExecController from './DataSetExecController.vue' import Algorithms from './Algorithms.vue' import AlgorithmHyperParam from './AlgorithmHyperParam.vue' +import Controller from './Controller.vue' import SlidersController from './SlidersController.vue' import ScatterPlot from './ScatterPlot.vue' +import PerMetricBarChart from './PerMetricBarChart.vue' import DataSpace from './DataSpace.vue' import PredictionsSpace from './PredictionsSpace.vue' +import BalancePredictions from './BalancePredictions.vue' import BarChart from './BarChart.vue' import Heatmap from './Heatmap.vue' import ToggleSelection from './ToggleSelection.vue' import FinalResultsLinePlot from './FinalResultsLinePlot.vue' +import CurrentStack from './CurrentStack.vue' +import Provenance from './Provenance.vue' import axios from 'axios' import { loadProgressBar } from 'axios-progress-bar' import 'axios-progress-bar/dist/nprogress.css' @@ -137,13 +160,18 @@ export default Vue.extend({ DataSetExecController, Algorithms, AlgorithmHyperParam, + Controller, SlidersController, ScatterPlot, + PerMetricBarChart, DataSpace, PredictionsSpace, + BalancePredictions, BarChart, Heatmap, ToggleSelection, + Provenance, + CurrentStack, FinalResultsLinePlot, mdbCard, mdbCardBody, @@ -161,11 +189,10 @@ export default Vue.extend({ Algorithms: ['KNN','RF'], selectedAlgorithm: '', PerformancePerModel: '', - brushed: 0, - brushedAll: [], - ExecutionStart: false, + PerformanceCheck: '', + selectedAlgorithms: [], + parametersofModels: [], reset: false, - limitModels: 64, brushedBoxPlotUpdate: 0, width: 0, height: 0, @@ -179,20 +206,18 @@ export default Vue.extend({ OverAllLength: 0, toggle1: 1, toggle2: 1, - toggle3: 1 + toggle3: 1, + modelsUpdate: [], + parametersUpdate: [], + AlgorithmsUpdate: [] } }, methods: { selectVisualRepresentation () { - const representationSelectionDocum = document.getElementById('selectProjection') + const representationSelectionDocum = document.getElementById('selectBarChart') this.representationSelection = representationSelectionDocum.options[representationSelectionDocum.selectedIndex].value EventBus.$emit('RepresentationSelection', this.representationSelection) }, - DataBaseRequestDataSetName () { - this.ExecutionStart = true - EventBus.$emit('slidersOn') - this.getOverviewResults() - }, getCollection () { this.Collection = this.getCollectionFromBackend() }, @@ -236,26 +261,19 @@ export default Vue.extend({ this.OverviewResults = response.data.OverviewResults console.log('Server successfully sent all the data related to visualizations!') EventBus.$emit('emittedEventCallingScatterPlot', this.OverviewResults) - var length = JSON.parse(this.OverviewResults[0]).length - this.OverSelLength = length - this.OverAllLength = length + EventBus.$emit('InitializeMetricsBarChart', this.OverviewResults) this.valueSel = 0 this.valueAll = 0 var toggles = [] toggles.push(this.toggle1) toggles.push(this.toggle2) toggles.push(this.toggle3) - if (length < this.limitModels) { - this.OverviewResults.push(JSON.stringify(this.ClassifierIDsList)) - EventBus.$emit('emittedEventCallingBarChart', this.OverviewResults) - EventBus.$emit('emitToggles', this.OverviewResults) - EventBus.$emit('emittedEventCallingToggles', toggles) - EventBus.$emit('emittedEventCallingHeatmapView', this.OverviewResults) - EventBus.$emit('emittedEventCallingTableView', this.OverviewResults) - EventBus.$emit('emittedEventCallingDataSpacePlotView', this.OverviewResults) - EventBus.$emit('emittedEventCallingPredictionsSpacePlotView', this.OverviewResults) - this.OverviewResults.pop() - } + EventBus.$emit('emitToggles', this.OverviewResults) + EventBus.$emit('emittedEventCallingToggles', toggles) + EventBus.$emit('emittedEventCallingHeatmapView', this.OverviewResults) + EventBus.$emit('emittedEventCallingTableView', this.OverviewResults) + EventBus.$emit('emittedEventCallingDataSpacePlotView', this.OverviewResults) + EventBus.$emit('emittedEventCallingPredictionsSpacePlotView', this.OverviewResults) this.getFinalResults() }) .catch(error => { @@ -279,8 +297,30 @@ export default Vue.extend({ axios.get(path, axiosConfig) .then(response => { this.PerformancePerModel = response.data.PerformancePerModel - console.log('Server successfully sent all the performance data related to models!') + console.log('Server successfully sent updated per class features!') EventBus.$emit('emittedEventCallingAllAlgorithms', this.PerformancePerModel) + EventBus.$emit('emittedEventCallingBarChart', this.PerformancePerModel) + }) + .catch(error => { + console.log(error) + }) + }, + UpdateModelsFeaturePerformance () { + const path = `http://localhost:5000/data/UpdatePerFeaturePerformance` + + const axiosConfig = { + headers: { + 'Content-Type': 'application/json', + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Headers': 'Origin, Content-Type, X-Auth-Token', + 'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, OPTIONS' + } + } + axios.get(path, axiosConfig) + .then(response => { + this.PerformanceCheck = response.data.PerformanceCheck + console.log('Server successfully sent all the performance data related to models!') + EventBus.$emit('emittedEventCallingBarChartUpdatedFeatures', this.PerformanceCheck) }) .catch(error => { console.log(error) @@ -308,15 +348,10 @@ export default Vue.extend({ .then(response => { console.log('Sent the selected points to the server (scatterplot)!') this.OverSelLength = this.ClassifierIDsList.length - if (this.ClassifierIDsList.length < this.limitModels) { - this.OverviewResults.push(JSON.stringify(this.ClassifierIDsList)) - EventBus.$emit('emittedEventCallingBarChart', this.OverviewResults) - EventBus.$emit('emittedEventCallingHeatmapView', this.OverviewResults) - EventBus.$emit('emittedEventCallingTableView', this.OverviewResults) - EventBus.$emit('emittedEventCallingDataSpacePlotView', this.OverviewResults) - EventBus.$emit('emittedEventCallingPredictionsSpacePlotView', this.OverviewResults) - this.OverviewResults.pop() - } + EventBus.$emit('emittedEventCallingHeatmapView', this.OverviewResults) + EventBus.$emit('emittedEventCallingTableView', this.OverviewResults) + EventBus.$emit('emittedEventCallingDataSpacePlotView', this.OverviewResults) + EventBus.$emit('emittedEventCallingPredictionsSpacePlotView', this.OverviewResults) this.getFinalResults() }) .catch(error => { @@ -396,8 +431,8 @@ export default Vue.extend({ EventBus.$emit('emittedEventCallingModelBrushed') const path = `http://127.0.0.1:5000/data/SendBrushedParam` const postData = { - brushed: this.brushed, - algorithm: this.selectedAlgorithm + parameters: this.parametersofModels, + algorithms: this.selectedAlgorithms } const axiosConfig = { headers: { @@ -410,6 +445,7 @@ export default Vue.extend({ axios.post(path, postData, axiosConfig) .then(response => { console.log('Send request to server! Brushed parameters sent successfully!') + this.getScatterplotDataFromBackend() if (!this.ExecutionStart) { } else { this.getCollection() @@ -419,6 +455,29 @@ export default Vue.extend({ console.log(error) }) }, + UpdateBarChartFeatures () { + const path = `http://127.0.0.1:5000/data/FeaturesScoresUpdate` + const postData = { + parameters: this.parametersUpdate, + algorithms: this.AlgorithmsUpdate + } + const axiosConfig = { + headers: { + 'Content-Type': 'application/json', + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Headers': 'Origin, Content-Type, X-Auth-Token', + 'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, OPTIONS' + } + } + axios.post(path, postData, axiosConfig) + .then(response => { + console.log('Send request to server! Updating Barchart!') + this.UpdateModelsFeaturePerformance() + }) + .catch(error => { + console.log(error) + }) + }, UpdateBasedonFeatures () { const path = `http://127.0.0.1:5000/data/FeaturesSelection` const postData = { @@ -557,22 +616,27 @@ export default Vue.extend({ mounted() { this.render(true) loadProgressBar() - this.fileNameSend() window.onbeforeunload = function(e) { return 'Dialog text here.' } $(window).on("unload", function(e) { alert('Handler for .unload() called.'); }) + EventBus.$on('ReturningAlgorithmsBar', data => { this.AlgorithmsUpdate = data }) + EventBus.$on('ReturningBrushedPointsParamsBar', data => { this.parametersUpdate = data }) + EventBus.$on('ReturningBrushedPointsParamsBar', this.UpdateBarChartFeatures ) + EventBus.$on('ConfirmDataSet', this.fileNameSend) + EventBus.$on('reset', this.Reset) EventBus.$on('UploadedFile', this.Reset) EventBus.$on('UploadedFile', this.UploadProcess) - EventBus.$on('ReturningBrushedPoints', data => { this.brushed = data }) + EventBus.$on('InitializeEnsembleLearningEvent', this.getOverviewResults) + EventBus.$on('ReturningAlgorithms', data => { this.selectedAlgorithms = data }) + EventBus.$on('ReturningBrushedPointsParams', data => { this.parametersofModels = data; }) EventBus.$on('SendSelectedPointsToServerEvent', data => { this.ClassifierIDsList = data }) EventBus.$on('SendSelectedPointsToServerEvent', this.SendSelectedPointsToServer) EventBus.$on('SendSelectedFeaturesEvent', data => { this.SelectedFeaturesPerClassifier = data }) EventBus.$on('SendSelectedFeaturesEvent', this.UpdateBasedonFeatures ) EventBus.$on('SendToServerDataSetConfirmation', data => { this.RetrieveValueFile = data }) - EventBus.$on('SendToServerDataSetConfirmation', this.fileNameSend) EventBus.$on('PCPCall', data => { this.selectedAlgorithm = data }) EventBus.$on('toggle1', data => { this.toggle1 = data }) EventBus.$on('toggle2', data => { this.toggle2 = data }) @@ -590,6 +654,8 @@ export default Vue.extend({ this.valueSel = data this.valueAll = data }) + EventBus.$on('sendPointsNumber', data => {this.OverSelLength = data}) + EventBus.$on('sendPointsNumber', data => {this.OverAllLength = data}) EventBus.$on('AllSelModels', data => {this.valueSel = data}) //Prevent double click to search for a word. document.addEventListener('mousedown', function (event) { diff --git a/frontend/src/components/PerMetricBarChart.vue b/frontend/src/components/PerMetricBarChart.vue new file mode 100644 index 000000000..7c3ab7e57 --- /dev/null +++ b/frontend/src/components/PerMetricBarChart.vue @@ -0,0 +1,127 @@ + + + \ No newline at end of file diff --git a/frontend/src/components/PredictionsSpace.vue b/frontend/src/components/PredictionsSpace.vue index e93589577..c9056a280 100644 --- a/frontend/src/components/PredictionsSpace.vue +++ b/frontend/src/components/PredictionsSpace.vue @@ -15,7 +15,7 @@ export default { }, methods: { ScatterPlotDataView () { - const XandYCoordinates = JSON.parse(this.PredictionsData[10]) + const XandYCoordinates = JSON.parse(this.PredictionsData[8]) var result = XandYCoordinates.reduce(function(r, a) { a.forEach(function(s, i) { @@ -40,7 +40,10 @@ export default { }, yaxis: { visible: false - } + }, + autosize: true, + width: 400, + height: 400, } Plotly.newPlot('OverviewPredPlotly', Data, layout, {responsive: true}) } diff --git a/frontend/src/components/Provenance.vue b/frontend/src/components/Provenance.vue new file mode 100644 index 000000000..69292fa01 --- /dev/null +++ b/frontend/src/components/Provenance.vue @@ -0,0 +1,40 @@ + + + \ No newline at end of file diff --git a/frontend/src/components/ScatterPlot.vue b/frontend/src/components/ScatterPlot.vue index 38cc13137..450427c56 100644 --- a/frontend/src/components/ScatterPlot.vue +++ b/frontend/src/components/ScatterPlot.vue @@ -18,33 +18,102 @@ export default { ScatterPlotResults: '', representationDefault: 'MDS', colorsforOver: [], + brushedBox : [], max: 0, - min: 0 + min: 0, + parametersAll: [], + length: 0, } }, methods: { ScatterPlotView () { + + function isEquivalent(a, b) { + // Create arrays of property names + var aProps = Object.getOwnPropertyNames(a); + var bProps = Object.getOwnPropertyNames(b); + + // If number of properties is different, + // objects are not equivalent + if (aProps.length != bProps.length) { + return false; + } + + for (var i = 0; i < aProps.length; i++) { + var propName = aProps[i]; + + // If values of same property are not equal, + // objects are not equivalent + if (a[propName] !== b[propName]) { + return false; + } + } + + // If we made it this far, objects + // are considered equivalent + return true; + } + Plotly.purge('OverviewPlotly') var colorsforScatterPlot = JSON.parse(this.ScatterPlotResults[0]) + console.log(colorsforScatterPlot) var MDSData = JSON.parse(this.ScatterPlotResults[1]) - var TSNEData = JSON.parse(this.ScatterPlotResults[12]) - const classifiersInfo = JSON.parse(this.ScatterPlotResults[2]) + console.log(MDSData) + var parameters = JSON.parse(this.ScatterPlotResults[2]) + parameters = JSON.parse(parameters) + var classifiersInfo = this.brushedBox + var keepingArrayIndices = [] + var modelsDetails = [] + var modelsIDs = [] + for (var j in parameters) { + for (var i in classifiersInfo) { + if (isEquivalent(JSON.parse(this.parametersAll[classifiersInfo[i].model]),parameters[j])) { + keepingArrayIndices.push(j) + modelsDetails.push(this.parametersAll[classifiersInfo[i].model]) + modelsIDs.push(classifiersInfo[i].model) + } else { + } + } + } + + var flag + this.length = keepingArrayIndices.length + EventBus.$emit('sendPointsNumber', this.length) + EventBus.$emit('sendModelsIDs', modelsIDs) + EventBus.$emit('sendIndicestoRemove', keepingArrayIndices) + var lengthInitial = colorsforScatterPlot.length + var counter = 0 + for (var i = 0; i < lengthInitial; i++) { + flag = 0 + for (var j = 0; j < keepingArrayIndices.length; j++) { + if (i == parseInt(keepingArrayIndices[j])) { + flag = 1 + } + } + if (flag == 0) { + colorsforScatterPlot.splice(i-counter, 1) + MDSData[0].splice(i-counter,1) + MDSData[1].splice(i-counter,1) + counter++ + } + } + console.log(MDSData) + console.log(colorsforScatterPlot) if (this.colorsforOver.length != 0) { if (this.colorsforOver[1].length != 0) { MDSData = this.colorsforOver[1] - TSNEData = this.colorsforOver[2] } if (this.colorsforOver[0].length != 0) { colorsforScatterPlot = this.colorsforOver[0] } } + console.log(this.colorsforOver) var classifiersInfoProcessing = [] - for (let i = 0; i < classifiersInfo.length; i++) { - classifiersInfoProcessing[i] = 'Model ID: ' + i + '; Details: ' + for (let i = 0; i < modelsDetails.length; i++) { + classifiersInfoProcessing[i] = 'Model ID: ' + modelsIDs[i] + '; Details: ' + modelsDetails[i] } var DataGeneral var layout - if ( this.representationDefault == 'MDS') { DataGeneral = [{ type: 'scatter', mode: 'markers', @@ -59,10 +128,9 @@ export default { size: 12, colorscale: 'Viridis', colorbar: { - title: 'Metrics Sum', + title: 'Metrics Average', titleside: 'Top' }, - reversescale: true } }] layout = { @@ -73,56 +141,14 @@ export default { yaxis: { visible: false }, + autosize: true, + width: 400, + height: 400, dragmode: 'lasso', hovermode: "closest", hoverlabel: { bgcolor: "#FFF" }, legend: {orientation: 'h', y: -0.3}, } - } else { - var result = TSNEData.reduce(function(r, a) { - a.forEach(function(s, i) { - var key = i === 0 ? 'Xax' : 'Yax'; - - r[key] || (r[key] = []); // if key not found on result object, add the key with empty array as the value - - r[key].push(s); - }) - return r; - }, {}) - DataGeneral = [{ - type: 'scatter', - mode: 'markers', - x: result.Xax, - y: result.Yax, - hovertemplate: - "%{text}

" + - "", - text: classifiersInfoProcessing, - marker: { - color: colorsforScatterPlot, - size: 12, - colorscale: 'Viridis', - colorbar: { - title: 'Metrics Sum', - titleside: 'Top' - }, - reversescale: true - } - }] - layout = { - title: 'Models Performance (t-SNE)', - xaxis: { - visible: false - }, - yaxis: { - visible: false - }, - dragmode: 'lasso', - hovermode: "closest", - hoverlabel: { bgcolor: "#FFF" }, - legend: {orientation: 'h', y: -0.3}, - } - } var config = {scrollZoom: true, displaylogo: false, showLink: false, showSendToCloud: false, modeBarButtonsToRemove: ['toImage', 'toggleSpikelines', 'autoScale2d', 'hoverClosestGl2d','hoverCompareCartesian','select2d','hoverClosestCartesian','zoomIn2d','zoomOut2d','zoom2d'], responsive: true} @@ -158,14 +184,15 @@ export default { } }, mounted() { + EventBus.$on('emittedEventCallingBrushedBoxPlot', data => { + this.brushedBox = data}) EventBus.$on('emittedEventCallingScatterPlot', data => { this.ScatterPlotResults = data}) EventBus.$on('emittedEventCallingScatterPlot', this.ScatterPlotView) EventBus.$on('getColors', data => { this.colorsforOver = data}) - EventBus.$on('getColors', this.UpdateScatter), - EventBus.$on('RepresentationSelection', data => {this.representationDefault = data}) - EventBus.$on('RepresentationSelection', this.ScatterPlotView) + EventBus.$on('ParametersAll', data => { this.parametersAll = data }) + EventBus.$on('getColors', this.UpdateScatter) } } \ No newline at end of file diff --git a/frontend/src/components/SlidersController.vue b/frontend/src/components/SlidersController.vue index 5d8cd43b5..6b5ea6647 100644 --- a/frontend/src/components/SlidersController.vue +++ b/frontend/src/components/SlidersController.vue @@ -1,10 +1,10 @@ @@ -21,7 +21,12 @@ basicValue2: 100, basicValue3: 100, basicValue4: 100, - basicValue5: 100 + basicValue5: 100, + basicValue6: 100, + basicValue7: 100, + basicValue8: 100, + basicValue9: 100, + basicValue10: 100 } }, methods: { @@ -36,16 +41,19 @@ basicValues.push(this.basicValue5/100) EventBus.$emit('CallFactorsView', basicValues) }, - Enable () { - document.getElementById('WrapSliders').style.cssText='height:200px;display:""'; - }, - Disable () { - document.getElementById('WrapSliders').style.cssText='display:none'; - } }, - mounted () { - EventBus.$on('slidersOn', this.Enable) - EventBus.$on('PCPCall', this.Disable) - } } + + \ No newline at end of file diff --git a/frontend/src/main.js b/frontend/src/main.js index ce2bf0e8c..9d057241b 100755 --- a/frontend/src/main.js +++ b/frontend/src/main.js @@ -6,10 +6,10 @@ import 'bootstrap-vue/dist/bootstrap-vue.css' import router from './router' import { library } from '@fortawesome/fontawesome-svg-core' import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' -import { faUpload, faPlay, faCheck, faSave, faTrash} from '@fortawesome/free-solid-svg-icons' +import { faUpload, faPlay, faCheck, faSave, faTrash, faPlus, faBalanceScale} from '@fortawesome/free-solid-svg-icons' import bFormSlider from 'vue-bootstrap-slider' -library.add(faUpload, faPlay, faCheck, faSave, faTrash) +library.add(faUpload, faPlay, faCheck, faSave, faTrash, faPlus, faBalanceScale) Vue.component('font-awesome-icon', FontAwesomeIcon) diff --git a/run.py b/run.py index aa89e5cd9..b2219d392 100644 --- a/run.py +++ b/run.py @@ -12,6 +12,7 @@ import warnings import copy from joblib import Memory from itertools import chain +import ast from sklearn.linear_model import LogisticRegression from sklearn.neighbors import KNeighborsClassifier @@ -72,15 +73,6 @@ def Reset(): # Initializing models - global classifiersId - classifiersId = [] - global classifiersIDwithFI - classifiersIDwithFI = [] - global classifiersIDPlusParams - classifiersIDPlusParams = [] - global classifierID - classifierID = 0 - global resultsList resultsList = [] @@ -146,15 +138,6 @@ def RetrieveFileName(): # Initializing models - global classifiersId - classifiersId = [] - global classifiersIDwithFI - classifiersIDwithFI = [] - global classifiersIDPlusParams - classifiersIDPlusParams = [] - global classifierID - classifierID = 0 - global RetrieveModelsList RetrieveModelsList = [] @@ -170,9 +153,7 @@ def RetrieveFileName(): global crossValidation crossValidation = 3 - global scoring #scoring = {'accuracy': 'accuracy', 'f1_macro': 'f1_weighted', 'precision': 'precision_weighted', 'recall': 'recall_weighted', 'jaccard': 'jaccard_weighted', 'neg_log_loss': 'neg_log_loss', 'r2': 'r2', 'neg_mean_absolute_error': 'neg_mean_absolute_error', 'neg_mean_absolute_error': 'neg_mean_absolute_error'} - scoring = {'accuracy': 'accuracy', 'f1_macro': 'f1_weighted', 'precision': 'precision_weighted', 'recall': 'recall_weighted', 'jaccard': 'jaccard_weighted'} global yPredictProb yPredictProb = [] @@ -296,7 +277,7 @@ def GridSearch(clf, params): number_of_columns = len(df_cv_results.iloc[0]) df_cv_results_per_item = [] df_cv_results_per_row = [] - + for i in range(number_of_classifiers): df_cv_results_per_item = [] for column in df_cv_results.iloc[0]: @@ -398,21 +379,15 @@ def Preprocessing(): global resultsList df_cv_results_classifiersList = [] parametersList = [] - #FeatureImportanceList = [] PerClassMetricsList = [] FeatureAccuracyList = [] - #RFEListPD = [] - #perm_imp_rfpimp = [] perm_imp_eli5PD = [] featureScores = [] for j, result in enumerate(resultsList): df_cv_results_classifiersList.append(resultsList[j][0]) parametersList.append(resultsList[j][1]) - #FeatureImportanceList.append(resultsList[j][2]) PerClassMetricsList.append(resultsList[j][2]) FeatureAccuracyList.append(resultsList[j][3]) - #RFEListPD.append(resultsList[j][5]) - #perm_imp_rfpimp.append(resultsList[j][6]) perm_imp_eli5PD.append(resultsList[j][4]) featureScores.append(resultsList[j][5]) @@ -427,9 +402,8 @@ def Preprocessing(): featureScoresCon = pd.concat(featureScores, ignore_index=True, sort=False) global factors factors = [1,1,1,1,1,1] - global scoring - NumberofscoringMetrics = len(scoring) global df_cv_results_classifiers_metrics + global NumberofscoringMetrics del df_cv_results_classifiers['params'] df_cv_results_classifiers_metrics = df_cv_results_classifiers.copy() del df_cv_results_classifiers_metrics['mean_fit_time'] @@ -441,10 +415,18 @@ def sumPerMetric(factors): sumPerClassifier = [] preProcessResults = [] preProcessResults = Preprocessing() - loopThroughMetrics = preProcessResults[4] + loopThroughMetrics = preProcessResults[3] + + global scoring + global metricsPerModel + metricsPerModel = [] + metricsPerModel.append(loopThroughMetrics['mean_test_accuracy'].sum()/loopThroughMetrics['mean_test_accuracy'].count()) + metricsPerModel.append(loopThroughMetrics['mean_test_f1_macro'].sum()/loopThroughMetrics['mean_test_f1_macro'].count()) + metricsPerModel.append(loopThroughMetrics['mean_test_precision'].sum()/loopThroughMetrics['mean_test_precision'].count()) + metricsPerModel.append(loopThroughMetrics['mean_test_recall'].sum()/loopThroughMetrics['mean_test_recall'].count()) + metricsPerModel.append(loopThroughMetrics['mean_test_jaccard'].sum()/loopThroughMetrics['mean_test_jaccard'].count()) for index, row in loopThroughMetrics.iterrows(): rowSum = 0 - global scoring lengthFactors = len(scoring) for loop,elements in enumerate(row): lengthFactors = lengthFactors - 1 + factors[loop] @@ -470,7 +452,7 @@ def RetrieveFactors(): ModelSpaceTSNENew = [] preProcessResults = [] preProcessResults = Preprocessing() - XClassifiers = preProcessResults[4] + XClassifiers = preProcessResults[3] flagLocal = 0 countRemovals = 0 for l,el in enumerate(FactorsInt['Factors']): @@ -489,10 +471,12 @@ def UpdateOverview(): global sumPerClassifierSel global ModelSpaceMDSNew global ModelSpaceTSNENew + global metricsPerModel ResultsUpdateOverview = [] ResultsUpdateOverview.append(sumPerClassifierSel) ResultsUpdateOverview.append(ModelSpaceMDSNew) ResultsUpdateOverview.append(ModelSpaceTSNENew) + ResultsUpdateOverview.append(metricsPerModel) response = { 'Results': ResultsUpdateOverview } @@ -506,7 +490,7 @@ def InitializeEnsemble(): mergedPredListListForm = [] for el in mergedPredList: mergedPredListListForm.append(list(chain(*el))) - XClassifiers = preProcessResults[4] + XClassifiers = preProcessResults[3] PredictionSpace = FunTsne(mergedPredListListForm) DataSpace = FunTsne(XData) ModelSpaceMDS = FunMDS(XClassifiers) @@ -522,38 +506,30 @@ def InitializeEnsemble(): def ReturnResults(sumPerClassifier,ModelSpaceMDS,ModelSpaceTSNE,preProcessResults,DataSpaceList,PredictionSpaceList): global Results Results = [] - #FeatureImportanceListPD = preProcessResults[1] + parametersGen = preProcessResults[0] PerClassMetrics = preProcessResults[1] FeatureAccuracy = preProcessResults[2] - #RFEListPDCon = preProcessResults[5] - #perm_imp_rfpimpCon = preProcessResults[6] perm_imp_eli5PDCon = preProcessResults[4] featureScoresCon = preProcessResults[5] - #FeatureImportanceListPD = FeatureImportanceListPD.to_json(orient='records') + parametersGenPD = parametersGen.to_json(orient='records') PerClassMetrics = PerClassMetrics.to_json(orient='records') FeatureAccuracy = FeatureAccuracy.to_json(orient='records') - #RFEListPDCon = RFEListPDCon.to_json(orient='records') - #perm_imp_rfpimpCon = perm_imp_rfpimpCon.to_json(orient='records') perm_imp_eli5PDCon = perm_imp_eli5PDCon.to_json(orient='records') featureScoresCon = featureScoresCon.to_json(orient='records') XDataJSON = XData.columns.tolist() + global metricsPerModel Results.append(json.dumps(sumPerClassifier)) # Position: 0 Results.append(json.dumps(ModelSpaceMDS)) # Position: 1 - Results.append(json.dumps(classifiersIDPlusParams)) # Position: 2 - #Results.append(FeatureImportanceListPD) # Position: 3 + Results.append(json.dumps(parametersGenPD)) # Position: 2 Results.append(PerClassMetrics) # Position: 3 Results.append(json.dumps(target_names)) # Position: 4 Results.append(FeatureAccuracy) # Position: 5 Results.append(json.dumps(XDataJSON)) # Position: 6 - Results.append(json.dumps(classifiersId)) # Position: 7 - Results.append(json.dumps(classifiersIDwithFI)) # Position: 8 - Results.append(json.dumps(DataSpaceList)) # Position: 9 - Results.append(json.dumps(PredictionSpaceList)) # Position: 10 - Results.append(json.dumps(ModelSpaceTSNE)) # Position: 11 - #Results.append(RFEListPDCon) # Position: 13 - #Results.append(perm_imp_rfpimpCon) # Position: 14 - Results.append(perm_imp_eli5PDCon) # Position: 12 - Results.append(featureScoresCon) # Position: 13 + Results.append(json.dumps(DataSpaceList)) # Position: 7 + Results.append(json.dumps(PredictionSpaceList)) # Position: 8 + Results.append(json.dumps(metricsPerModel)) # Position: 9 + Results.append(perm_imp_eli5PDCon) # Position: 10 + Results.append(featureScoresCon) # Position: 11 return Results # Retrieve data from client @@ -581,7 +557,9 @@ def FeatureSelPerModel(): resultsList = [] global loopFeatures loopFeatures = 2 - for index, eachalgor in enumerate(algorithmList): + + algorithmsWithoutDuplicates = list(dict.fromkeys(algorithmList)) + for index, eachalgor in enumerate(algorithmsWithoutDuplicates): if (eachalgor == 'KNN'): clf = KNeighborsClassifier() params = detailsParams[index] @@ -595,8 +573,7 @@ def FeatureSelPerModel(): if (featureSelection['featureSelection'] == ''): key = 0 else: - key = 2 - EnsembleModel(ClassifierIDsList, key) + key = 2 return 'Everything Okay' def FunMDS (data): @@ -621,11 +598,13 @@ def EnsembleModel (ClassifierIDsList, keyRetrieved): global all_classifiers global algorithmList + algorithmsWithoutDuplicates = list(dict.fromkeys(algorithmList)) if (keyRetrieved == 0): columnsInit = [] all_classifiers = [] columnsInit = [XData.columns.get_loc(c) for c in XData.columns if c in XData] - for index, eachelem in enumerate(algorithmList): + + for index, eachelem in enumerate(algorithmsWithoutDuplicates): if (eachelem == 'KNN'): for each in resultsList[index][1]: all_classifiers.append(make_pipeline(ColumnSelector(cols=columnsInit), KNeighborsClassifier().set_params(**each))) @@ -640,7 +619,7 @@ def EnsembleModel (ClassifierIDsList, keyRetrieved): random_state=RANDOM_SEED, n_jobs = -1) elif (keyRetrieved == 1): - ClassifierIDsList = json.loads(ClassifierIDsList) + ClassifierIDsList = json.loads(ClassifierIDsList) for loop in ClassifierIDsList['ClassifiersList']: temp = [int(s) for s in re.findall(r'\b\d+\b', loop)] all_classifiersSelection.append(all_classifiers[temp[0]]) @@ -656,7 +635,7 @@ def EnsembleModel (ClassifierIDsList, keyRetrieved): lr = LogisticRegression() if (len(all_classifiersSelection) == 0): all_classifiers = [] - for index, eachelem in enumerate(algorithmList): + for index, eachelem in enumerate(algorithmsWithoutDuplicates): if (eachelem == 'KNN'): for j, each in enumerate(resultsList[index][1]): all_classifiers.append(make_pipeline(ColumnSelector(cols=columnsReduce[j]), KNeighborsClassifier().set_params(**each))) @@ -671,7 +650,7 @@ def EnsembleModel (ClassifierIDsList, keyRetrieved): random_state=RANDOM_SEED, n_jobs = -1) else: - for index, eachelem in enumerate(algorithmList): + for index, eachelem in enumerate(algorithmsWithoutDuplicates): if (eachelem == 'KNN'): for j, each in enumerate(resultsList[index][1]): all_classifiersSelection.append(make_pipeline(ColumnSelector(cols=columnsReduce[j]), KNeighborsClassifier().set_params(**each))) @@ -726,6 +705,8 @@ def RetrieveModel(): global parametersPerformancePerModel parametersPerformancePerModel = [] global algorithms + global factors + factors = [1,1,1,1,1,1] algorithms = RetrievedModel['Algorithms'] for eachAlgor in algorithms: if (eachAlgor) == 'KNN': @@ -734,22 +715,31 @@ def RetrieveModel(): else: clf = RandomForestClassifier() params = {'n_estimators': list(range(80, 120)), 'criterion': ['gini', 'entropy']} - GridSearchForParameters(clf, params, eachAlgor) + GridSearchForParameters(clf, params, eachAlgor, factors) SendEachClassifiersPerformanceToVisualize() return 'Everything Okay' -def GridSearchForParameters(clf, params, eachAlgor): +def GridSearchForParameters(clf, params, eachAlgor, factors): + global scoring + global NumberofscoringMetrics + + scoring = {'accuracy': 'accuracy', 'f1_macro': 'f1_weighted', 'precision': 'precision_weighted', 'recall': 'recall_weighted', 'jaccard': 'jaccard_weighted'} + NumberofscoringMetrics = len(scoring) + grid = GridSearchCV(estimator=clf, param_grid=params, - scoring='accuracy', + scoring=scoring, cv=crossValidation, + refit='accuracy', n_jobs = -1) grid.fit(XData, yData) + yPredict = grid.predict(XData) cv_results = [] cv_results.append(grid.cv_results_) df_cv_results = pd.DataFrame.from_dict(cv_results) number_of_classifiers = len(df_cv_results.iloc[0][0]) number_of_columns = len(df_cv_results.iloc[0]) + df_cv_results_per_item = [] df_cv_results_per_row = [] @@ -761,9 +751,42 @@ def GridSearchForParameters(clf, params, eachAlgor): df_cv_results_classifiers = pd.DataFrame(data = df_cv_results_per_row, columns= df_cv_results.columns) global allParametersPerformancePerModel - parametersPerformancePerModel = df_cv_results_classifiers[['mean_test_score','params']] + global parametersPerformancePerModel + + metrics = df_cv_results_classifiers.copy() + del metrics['mean_fit_time'] + del metrics['mean_score_time'] + metrics = metrics.ix[:, 0:NumberofscoringMetrics] + sumperModel = [] + global rowSum + for index, row in metrics.iterrows(): + rowSum = 0 + lengthFactors = NumberofscoringMetrics + for loop,elements in enumerate(row): + lengthFactors = lengthFactors - 1 + factors[loop] + rowSum = elements*factors[loop] + rowSum + if lengthFactors is 0: + sumperModel = 0 + else: + sumperModel.append(rowSum/lengthFactors) + global target_names + global PerClassMetric + global PerClassMetricPandas + PerClassMetric = [] + yPredictProb.append(grid.predict_proba(XData)) + PerClassMetric.append(classification_report(yData, yPredict, target_names=target_names, digits=2, output_dict=True)) + PerClassMetricPandas = pd.DataFrame(PerClassMetric) + del PerClassMetricPandas['accuracy'] + del PerClassMetricPandas['macro avg'] + del PerClassMetricPandas['weighted avg'] + summarizedMetrics = pd.DataFrame(sumperModel) + summarizedMetrics.rename(columns={0:'sum'}) + parameters = pd.DataFrame(df_cv_results_classifiers['params']) + parametersPerformancePerModel = pd.concat([summarizedMetrics, parameters], axis=1) + PerClassMetricPandas = PerClassMetricPandas.to_json() parametersPerformancePerModel = parametersPerformancePerModel.to_json() allParametersPerformancePerModel.append(parametersPerformancePerModel) + allParametersPerformancePerModel.append(PerClassMetricPandas) return 'Everything is okay' #GridSearchForParameters = mem.cache(GridSearchForParameters) @@ -772,7 +795,7 @@ def GridSearchForParameters(clf, params, eachAlgor): @app.route('/data/PerformanceForEachModel', methods=["GET", "POST"]) def SendEachClassifiersPerformanceToVisualize (): response = { - 'PerformancePerModel': allParametersPerformancePerModel + 'PerformancePerModel': allParametersPerformancePerModel, } return jsonify(response) @@ -780,7 +803,13 @@ def Remove(duplicate): final_list = [] for num in duplicate: if num not in final_list: - final_list.append(num) + if (isinstance(num, float)): + if np.isnan(num): + pass + else: + final_list.append(int(num)) + else: + final_list.append(num) return final_list # Retrieve data from client @@ -789,45 +818,174 @@ def Remove(duplicate): def RetrieveModelsParam(): RetrieveModelsPar = request.get_data().decode('utf8').replace("'", '"') RetrieveModelsPar = json.loads(RetrieveModelsPar) - algorithm = RetrieveModelsPar['algorithm'] - RetrieveModelsParPandas = pd.DataFrame(RetrieveModelsPar['brushed']) - RetrieveModelsParPandas = RetrieveModelsParPandas.drop(columns=['performance']) - RetrieveModelsParPandas = RetrieveModelsParPandas.drop(columns=['model']) - RetrieveModelsParPandas = RetrieveModelsParPandas.to_dict(orient='list') + + global algorithmList + algorithmList = RetrieveModelsPar['algorithms'] + count = [] + if ('KNN' in algorithmList): + count.append('KNN') + if ('RF' in algorithmList): + count.append('RF') + + global detailsParams + results = [] + counter1 = 0 + counter2 = 0 + for index, items in enumerate(algorithmList): + if (items == 'KNN'): + counter1 = counter1 + 1 + else: + counter2 = counter2 + 1 + + output = pd.DataFrame() + for d in RetrieveModelsPar['parameters']: + output = output.append(json.loads(d), ignore_index=True) + RetrieveModelsPandSel = output.loc[0:counter1,:] + RetrieveModelsPandSel2 = output.loc[counter1:counter1+counter2,:] + RetrieveModelsPandSelDic = RetrieveModelsPandSel.to_dict(orient='list') + RetrieveModelsPandSelDic2 = RetrieveModelsPandSel2.to_dict(orient='list') + RetrieveModels = {} - for key, value in RetrieveModelsParPandas.items(): + for key, value in RetrieveModelsPandSelDic.items(): withoutDuplicates = Remove(value) RetrieveModels[key] = withoutDuplicates - global RetrieveModelsList - RetrieveModelsList.append(RetrieveModels) - global classifierID - global algorithmList - global detailsParams + RetrieveModels2 = {} + for key, value in RetrieveModelsPandSelDic2.items(): + withoutDuplicates = Remove(value) + RetrieveModels2[key] = withoutDuplicates + global resultsList + resultsList = [] + for alg in count: + if (alg == 'KNN'): + clf = KNeighborsClassifier() + params = RetrieveModels + detailsParams.append(params) + results.append(GridSearch(clf, params)) + resultsList.append(results[0]) + elif (alg == 'RF'): + clf = RandomForestClassifier() + params = RetrieveModels2 + detailsParams.append(params) + results.append(GridSearch(clf, params)) + resultsList.append(results[0]) + else: + pass + return 'Everything Okay' + +# Retrieve data from client +@cross_origin(origin='localhost',headers=['Content-Type','Authorization']) +@app.route('/data/FeaturesScoresUpdate', methods=["GET", "POST"]) +def UpdateBarChartLine(): + RetrieveModelsforUpdate = request.get_data().decode('utf8').replace("'", '"') + RetrieveModelsforUpdate = json.loads(RetrieveModelsforUpdate) + algorithms = RetrieveModelsforUpdate['algorithms'] + count = [] + if ('KNN' in algorithms): + count.append('KNN') + else: + count.append(0) + if ('RF' in algorithms): + count.append('RF') + else: + count.append(0) + results = [] - algorithmList.append(algorithm) - if (algorithm == 'KNN'): - clf = KNeighborsClassifier() - params = RetrieveModels - detailsParams.append(params) - results.append(GridSearch(clf, params)) - resultsList.append(results[0]) - for j, oneClassifier in enumerate(results[0][1]): - classifiersId.append(classifierID) - classifiersIDPlusParams.append(classifierID) - classifierID = classifierID + 1 - elif (algorithm == 'RF'): - clf = RandomForestClassifier() - params = RetrieveModels - detailsParams.append(params) - results.append(GridSearch(clf, params)) - resultsList.append(results[0]) - for oneClassifier, j in enumerate(results[0][1]): - classifiersIDPlusParams.append(classifierID) - classifiersIDwithFI.append(classifierID) - classifierID = classifierID + 1 + counter1 = 0 + counter2 = 0 + for index, items in enumerate(algorithms): + if (items == 'KNN'): + counter1 = counter1 + 1 + else: + counter2 = counter2 + 1 + + output = pd.DataFrame() + output2 = pd.DataFrame() + loop = 0 + for d in RetrieveModelsforUpdate['parameters']: + if (loop < counter1): + output = output.append(json.loads(d), ignore_index=True) + else: + output2 = output2.append(json.loads(d), ignore_index=True) + loop = loop + 1 + output.dropna(axis='columns') + output2.dropna(axis='columns') + + if (output.empty): + pass else: + RetrieveModelsPandSel = output.loc[0:counter1,:] + RetrieveModelsPandSelDic = RetrieveModelsPandSel.to_dict(orient='list') + RetrieveModels = {} + for key, value in RetrieveModelsPandSelDic.items(): + withoutDuplicates = Remove(value) + RetrieveModels[key] = withoutDuplicates + + if (output2.empty): pass + else: + RetrieveModelsPandSel2 = output2.loc[0:counter2,:] + RetrieveModelsPandSelDic2 = RetrieveModelsPandSel2.to_dict(orient='list') + RetrieveModels2 = {} + for key, value in RetrieveModelsPandSelDic2.items(): + withoutDuplicates = Remove(value) + RetrieveModels2[key] = withoutDuplicates + + factors = [1,1,1,1,1,1] + global allParametersPerformancePerModelUpdate + allParametersPerformancePerModelUpdate = [] + for alg in count: + if (alg == 'KNN'): + clf = KNeighborsClassifier() + params = RetrieveModels + GridSearchForUpdate(clf, params, factors) + elif (alg == 'RF'): + clf = RandomForestClassifier() + params = RetrieveModels2 + GridSearchForUpdate(clf, params, factors) + else: + allParametersPerformancePerModelUpdate.append(0) + SendEachClassifiersPerformanceToVisualizeLinePlot() return 'Everything Okay' - \ No newline at end of file + +def GridSearchForUpdate(clf, params, factors): + global scoring + global NumberofscoringMetrics + scoring = {'accuracy': 'accuracy', 'f1_macro': 'f1_weighted', 'precision': 'precision_weighted', 'recall': 'recall_weighted', 'jaccard': 'jaccard_weighted'} + NumberofscoringMetrics = len(scoring) + + grid = GridSearchCV(estimator=clf, + param_grid=params, + scoring=scoring, + cv=crossValidation, + refit='accuracy', + n_jobs = -1) + grid.fit(XData, yData) + yPredict = grid.predict(XData) + + global allParametersPerformancePerModelUpdate + + global target_names + global PerClassUpd + global PerClassMetricUpdate + PerClassUpd = [] + PerClassMetricUpdate = [] + PerClassUpd.append(classification_report(yData, yPredict, target_names=target_names, digits=2, output_dict=True)) + PerClassMetricUpdate = pd.DataFrame(PerClassUpd) + del PerClassMetricUpdate['accuracy'] + del PerClassMetricUpdate['macro avg'] + del PerClassMetricUpdate['weighted avg'] + PerClassMetricUpdate = PerClassMetricUpdate.to_json() + allParametersPerformancePerModelUpdate.append(PerClassMetricUpdate) + return 'Everything is okay' + + +# Sending each model's results +@app.route('/data/UpdatePerFeaturePerformance', methods=["GET", "POST"]) +def SendEachClassifiersPerformanceToVisualizeLinePlot (): + global allParametersPerformancePerModelUpdate + response = { + 'PerformanceCheck': allParametersPerformancePerModelUpdate, + } + return jsonify(response) \ No newline at end of file