From 868014bfc36b05027ac301fd65b84b83376674af Mon Sep 17 00:00:00 2001 From: mustafabawany Date: Sun, 13 Aug 2023 06:00:20 -0700 Subject: [PATCH 1/7] Restructured code for better understanding --- package-lock.json | 1823 ++++++++++++++++++++++++++++--------------- scripts/leetcode.js | 372 +++++---- 2 files changed, 1415 insertions(+), 780 deletions(-) diff --git a/package-lock.json b/package-lock.json index 12ec8879..b6770434 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,422 +1,551 @@ { "name": "LeetHub", "version": "0.0.9", - "lockfileVersion": 1, + "lockfileVersion": 3, "requires": true, - "dependencies": { - "@babel/code-frame": { + "packages": { + "": { + "name": "LeetHub", + "version": "0.0.9", + "devDependencies": { + "eslint": "^7.2.0", + "eslint-config-airbnb": "^18.2.1", + "eslint-config-prettier": "^6.15.0", + "eslint-plugin-import": "^2.22.1", + "eslint-plugin-jsx-a11y": "^6.4.1", + "eslint-plugin-prettier": "^3.1.4", + "eslint-plugin-react": "^7.21.5", + "eslint-plugin-react-hooks": "^4.0.0", + "prettier": "^2.2.1" + } + }, + "node_modules/@babel/code-frame": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", "dev": true, - "requires": { + "dependencies": { "@babel/highlight": "^7.10.4" } }, - "@babel/helper-validator-identifier": { + "node_modules/@babel/helper-validator-identifier": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", "dev": true }, - "@babel/highlight": { + "node_modules/@babel/highlight": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", "js-tokens": "^4.0.0" - }, + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, "dependencies": { - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - } + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" } }, - "@babel/runtime": { + "node_modules/@babel/runtime": { "version": "7.12.5", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", "dev": true, - "requires": { + "dependencies": { "regenerator-runtime": "^0.13.4" } }, - "@babel/runtime-corejs3": { + "node_modules/@babel/runtime-corejs3": { "version": "7.12.5", "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.12.5.tgz", "integrity": "sha512-roGr54CsTmNPPzZoCP1AmDXuBoNao7tnSA83TXTwt+UK5QVyh1DIJnrgYRPWKCF2flqZQXwa7Yr8v7VmLzF0YQ==", "dev": true, - "requires": { + "dependencies": { "core-js-pure": "^3.0.0", "regenerator-runtime": "^0.13.4" } }, - "@types/json5": { + "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true }, - "acorn": { + "node_modules/acorn": { "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } }, - "acorn-jsx": { + "node_modules/acorn-jsx": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", - "dev": true + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } }, - "ajv": { + "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "requires": { + "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "ansi-escapes": { + "node_modules/ansi-escapes": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", "dev": true, - "requires": { + "dependencies": { "type-fest": "^0.11.0" }, - "dependencies": { - "type-fest": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", - "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", - "dev": true - } + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "ansi-regex": { + "node_modules/ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "ansi-styles": { + "node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "requires": { + "dependencies": { "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" } }, - "argparse": { + "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, - "requires": { + "dependencies": { "sprintf-js": "~1.0.2" } }, - "aria-query": { + "node_modules/aria-query": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", "dev": true, - "requires": { + "dependencies": { "@babel/runtime": "^7.10.2", "@babel/runtime-corejs3": "^7.10.2" + }, + "engines": { + "node": ">=6.0" } }, - "array-includes": { + "node_modules/array-includes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.2.tgz", "integrity": "sha512-w2GspexNQpx+PutG3QpT437/BenZBj0M/MZGn5mzv/MofYqo0xmRHzn4lFsoDlWJ+THYsGJmFlW68WlDFx7VRw==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", "es-abstract": "^1.18.0-next.1", "get-intrinsic": "^1.0.1", "is-string": "^1.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "array.prototype.flat": { + "node_modules/array.prototype.flat": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", "es-abstract": "^1.18.0-next.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "array.prototype.flatmap": { + "node_modules/array.prototype.flatmap": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz", "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", "es-abstract": "^1.18.0-next.1", "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "ast-types-flow": { + "node_modules/ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", "dev": true }, - "astral-regex": { + "node_modules/astral-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "axe-core": { + "node_modules/axe-core": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.1.1.tgz", "integrity": "sha512-5Kgy8Cz6LPC9DJcNb3yjAXTu3XihQgEdnIg50c//zOC/MyLP0Clg+Y8Sh9ZjjnvBrDZU4DgXS9C3T9r4/scGZQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "axobject-query": { + "node_modules/axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==", "dev": true }, - "balanced-match": { + "node_modules/balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, - "brace-expansion": { + "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "requires": { + "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "call-bind": { + "node_modules/call-bind": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz", "integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==", "dev": true, - "requires": { + "dependencies": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "callsites": { + "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "chalk": { + "node_modules/chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", "dev": true, - "requires": { + "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "chardet": { + "node_modules/chalk/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/chalk/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/chalk/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, - "cli-cursor": { + "node_modules/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": { + "dependencies": { "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" } }, - "cli-width": { + "node_modules/cli-width": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", - "dev": true + "dev": true, + "engines": { + "node": ">= 10" + } }, - "color-convert": { + "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "requires": { + "dependencies": { "color-name": "1.1.3" } }, - "color-name": { + "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, - "concat-map": { + "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "confusing-browser-globals": { + "node_modules/confusing-browser-globals": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz", "integrity": "sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA==", "dev": true }, - "contains-path": { + "node_modules/contains-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "core-js-pure": { + "node_modules/core-js-pure": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.8.0.tgz", "integrity": "sha512-fRjhg3NeouotRoIV0L1FdchA6CK7ZD+lyINyMoz19SyV+ROpC4noS1xItWHFtwZdlqfMfVPJEyEGdfri2bD1pA==", - "dev": true + "deprecated": "core-js-pure@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js-pure.", + "dev": true, + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } }, - "cross-spawn": { + "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, - "requires": { + "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" } }, - "damerau-levenshtein": { + "node_modules/damerau-levenshtein": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz", "integrity": "sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug==", "dev": true }, - "debug": { + "node_modules/debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, - "requires": { + "dependencies": { "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "deep-is": { + "node_modules/deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, - "define-properties": { + "node_modules/define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", "dev": true, - "requires": { + "dependencies": { "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" } }, - "doctrine": { + "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, - "requires": { + "dependencies": { "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" } }, - "emoji-regex": { + "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "error-ex": { + "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, - "requires": { + "dependencies": { "is-arrayish": "^0.2.1" } }, - "es-abstract": { + "node_modules/es-abstract": { "version": "1.18.0-next.1", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", "dev": true, - "requires": { + "dependencies": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", @@ -429,31 +558,46 @@ "object.assign": "^4.1.1", "string.prototype.trimend": "^1.0.1", "string.prototype.trimstart": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "es-to-primitive": { + "node_modules/es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, - "requires": { + "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "escape-string-regexp": { + "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.8.0" + } }, - "eslint": { + "node_modules/eslint": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.2.0.tgz", "integrity": "sha512-B3BtEyaDKC5MlfDa2Ha8/D6DsS4fju95zs0hjS3HdGazw+LNayai38A25qMppK37wWGWNYSPOR6oYzlz5MHsRQ==", "dev": true, - "requires": { + "dependencies": { "@babel/code-frame": "^7.0.0", "ajv": "^6.10.0", "chalk": "^4.0.0", @@ -490,99 +634,130 @@ "table": "^5.2.3", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "eslint-config-airbnb": { + "node_modules/eslint-config-airbnb": { "version": "18.2.1", "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-18.2.1.tgz", "integrity": "sha512-glZNDEZ36VdlZWoxn/bUR1r/sdFKPd1mHPbqUtkctgNG4yT2DLLtJ3D+yCV+jzZCc2V1nBVkmdknOJBZ5Hc0fg==", "dev": true, - "requires": { + "dependencies": { "eslint-config-airbnb-base": "^14.2.1", "object.assign": "^4.1.2", "object.entries": "^1.1.2" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "eslint": "^5.16.0 || ^6.8.0 || ^7.2.0", + "eslint-plugin-import": "^2.22.1", + "eslint-plugin-jsx-a11y": "^6.4.1", + "eslint-plugin-react": "^7.21.5", + "eslint-plugin-react-hooks": "^4 || ^3 || ^2.3.0 || ^1.7.0" } }, - "eslint-config-airbnb-base": { + "node_modules/eslint-config-airbnb-base": { "version": "14.2.1", "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz", "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==", "dev": true, - "requires": { + "dependencies": { "confusing-browser-globals": "^1.0.10", "object.assign": "^4.1.2", "object.entries": "^1.1.2" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "eslint": "^5.16.0 || ^6.8.0 || ^7.2.0", + "eslint-plugin-import": "^2.22.1" } }, - "eslint-config-prettier": { + "node_modules/eslint-config-prettier": { "version": "6.15.0", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz", "integrity": "sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw==", "dev": true, - "requires": { + "dependencies": { "get-stdin": "^6.0.0" + }, + "bin": { + "eslint-config-prettier-check": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=3.14.1" } }, - "eslint-import-resolver-node": { + "node_modules/eslint-import-resolver-node": { "version": "0.3.4", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", "dev": true, - "requires": { + "dependencies": { "debug": "^2.6.9", "resolve": "^1.13.1" - }, + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } + "ms": "2.0.0" } }, - "eslint-module-utils": { + "node_modules/eslint-import-resolver-node/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/eslint-module-utils": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz", "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==", "dev": true, - "requires": { + "dependencies": { "debug": "^2.6.9", "pkg-dir": "^2.0.0" }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } + "ms": "2.0.0" } }, - "eslint-plugin-import": { + "node_modules/eslint-module-utils/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/eslint-plugin-import": { "version": "2.22.1", "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz", "integrity": "sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==", "dev": true, - "requires": { + "dependencies": { "array-includes": "^3.1.1", "array.prototype.flat": "^1.2.3", "contains-path": "^0.1.0", @@ -597,40 +772,47 @@ "resolve": "^1.17.0", "tsconfig-paths": "^3.9.0" }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } + "ms": "2.0.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "dependencies": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "eslint-plugin-jsx-a11y": { + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/eslint-plugin-jsx-a11y": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.4.1.tgz", "integrity": "sha512-0rGPJBbwHoGNPU73/QCLP/vveMlM1b1Z9PponxO87jfr6tuH5ligXbDT6nHSSzBC8ovX2Z+BQu7Bk5D/Xgq9zg==", "dev": true, - "requires": { + "dependencies": { "@babel/runtime": "^7.11.2", "aria-query": "^4.2.2", "array-includes": "^3.1.1", @@ -643,30 +825,41 @@ "jsx-ast-utils": "^3.1.0", "language-tags": "^1.0.5" }, - "dependencies": { - "emoji-regex": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.0.tgz", - "integrity": "sha512-DNc3KFPK18bPdElMJnf/Pkv5TXhxFU3YFDEuGLDRtPmV4rkmCjBkCSEp22u6rBHdSN9Vlp/GK7k98prmE1Jgug==", - "dev": true - } + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7" } }, - "eslint-plugin-prettier": { + "node_modules/eslint-plugin-jsx-a11y/node_modules/emoji-regex": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.0.tgz", + "integrity": "sha512-DNc3KFPK18bPdElMJnf/Pkv5TXhxFU3YFDEuGLDRtPmV4rkmCjBkCSEp22u6rBHdSN9Vlp/GK7k98prmE1Jgug==", + "dev": true + }, + "node_modules/eslint-plugin-prettier": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.4.tgz", "integrity": "sha512-jZDa8z76klRqo+TdGDTFJSavwbnWK2ZpqGKNZ+VvweMW516pDUMmQ2koXvxEE4JhzNvTv+radye/bWGBmA6jmg==", "dev": true, - "requires": { + "dependencies": { "prettier-linter-helpers": "^1.0.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "peerDependencies": { + "eslint": ">=5.0.0", + "prettier": ">=1.13.0" } }, - "eslint-plugin-react": { + "node_modules/eslint-plugin-react": { "version": "7.21.5", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.21.5.tgz", "integrity": "sha512-8MaEggC2et0wSF6bUeywF7qQ46ER81irOdWS4QWxnnlAEsnzeBevk1sWh7fhpCghPpXb+8Ks7hvaft6L/xsR6g==", "dev": true, - "requires": { + "dependencies": { "array-includes": "^3.1.1", "array.prototype.flatmap": "^1.2.3", "doctrine": "^2.1.0", @@ -679,344 +872,456 @@ "resolve": "^1.18.1", "string.prototype.matchall": "^4.0.2" }, - "dependencies": { - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - } + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7" } }, - "eslint-plugin-react-hooks": { + "node_modules/eslint-plugin-react-hooks": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.0.0.tgz", "integrity": "sha512-YKBY+kilK5wrwIdQnCF395Ya6nDro3EAMoe+2xFkmyklyhF16fH83TrQOo9zbZIDxBsXFgBbywta/0JKRNFDkw==", - "dev": true + "dev": true, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } }, - "eslint-scope": { + "node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, - "requires": { + "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" } }, - "eslint-utils": { + "node_modules/eslint-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, - "requires": { + "dependencies": { "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" } }, - "eslint-visitor-keys": { + "node_modules/eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "espree": { + "node_modules/espree": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz", "integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==", "dev": true, - "requires": { + "dependencies": { "acorn": "^7.4.0", "acorn-jsx": "^5.2.0", "eslint-visitor-keys": "^1.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" } }, - "esprima": { + "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } }, - "esquery": { + "node_modules/esquery": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", "dev": true, - "requires": { + "dependencies": { "estraverse": "^5.1.0" }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } + "engines": { + "node": ">=0.10" } }, - "esrecurse": { + "node_modules/esquery/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, - "requires": { + "dependencies": { "estraverse": "^5.2.0" }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" } }, - "estraverse": { + "node_modules/estraverse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true + "dev": true, + "engines": { + "node": ">=4.0" + } }, - "esutils": { + "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "external-editor": { + "node_modules/external-editor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "dev": true, - "requires": { + "dependencies": { "chardet": "^0.7.0", "iconv-lite": "^0.4.24", "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" } }, - "fast-deep-equal": { + "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "fast-diff": { + "node_modules/fast-diff": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", "dev": true }, - "fast-json-stable-stringify": { + "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, - "fast-levenshtein": { + "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, - "figures": { + "node_modules/figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "dev": true, - "requires": { + "dependencies": { "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "file-entry-cache": { + "node_modules/file-entry-cache": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", "dev": true, - "requires": { + "dependencies": { "flat-cache": "^2.0.1" + }, + "engines": { + "node": ">=4" } }, - "find-up": { + "node_modules/find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, - "requires": { + "dependencies": { "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" } }, - "flat-cache": { + "node_modules/flat-cache": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", "dev": true, - "requires": { + "dependencies": { "flatted": "^2.0.0", "rimraf": "2.6.3", "write": "1.0.3" + }, + "engines": { + "node": ">=4" } }, - "flatted": { + "node_modules/flatted": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", "dev": true }, - "fs.realpath": { + "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "function-bind": { + "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "functional-red-black-tree": { + "node_modules/functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, - "get-intrinsic": { + "node_modules/get-intrinsic": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.1.tgz", "integrity": "sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg==", "dev": true, - "requires": { + "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "get-stdin": { + "node_modules/get-stdin": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "glob": { + "node_modules/glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, - "requires": { + "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "glob-parent": { + "node_modules/glob-parent": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", "dev": true, - "requires": { + "dependencies": { "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" } }, - "globals": { + "node_modules/globals": { "version": "12.4.0", "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", "dev": true, - "requires": { + "dependencies": { "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "graceful-fs": { + "node_modules/graceful-fs": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true }, - "has": { + "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, - "requires": { + "dependencies": { "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" } }, - "has-flag": { + "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "has-symbols": { + "node_modules/has-symbols": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "hosted-git-info": { + "node_modules/hosted-git-info": { "version": "2.8.8", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", "dev": true }, - "iconv-lite": { + "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, - "requires": { + "dependencies": { "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" } }, - "ignore": { + "node_modules/ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true + "dev": true, + "engines": { + "node": ">= 4" + } }, - "import-fresh": { + "node_modules/import-fresh": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz", "integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==", "dev": true, - "requires": { + "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" } }, - "imurmurhash": { + "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.8.19" + } }, - "inflight": { + "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, - "requires": { + "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, - "inherits": { + "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "inquirer": { + "node_modules/inquirer": { "version": "7.3.3", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", "dev": true, - "requires": { + "dependencies": { "ansi-escapes": "^4.2.1", "chalk": "^4.1.0", "cli-cursor": "^3.1.0", @@ -1030,794 +1335,1038 @@ "string-width": "^4.1.0", "strip-ansi": "^6.0.0", "through": "^2.3.6" + }, + "engines": { + "node": ">=8.0.0" } }, - "internal-slot": { + "node_modules/internal-slot": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.2.tgz", "integrity": "sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g==", "dev": true, - "requires": { + "dependencies": { "es-abstract": "^1.17.0-next.1", "has": "^1.0.3", "side-channel": "^1.0.2" }, - "dependencies": { - "es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/internal-slot/node_modules/es-abstract": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", + "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "dev": true, + "dependencies": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-arrayish": { + "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, - "is-callable": { + "node_modules/is-callable": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "is-core-module": { + "node_modules/is-core-module": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", "dev": true, - "requires": { + "dependencies": { "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-date-object": { + "node_modules/is-date-object": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "is-extglob": { + "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "is-fullwidth-code-point": { + "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "is-glob": { + "node_modules/is-glob": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, - "requires": { + "dependencies": { "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "is-negative-zero": { + "node_modules/is-negative-zero": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz", "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.4" + } }, - "is-regex": { + "node_modules/is-regex": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", "dev": true, - "requires": { + "dependencies": { "has-symbols": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-string": { + "node_modules/is-string": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "is-symbol": { + "node_modules/is-symbol": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", "dev": true, - "requires": { + "dependencies": { "has-symbols": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "isarray": { + "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, - "isexe": { + "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, - "js-tokens": { + "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, - "js-yaml": { + "node_modules/js-yaml": { "version": "3.14.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", "dev": true, - "requires": { + "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "json-schema-traverse": { + "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, - "json-stable-stringify-without-jsonify": { + "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, - "json5": { + "node_modules/json5": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "dev": true, - "requires": { + "dependencies": { "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" } }, - "jsx-ast-utils": { + "node_modules/jsx-ast-utils": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.1.0.tgz", "integrity": "sha512-d4/UOjg+mxAWxCiF0c5UTSwyqbchkbqCvK87aBovhnh8GtysTjWmgC63tY0cJx/HzGgm9qnA147jVBdpOiQ2RA==", "dev": true, - "requires": { + "dependencies": { "array-includes": "^3.1.1", "object.assign": "^4.1.1" + }, + "engines": { + "node": ">=4.0" } }, - "language-subtag-registry": { + "node_modules/language-subtag-registry": { "version": "0.3.21", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz", "integrity": "sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg==", "dev": true }, - "language-tags": { + "node_modules/language-tags": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", "integrity": "sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=", "dev": true, - "requires": { + "dependencies": { "language-subtag-registry": "~0.3.2" } }, - "levn": { + "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, - "requires": { + "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" } }, - "load-json-file": { + "node_modules/load-json-file": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "dev": true, - "requires": { + "dependencies": { "graceful-fs": "^4.1.2", "parse-json": "^2.2.0", "pify": "^2.0.0", "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "locate-path": { + "node_modules/locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "dev": true, - "requires": { + "dependencies": { "p-locate": "^2.0.0", "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "lodash": { + "node_modules/lodash": { "version": "4.17.20", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", "dev": true }, - "loose-envify": { + "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "dev": true, - "requires": { + "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" } }, - "lru-cache": { + "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, - "requires": { + "dependencies": { "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, - "mimic-fn": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=6" + } }, - "minimatch": { + "node_modules/minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, - "requires": { + "dependencies": { "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "minimist": { + "node_modules/minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, - "mkdirp": { + "node_modules/mkdirp": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, - "requires": { + "dependencies": { "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" } }, - "ms": { + "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "mute-stream": { + "node_modules/mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, - "natural-compare": { + "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "normalize-package-data": { + "node_modules/normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, - "requires": { + "dependencies": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } } }, - "object-assign": { + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "object-inspect": { + "node_modules/object-inspect": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", - "dev": true + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "object-keys": { + "node_modules/object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.4" + } }, - "object.assign": { + "node_modules/object.assign": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", "has-symbols": "^1.0.1", "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "object.entries": { + "node_modules/object.entries": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.3.tgz", "integrity": "sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", "es-abstract": "^1.18.0-next.1", "has": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" } }, - "object.fromentries": { + "node_modules/object.fromentries": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.3.tgz", "integrity": "sha512-IDUSMXs6LOSJBWE++L0lzIbSqHl9KDCfff2x/JSEIDtEUavUnyMYC2ZGay/04Zq4UT8lvd4xNhU4/YHKibAOlw==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", "es-abstract": "^1.18.0-next.1", "has": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "object.values": { + "node_modules/object.values": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.2.tgz", "integrity": "sha512-MYC0jvJopr8EK6dPBiO8Nb9mvjdypOachO5REGk6MXzujbBrAisKo3HmdEI6kZDL6fC31Mwee/5YbtMebixeag==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", "es-abstract": "^1.18.0-next.1", "has": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "once": { + "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, - "requires": { + "dependencies": { "wrappy": "1" } }, - "onetime": { + "node_modules/onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, - "requires": { + "dependencies": { "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "optionator": { + "node_modules/optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, - "requires": { + "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" } }, - "os-tmpdir": { + "node_modules/os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "p-limit": { + "node_modules/p-limit": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", "dev": true, - "requires": { + "dependencies": { "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" } }, - "p-locate": { + "node_modules/p-locate": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, - "requires": { + "dependencies": { "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" } }, - "p-try": { + "node_modules/p-try": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "parent-module": { + "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, - "requires": { + "dependencies": { "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "parse-json": { + "node_modules/parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, - "requires": { + "dependencies": { "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "path-exists": { + "node_modules/path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "path-is-absolute": { + "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "path-key": { + "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "path-parse": { + "node_modules/path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, - "path-type": { + "node_modules/path-type": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", "dev": true, - "requires": { + "dependencies": { "pify": "^2.0.0" + }, + "engines": { + "node": ">=4" } }, - "pify": { + "node_modules/pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "pkg-dir": { + "node_modules/pkg-dir": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", "dev": true, - "requires": { + "dependencies": { "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" } }, - "prelude-ls": { + "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.8.0" + } }, - "prettier": { + "node_modules/prettier": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", - "dev": true + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } }, - "prettier-linter-helpers": { + "node_modules/prettier-linter-helpers": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", "dev": true, - "requires": { + "dependencies": { "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" } }, - "progress": { + "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.4.0" + } }, - "prop-types": { + "node_modules/prop-types": { "version": "15.7.2", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", "dev": true, - "requires": { + "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.8.1" } }, - "punycode": { + "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "react-is": { + "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true }, - "read-pkg": { + "node_modules/read-pkg": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", "dev": true, - "requires": { + "dependencies": { "load-json-file": "^2.0.0", "normalize-package-data": "^2.3.2", "path-type": "^2.0.0" + }, + "engines": { + "node": ">=4" } }, - "read-pkg-up": { + "node_modules/read-pkg-up": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", "dev": true, - "requires": { + "dependencies": { "find-up": "^2.0.0", "read-pkg": "^2.0.0" + }, + "engines": { + "node": ">=4" } }, - "regenerator-runtime": { + "node_modules/regenerator-runtime": { "version": "0.13.7", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", "dev": true }, - "regexp.prototype.flags": { + "node_modules/regexp.prototype.flags": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", "dev": true, - "requires": { + "dependencies": { "define-properties": "^1.1.3", "es-abstract": "^1.17.0-next.1" }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags/node_modules/es-abstract": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", + "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "dev": true, "dependencies": { - "es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "regexpp": { + "node_modules/regexpp": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } }, - "resolve": { + "node_modules/resolve": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", "dev": true, - "requires": { + "dependencies": { "is-core-module": "^2.1.0", "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "resolve-from": { + "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "restore-cursor": { + "node_modules/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": { + "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" } }, - "rimraf": { + "node_modules/rimraf": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, - "requires": { + "dependencies": { "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" } }, - "run-async": { + "node_modules/run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.12.0" + } }, - "rxjs": { + "node_modules/rxjs": { "version": "6.6.3", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz", "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==", "dev": true, - "requires": { + "dependencies": { "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" } }, - "safer-buffer": { + "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "semver": { + "node_modules/semver": { "version": "7.3.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", "dev": true, - "requires": { + "dependencies": { "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "shebang-command": { + "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "requires": { + "dependencies": { "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "shebang-regex": { + "node_modules/shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "side-channel": { + "node_modules/side-channel": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.3.tgz", "integrity": "sha512-A6+ByhlLkksFoUepsGxfj5x1gTSrs+OydsRptUxeNCabQpCFUvcwIczgOigI8vhY/OJCnPnyE9rGiwgvr9cS1g==", "dev": true, - "requires": { + "dependencies": { "es-abstract": "^1.18.0-next.0", "object-inspect": "^1.8.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "signal-exit": { + "node_modules/signal-exit": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", "dev": true }, - "slice-ansi": { + "node_modules/slice-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", "dev": true, - "requires": { + "dependencies": { "ansi-styles": "^3.2.0", "astral-regex": "^1.0.0", "is-fullwidth-code-point": "^2.0.0" }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - } + "engines": { + "node": ">=6" + } + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" } }, - "spdx-correct": { + "node_modules/spdx-correct": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", "dev": true, - "requires": { + "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, - "spdx-exceptions": { + "node_modules/spdx-exceptions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", "dev": true }, - "spdx-expression-parse": { + "node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, - "requires": { + "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, - "spdx-license-ids": { + "node_modules/spdx-license-ids": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", "dev": true }, - "sprintf-js": { + "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, - "string-width": { + "node_modules/string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "dev": true, - "requires": { + "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" } }, - "string.prototype.matchall": { + "node_modules/string.prototype.matchall": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.3.tgz", "integrity": "sha512-OBxYDA2ifZQ2e13cP82dWFMaCV9CGF8GzmN4fljBVw5O5wep0lu4gacm1OL6MjROoUnB8VbkWRThqkV2YFLNxw==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", "es-abstract": "^1.18.0-next.1", @@ -1825,220 +2374,278 @@ "internal-slot": "^1.0.2", "regexp.prototype.flags": "^1.3.0", "side-channel": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "string.prototype.trimend": { + "node_modules/string.prototype.trimend": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.0", "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "string.prototype.trimstart": { + "node_modules/string.prototype.trimstart": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", "dev": true, - "requires": { + "dependencies": { "call-bind": "^1.0.0", "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "strip-ansi": { + "node_modules/strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, - "requires": { + "dependencies": { "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" } }, - "strip-bom": { + "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "strip-json-comments": { + "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "supports-color": { + "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, - "requires": { + "dependencies": { "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "table": { + "node_modules/table": { "version": "5.4.6", "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", "dev": true, - "requires": { + "dependencies": { "ajv": "^6.10.2", "lodash": "^4.17.14", "slice-ansi": "^2.1.0", "string-width": "^3.0.0" }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/table/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/table/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/table/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/table/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" } }, - "text-table": { + "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, - "through": { + "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, - "tmp": { + "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, - "requires": { + "dependencies": { "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" } }, - "tsconfig-paths": { + "node_modules/tsconfig-paths": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", "dev": true, - "requires": { + "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.1", "minimist": "^1.2.0", "strip-bom": "^3.0.0" } }, - "tslib": { + "node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, - "type-check": { + "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, - "requires": { + "dependencies": { "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" } }, - "type-fest": { + "node_modules/type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "uri-js": { + "node_modules/uri-js": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", "dev": true, - "requires": { + "dependencies": { "punycode": "^2.1.0" } }, - "v8-compile-cache": { + "node_modules/v8-compile-cache": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", "dev": true }, - "validate-npm-package-license": { + "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, - "requires": { + "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, - "which": { + "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "requires": { + "dependencies": { "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, - "word-wrap": { + "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "wrappy": { + "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "write": { + "node_modules/write": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", "dev": true, - "requires": { + "dependencies": { "mkdirp": "^0.5.1" + }, + "engines": { + "node": ">=4" } }, - "yallist": { + "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", diff --git a/scripts/leetcode.js b/scripts/leetcode.js index a4569f25..fd103402 100644 --- a/scripts/leetcode.js +++ b/scripts/leetcode.js @@ -36,25 +36,155 @@ let difficulty = ''; /* state of upload for progress */ let uploadState = { uploading: false }; -/* Get file extension for submission */ -function findLanguage() { - const tag = [ - ...document.getElementsByClassName( - 'ant-select-selection-selected-value', - ), - ...document.getElementsByClassName('Select-value-label'), - ]; - if (tag && tag.length > 0) { - for (let i = 0; i < tag.length; i += 1) { - const elem = tag[i].textContent; - if (elem !== undefined && languages[elem] !== undefined) { - return languages[elem]; // should generate respective file extension - } +/* ------------------------------------------------ UTILITY FUNCTIONS ------------------------------------------------------ */ + +/* Util function to check if an element exists */ +function checkElem(elem) { + return elem && elem.length > 0; +} + +function convertToSlug(string) { + const a = + 'àáâäæãåāăąçćčđďèéêëēėęěğǵḧîïíīįìłḿñńǹňôöòóœøōõőṕŕřßśšşșťțûüùúūǘůűųẃẍÿýžźż·/_,:;'; + const b = + 'aaaaaaaaaacccddeeeeeeeegghiiiiiilmnnnnoooooooooprrsssssttuuuuuuuuuwxyyzzz------'; + const p = new RegExp(a.split('').join('|'), 'g'); + + return string + .toString() + .toLowerCase() + .replace(/\s+/g, '-') // Replace spaces with - + .replace(p, (c) => b.charAt(a.indexOf(c))) // Replace special characters + .replace(/&/g, '-and-') // Replace & with 'and' + .replace(/[^\w\-]+/g, '') // Remove all non-word characters + .replace(/\-\-+/g, '-') // Replace multiple - with single - + .replace(/^-+/, '') // Trim - from start of text + .replace(/-+$/, ''); // Trim - from end of text +} + +function addLeadingZeros(title) { + const maxTitlePrefixLength = 4; + var len = title.split('-')[0].length; + if (len < maxTitlePrefixLength) { + return '0'.repeat(4 - len) + title; + } + return title; +} + +/* inject css style required for the upload progress feature */ +function injectStyle() { + const style = document.createElement('style'); + style.textContent = + '.leethub_progress {pointer-events: none;width: 2.0em;height: 2.0em;border: 0.4em solid transparent;border-color: #eee;border-top-color: #3E67EC;border-radius: 50%;animation: loadingspin 1s linear infinite;} @keyframes loadingspin { 100% { transform: rotate(360deg) }}'; + document.head.append(style); +} + +/* This will create a failed tick mark before "Run Code" button signalling that upload failed */ +function markUploadFailed() { + elem = document.getElementById('leethub_progress_elem'); + if (elem) { + elem.className = ''; + style = + 'display: inline-block;transform: rotate(45deg);height:24px;width:12px;border-bottom:7px solid red;border-right:7px solid red;'; + elem.style = style; + } +} + +/* This will create a tick mark before "Run Code" button signalling LeetHub has done its job */ +function markUploaded() { + elem = document.getElementById('leethub_progress_elem'); + if (elem) { + elem.className = ''; + style = + 'display: inline-block;transform: rotate(45deg);height:24px;width:12px;border-bottom:7px solid #78b13f;border-right:7px solid #78b13f;'; + elem.style = style; + } +} + +/* Main parser function for the code */ +function parseCode() { + const e = document.getElementsByClassName('CodeMirror-code'); + if (e !== undefined && e.length > 0) { + const elem = e[0]; + let parsedCode = ''; + const textArr = elem.innerText.split('\n'); + for (let i = 1; i < textArr.length; i += 2) { + parsedCode += `${textArr[i]}\n`; } + return parsedCode; } return null; } +/* we will need specific anchor element that is specific to the page you are in Eg. Explore */ +function insertToAnchorElement(elem) { + if (document.URL.startsWith('https://leetcode.com/explore/')) { + // means we are in explore page + action = document.getElementsByClassName('action'); + if ( + checkElem(action) && + checkElem(action[0].getElementsByClassName('row')) && + checkElem( + action[0] + .getElementsByClassName('row')[0] + .getElementsByClassName('col-sm-6'), + ) && + action[0] + .getElementsByClassName('row')[0] + .getElementsByClassName('col-sm-6').length > 1 + ) { + target = action[0] + .getElementsByClassName('row')[0] + .getElementsByClassName('col-sm-6')[1]; + elem.className = 'pull-left'; + if (target.childNodes.length > 0) + target.childNodes[0].prepend(elem); + } + } else { + if (checkElem(document.getElementsByClassName('action__38Xc'))) { + target = document.getElementsByClassName('action__38Xc')[0]; + elem.className = 'runcode-wrapper__8rXm'; + if (target.childNodes.length > 0) + target.childNodes[0].prepend(elem); + } + } +} + +/* ----------------------------------------- GIT FUNCTIONS ------------------------------------------------------------ */ + +/* Since we dont yet have callbacks/promises that helps to find out if things went bad */ +/* we will start 10 seconds counter and even after that upload is not complete, then we conclude its failed */ +function startUploadCountDown() { + uploadState.uploading = true; + uploadState['countdown'] = setTimeout(() => { + if ((uploadState.uploading = true)) { + // still uploading, then it failed + uploadState.uploading = false; + markUploadFailed(); + } + }, 10000); +} + +/* start upload will inject a spinner on left side to the "Run Code" button */ +function startUpload() { + try { + elem = document.getElementById('leethub_progress_anchor_element'); + if (!elem) { + elem = document.createElement('span'); + elem.id = 'leethub_progress_anchor_element'; + elem.style = 'margin-right: 20px;padding-top: 2px;'; + } + elem.innerHTML = `
`; + target = insertToAnchorElement(elem); + // start the countdown + startUploadCountDown(); + } catch (error) { + // generic exception handler for time being so that existing feature doesnt break but + // error gets logged + console.log(error); + } +} + /* Main function for uploading code to GitHub repo, and callback cb is called if success */ const upload = ( token, @@ -253,6 +383,28 @@ function uploadGit( }); } +/* ----------------------------------------- LEETCODE WEB PAGE PARSING FUNCTIONS ------------------------------------------------------------ */ + + +/* Get file extension for submission */ +function findLanguage() { + const tag = [ + ...document.getElementsByClassName( + 'ant-select-selection-selected-value', + ), + ...document.getElementsByClassName('Select-value-label'), + ]; + if (tag && tag.length > 0) { + for (let i = 0; i < tag.length; i += 1) { + const elem = tag[i].textContent; + if (elem !== undefined && languages[elem] !== undefined) { + return languages[elem]; // should generate respective file extension + } + } + } + return null; +} + /* Function for finding and parsing the full code. */ /* - At first find the submission details url. */ /* - Then send a request for the details page. */ @@ -368,25 +520,7 @@ function findCode( } } -/* Main parser function for the code */ -function parseCode() { - const e = document.getElementsByClassName('CodeMirror-code'); - if (e !== undefined && e.length > 0) { - const elem = e[0]; - let parsedCode = ''; - const textArr = elem.innerText.split('\n'); - for (let i = 1; i < textArr.length; i += 2) { - parsedCode += `${textArr[i]}\n`; - } - return parsedCode; - } - return null; -} -/* Util function to check if an element exists */ -function checkElem(elem) { - return elem && elem.length > 0; -} function convertToSlug(string) { const a = 'àáâäæãåāăąçćčđďèéêëēėęěğǵḧîïíīįìłḿñńǹňôöòóœøōõőṕŕřßśšşșťțûüùúūǘůűųẃẍÿýžźż·/_,:;'; @@ -427,15 +561,6 @@ function getProblemNameSlug() { return addLeadingZeros(convertToSlug(questionTitle)); } -function addLeadingZeros(title) { - const maxTitlePrefixLength = 4; - var len = title.split('-')[0].length; - if (len < maxTitlePrefixLength) { - return '0'.repeat(4 - len) + title; - } - return title; -} - /* Parser function for the question and tags */ function parseQuestion() { var questionUrl = window.location.href; @@ -530,7 +655,7 @@ document.addEventListener('click', (event) => { if ( oldPath !== window.location.pathname && oldPath === - window.location.pathname.substring(0, oldPath.length) && + window.location.pathname.substring(0, oldPath.length) && !Number.isNaN(window.location.pathname.charAt(oldPath.length)) ) { const date = new Date(); @@ -550,38 +675,38 @@ document.addEventListener('click', (event) => { } }); -/* function to get the notes if there is any - the note should be opened atleast once for this to work - this is because the dom is populated after data is fetched by opening the note */ -function getNotesIfAny() { - // there are no notes on expore - if (document.URL.startsWith('https://leetcode.com/explore/')) - return ''; - - notes = ''; - if ( - checkElem(document.getElementsByClassName('notewrap__eHkN')) && - checkElem( - document - .getElementsByClassName('notewrap__eHkN')[0] - .getElementsByClassName('CodeMirror-code'), - ) - ) { - notesdiv = document - .getElementsByClassName('notewrap__eHkN')[0] - .getElementsByClassName('CodeMirror-code')[0]; - if (notesdiv) { - for (i = 0; i < notesdiv.childNodes.length; i++) { - if (notesdiv.childNodes[i].childNodes.length == 0) continue; - text = notesdiv.childNodes[i].childNodes[0].innerText; - if (text) { - notes = `${notes}\n${text.trim()}`.trim(); - } - } - } - } - return notes.trim(); -} +// /* function to get the notes if there is any +// the note should be opened atleast once for this to work +// this is because the dom is populated after data is fetched by opening the note */ +// function getNotesIfAny() { +// // there are no notes on expore +// if (document.URL.startsWith('https://leetcode.com/explore/')) +// return ''; + +// notes = ''; +// if ( +// checkElem(document.getElementsByClassName('notewrap__eHkN')) && +// checkElem( +// document +// .getElementsByClassName('notewrap__eHkN')[0] +// .getElementsByClassName('CodeMirror-code'), +// ) +// ) { +// notesdiv = document +// .getElementsByClassName('notewrap__eHkN')[0] +// .getElementsByClassName('CodeMirror-code')[0]; +// if (notesdiv) { +// for (i = 0; i < notesdiv.childNodes.length; i++) { +// if (notesdiv.childNodes[i].childNodes.length == 0) continue; +// text = notesdiv.childNodes[i].childNodes[0].innerText; +// if (text) { +// notes = `${notes}\n${text.trim()}`.trim(); +// } +// } +// } +// } +// return notes.trim(); +// } const loader = setInterval(() => { let code = null; @@ -701,95 +826,6 @@ const loader = setInterval(() => { } }, 1000); -/* Since we dont yet have callbacks/promises that helps to find out if things went bad */ -/* we will start 10 seconds counter and even after that upload is not complete, then we conclude its failed */ -function startUploadCountDown() { - uploadState.uploading = true; - uploadState['countdown'] = setTimeout(() => { - if ((uploadState.uploading = true)) { - // still uploading, then it failed - uploadState.uploading = false; - markUploadFailed(); - } - }, 10000); -} - -/* we will need specific anchor element that is specific to the page you are in Eg. Explore */ -function insertToAnchorElement(elem) { - if (document.URL.startsWith('https://leetcode.com/explore/')) { - // means we are in explore page - action = document.getElementsByClassName('action'); - if ( - checkElem(action) && - checkElem(action[0].getElementsByClassName('row')) && - checkElem( - action[0] - .getElementsByClassName('row')[0] - .getElementsByClassName('col-sm-6'), - ) && - action[0] - .getElementsByClassName('row')[0] - .getElementsByClassName('col-sm-6').length > 1 - ) { - target = action[0] - .getElementsByClassName('row')[0] - .getElementsByClassName('col-sm-6')[1]; - elem.className = 'pull-left'; - if (target.childNodes.length > 0) - target.childNodes[0].prepend(elem); - } - } else { - if (checkElem(document.getElementsByClassName('action__38Xc'))) { - target = document.getElementsByClassName('action__38Xc')[0]; - elem.className = 'runcode-wrapper__8rXm'; - if (target.childNodes.length > 0) - target.childNodes[0].prepend(elem); - } - } -} - -/* start upload will inject a spinner on left side to the "Run Code" button */ -function startUpload() { - try { - elem = document.getElementById('leethub_progress_anchor_element'); - if (!elem) { - elem = document.createElement('span'); - elem.id = 'leethub_progress_anchor_element'; - elem.style = 'margin-right: 20px;padding-top: 2px;'; - } - elem.innerHTML = `
`; - target = insertToAnchorElement(elem); - // start the countdown - startUploadCountDown(); - } catch (error) { - // generic exception handler for time being so that existing feature doesnt break but - // error gets logged - console.log(error); - } -} - -/* This will create a tick mark before "Run Code" button signalling LeetHub has done its job */ -function markUploaded() { - elem = document.getElementById('leethub_progress_elem'); - if (elem) { - elem.className = ''; - style = - 'display: inline-block;transform: rotate(45deg);height:24px;width:12px;border-bottom:7px solid #78b13f;border-right:7px solid #78b13f;'; - elem.style = style; - } -} - -/* This will create a failed tick mark before "Run Code" button signalling that upload failed */ -function markUploadFailed() { - elem = document.getElementById('leethub_progress_elem'); - if (elem) { - elem.className = ''; - style = - 'display: inline-block;transform: rotate(45deg);height:24px;width:12px;border-bottom:7px solid red;border-right:7px solid red;'; - elem.style = style; - } -} - /* Sync to local storage */ chrome.storage.local.get('isSync', (data) => { keys = [ @@ -815,12 +851,4 @@ chrome.storage.local.get('isSync', (data) => { }); // inject the style -injectStyle(); - -/* inject css style required for the upload progress feature */ -function injectStyle() { - const style = document.createElement('style'); - style.textContent = - '.leethub_progress {pointer-events: none;width: 2.0em;height: 2.0em;border: 0.4em solid transparent;border-color: #eee;border-top-color: #3E67EC;border-radius: 50%;animation: loadingspin 1s linear infinite;} @keyframes loadingspin { 100% { transform: rotate(360deg) }}'; - document.head.append(style); -} +injectStyle(); \ No newline at end of file From 9acaa615ed46c38732403c6a88db7f66d3c47d0d Mon Sep 17 00:00:00 2001 From: mustafabawany Date: Sun, 13 Aug 2023 06:16:39 -0700 Subject: [PATCH 2/7] Fixed updated UI issue --- scripts/leetcode.js | 1022 +++++++++++++++++++------------------------ 1 file changed, 454 insertions(+), 568 deletions(-) diff --git a/scripts/leetcode.js b/scripts/leetcode.js index fd103402..c9624c86 100644 --- a/scripts/leetcode.js +++ b/scripts/leetcode.js @@ -1,25 +1,132 @@ -/* Enum for languages supported by LeetCode. */ -const languages = { - Python: '.py', - Python3: '.py', - 'C++': '.cpp', - C: '.c', - Java: '.java', - 'C#': '.cs', - JavaScript: '.js', - Javascript: '.js', - Ruby: '.rb', - Swift: '.swift', - Go: '.go', - Kotlin: '.kt', - Scala: '.scala', - Rust: '.rs', - PHP: '.php', - TypeScript: '.ts', - MySQL: '.sql', - 'MS SQL Server': '.sql', - Oracle: '.sql', -}; +/* Constants used through out the code */ +const constant = { + elementTags: { + questionTag: "xFUwe", + problemStatsTag: "mt-3", + percentileStatsTag: "mt-2", + difficulty: { + easy: ".text-olive", /* .text-olive is for easy problem */ + medium: ".text-yellow", /* .text-yellow is for medium problem */ + hard: ".text-pink" /* .text-pink is for hard problem */ + }, + problemNameTag: "a.mr-2.text-label-1", + submitButtonTag: '[data-e2e-locator="console-submit-button"]', + successTag: 'span[data-e2e-locator="submission-result"]', + }, + regex: { + percentageRegex: /(\d+(\.\d+)?%)/ + }, + url: { + apiURL: "https://leetcode.com/graphql", + payload: { + getAllSubmissions: `query submissionList($offset: Int!, $limit: Int!, $lastKey: String, $questionSlug: String!, $lang: Int, $status: Int) { + questionSubmissionList( + offset: $offset + limit: $limit + lastKey: $lastKey + questionSlug: $questionSlug + lang: $lang + status: $status + ) { + lastKey + hasNext + submissions { + id + title + titleSlug + status + statusDisplay + lang + langName + runtime + timestamp + url + isPending + memory + hasNotes + notes + } + } + }`, + getSubmission: `query submissionDetails($submissionId: Int!) { + submissionDetails(submissionId: $submissionId) { + runtime + runtimeDisplay + runtimePercentile + runtimeDistribution + memory + memoryDisplay + memoryPercentile + memoryDistribution + code + timestamp + statusCode + user { + username + profile { + realName + userAvatar + } + } + lang { + name + verboseName + } + question { + questionId + acRate + difficulty + freqBar + frontendQuestionId: questionFrontendId + isFavor + paidOnly: isPaidOnly + content + status + title + titleSlug + topicTags { + name + id + slug + } + hasSolution + hasVideoSolution + } + notes + topicTags { + tagId + slug + name + } + runtimeError + compileError + lastTestcase + } + }` + } + }, + languages: { + 'Python': '.py', + 'Python3': '.py', + 'C++': '.cpp', + 'C': '.c', + 'Java': '.java', + 'C#': '.cs', + 'JavaScript': '.js', + 'Javascript': '.js', + 'Ruby': '.rb', + 'Swift': '.swift', + 'Go': '.go', + 'Kotlin': '.kt', + 'Scala': '.scala', + 'Rust': '.rs', + 'PHP': '.php', + 'TypeScript': '.ts', + 'MySQL': '.sql', + 'MS SQL Server': '.sql', + 'Oracle': '.sql', + } +} /* Commit messages */ const readmeMsg = 'Create README - LeetHub'; @@ -34,9 +141,11 @@ const EXPLORE_SECTION_PROBLEM = 1; let difficulty = ''; /* state of upload for progress */ -let uploadState = { uploading: false }; +let uploadState = { + uploading: false +}; -/* ------------------------------------------------ UTILITY FUNCTIONS ------------------------------------------------------ */ +// *------------------------------------------------ UTILITIES------------------------------------------------------ /* Util function to check if an element exists */ function checkElem(elem) { @@ -62,6 +171,7 @@ function convertToSlug(string) { .replace(/-+$/, ''); // Trim - from end of text } + function addLeadingZeros(title) { const maxTitlePrefixLength = 4; var len = title.split('-')[0].length; @@ -79,6 +189,7 @@ function injectStyle() { document.head.append(style); } + /* This will create a failed tick mark before "Run Code" button signalling that upload failed */ function markUploadFailed() { elem = document.getElementById('leethub_progress_elem'); @@ -90,17 +201,6 @@ function markUploadFailed() { } } -/* This will create a tick mark before "Run Code" button signalling LeetHub has done its job */ -function markUploaded() { - elem = document.getElementById('leethub_progress_elem'); - if (elem) { - elem.className = ''; - style = - 'display: inline-block;transform: rotate(45deg);height:24px;width:12px;border-bottom:7px solid #78b13f;border-right:7px solid #78b13f;'; - elem.style = style; - } -} - /* Main parser function for the code */ function parseCode() { const e = document.getElementsByClassName('CodeMirror-code'); @@ -116,6 +216,9 @@ function parseCode() { return null; } + +// *-----------------------------------------GIT FUNCTIONS------------------------------------------------------------ + /* we will need specific anchor element that is specific to the page you are in Eg. Explore */ function insertToAnchorElement(elem) { if (document.URL.startsWith('https://leetcode.com/explore/')) { @@ -150,8 +253,6 @@ function insertToAnchorElement(elem) { } } -/* ----------------------------------------- GIT FUNCTIONS ------------------------------------------------------------ */ - /* Since we dont yet have callbacks/promises that helps to find out if things went bad */ /* we will start 10 seconds counter and even after that upload is not complete, then we conclude its failed */ function startUploadCountDown() { @@ -185,88 +286,119 @@ function startUpload() { } } -/* Main function for uploading code to GitHub repo, and callback cb is called if success */ -const upload = ( - token, - hook, - code, - directory, - filename, - sha, - msg, - cb = undefined, -) => { - // To validate user, load user object from GitHub. +// Helper function to check if a file already exists in the directory +function checkFileExists(token, hook, directory, filename, cb) { const URL = `https://api.github.com/repos/${hook}/contents/${directory}/${filename}`; - - /* Define Payload */ - let data = { - message: msg, - content: code, - sha, - }; - - data = JSON.stringify(data); - const xhr = new XMLHttpRequest(); xhr.addEventListener('readystatechange', function () { if (xhr.readyState === 4) { - if (xhr.status === 200 || xhr.status === 201) { - const updatedSha = JSON.parse(xhr.responseText).content.sha; // get updated SHA. - - chrome.storage.local.get('stats', (data2) => { - let { stats } = data2; - if (stats === null || stats === {} || stats === undefined) { - // create stats object - stats = {}; - stats.solved = 0; - stats.easy = 0; - stats.medium = 0; - stats.hard = 0; - stats.sha = {}; - } - const filePath = directory + filename; - // Only increment solved problems statistics once - // New submission commits twice (README and problem) - if (filename === 'README.md' && sha === null) { - stats.solved += 1; - stats.easy += difficulty === 'Easy' ? 1 : 0; - stats.medium += difficulty === 'Medium' ? 1 : 0; - stats.hard += difficulty === 'Hard' ? 1 : 0; - } - stats.sha[filePath] = updatedSha; // update sha key. - chrome.storage.local.set({ stats }, () => { - console.log( - `Successfully committed ${filename} to github`, - ); + if (xhr.status === 200) { + // File exists, get the SHA of the existing file + const response = JSON.parse(xhr.responseText); + const sha = response.sha; + cb(true, sha); + } else if (xhr.status === 404) { + // File doesn't exist + cb(false, null); + } else { + // Error occurred + cb(false, null); + } + } + }); - // if callback is defined, call it + xhr.open('GET', URL, true); + xhr.setRequestHeader('Authorization', `token ${token}`); + xhr.setRequestHeader('Accept', 'application/vnd.github.v3+json'); + xhr.send(); +} + +// Main function for uploading code to GitHub repo, and callback cb is called if success +const upload = (token, hook, code, directory, filename, msg, cb = undefined) => { + checkFileExists(token, hook, directory, filename, (fileExists, sha) => { + // Define Payload + let data = { + message: msg, + content: code, + }; + + // If file exists, update the data with the SHA of the existing file + if (fileExists && sha) { + data.sha = sha; + } + + data = JSON.stringify(data); + + const URL = `https://api.github.com/repos/${hook}/contents/${directory}/${filename}`; + + const xhr = new XMLHttpRequest(); + xhr.addEventListener('readystatechange', function () { + if (xhr.readyState === 4) { + if (xhr.status === 200 || xhr.status === 201) { + const response = JSON.parse(xhr.responseText); + const updatedSha = response.content.sha; // Get updated SHA. + + if (filename === 'README.md' && sha === null) { + // If it's the README and sha is null, it means it's a new problem, so update stats + chrome.storage.local.get('stats', (data2) => { + let { stats } = data2; + if (stats === null || stats === {} || stats === undefined) { + stats = {}; + stats.solved = 0; + stats.easy = 0; + stats.medium = 0; + stats.hard = 0; + stats.sha = {}; + } + const filePath = `${directory}/${filename}`; + stats.solved += 1; + stats.easy += difficulty === 'Easy' ? 1 : 0; + stats.medium += difficulty === 'Medium' ? 1 : 0; + stats.hard += difficulty === 'Hard' ? 1 : 0; + stats.sha[filePath] = updatedSha; // update sha key. + chrome.storage.local.set({ stats }, () => { + console.log(`Successfully committed ${filename} to GitHub`); + + // If callback is defined, call it + if (cb !== undefined) { + cb(); + } + }); + }); + } else { + // For other files, simply update the stats + const filePath = `${directory}/${filename}`; + chrome.storage.local.get('stats', (data2) => { + let { stats } = data2; + if (stats !== null && stats !== {} && stats !== undefined) { + stats.sha[filePath] = updatedSha; // update sha key. + chrome.storage.local.set({ stats }); + } + }); + + console.log(`Successfully committed ${filename} to GitHub`); + + // If callback is defined, call it if (cb !== undefined) { cb(); } - }); - }); + } + } } - } + }); + + xhr.open('PUT', URL, true); + xhr.setRequestHeader('Authorization', `token ${token}`); + xhr.setRequestHeader('Accept', 'application/vnd.github.v3+json'); + xhr.send(data); }); - xhr.open('PUT', URL, true); - xhr.setRequestHeader('Authorization', `token ${token}`); - xhr.setRequestHeader('Accept', 'application/vnd.github.v3+json'); - xhr.send(data); }; /* Main function for updating code on GitHub Repo */ /* Currently only used for prepending discussion posts to README */ /* callback cb is called on success if it is defined */ -const update = ( - token, - hook, - addition, - directory, - msg, - prepend, - cb = undefined, -) => { +const update = (token, hook, addition, directory, msg, prepend, cb = undefined) => { + const URL = `https://api.github.com/repos/${hook}/contents/${directory}/README.md`; /* Read from existing file on GitHub */ @@ -275,30 +407,18 @@ const update = ( if (xhr.readyState === 4) { if (xhr.status === 200 || xhr.status === 201) { const response = JSON.parse(xhr.responseText); - const existingContent = decodeURIComponent( - escape(atob(response.content)), - ); + const existingContent = atob(response.content); + let newContent = ''; /* Discussion posts prepended at top of README */ /* Future implementations may require appending to bottom of file */ if (prepend) { - newContent = btoa( - unescape(encodeURIComponent(addition + existingContent)), - ); + newContent = btoa(addition + existingContent); } /* Write file with new content to GitHub */ - upload( - token, - hook, - newContent, - directory, - 'README.md', - response.sha, - msg, - cb, - ); + upload(token, hook, newContent, directory, 'README.md', response.sha, msg, cb); } } }); @@ -308,16 +428,7 @@ const update = ( xhr.send(); }; -function uploadGit( - code, - problemName, - fileName, - msg, - action, - prepend = true, - cb = undefined, - _diff = undefined, -) { +function uploadGit(code, problemNameSlug, fileName, msg, action, prepend = true, cb = undefined, _diff = undefined) { // Assign difficulty if (_diff && _diff !== undefined) { difficulty = _diff.trim(); @@ -334,47 +445,13 @@ function uploadGit( chrome.storage.local.get('leethub_hook', (h) => { const hook = h.leethub_hook; if (hook) { - /* Get SHA, if it exists */ - - /* to get unique key */ - const filePath = problemName + fileName; - chrome.storage.local.get('stats', (s) => { - const { stats } = s; - let sha = null; - - if ( - stats !== undefined && - stats.sha !== undefined && - stats.sha[filePath] !== undefined - ) { - sha = stats.sha[filePath]; - } - if (action === 'upload') { - /* Upload to git. */ - upload( - token, - hook, - code, - problemName, - fileName, - sha, - msg, - cb, - ); - } else if (action === 'update') { - /* Update on git */ - update( - token, - hook, - code, - problemName, - msg, - prepend, - cb, - ); - } - }); + if (action === 'upload') { + upload(token, hook, code, problemNameSlug, fileName, msg, cb); + } + else if (action === 'update') { + update(token, hook, code, problemNameSlug, msg, prepend, cb); + } } }); } @@ -383,448 +460,253 @@ function uploadGit( }); } -/* ----------------------------------------- LEETCODE WEB PAGE PARSING FUNCTIONS ------------------------------------------------------------ */ +/* This will create a tick mark before "Run Code" button signalling LeetHub has done its job */ +function markUploaded() { + elem = document.getElementById('leethub_progress_elem'); + if (elem) { + elem.className = ''; + style = + 'display: inline-block;transform: rotate(45deg);height:24px;width:12px;border-bottom:7px solid #78b13f;border-right:7px solid #78b13f;'; + elem.style = style; + } +} + +// *------------------------------------------------ LEETCODE WEB PAGE PARSING ------------------------------------------------------ /* Get file extension for submission */ -function findLanguage() { - const tag = [ - ...document.getElementsByClassName( - 'ant-select-selection-selected-value', - ), - ...document.getElementsByClassName('Select-value-label'), - ]; - if (tag && tag.length > 0) { - for (let i = 0; i < tag.length; i += 1) { - const elem = tag[i].textContent; - if (elem !== undefined && languages[elem] !== undefined) { - return languages[elem]; // should generate respective file extension - } - } +function findLanguageExtension() { + const languageElement = document.querySelector('div.relative.notranslate button div'); + const language = languageElement.textContent; + if (language !== undefined && constant.languages[language] !== undefined) { + + // Return the respective file extension or language identifier + return constant.languages[language]; } return null; } + /* Function for finding and parsing the full code. */ -/* - At first find the submission details url. */ -/* - Then send a request for the details page. */ -/* - Finally, parse the code from the html reponse. */ -/* - Also call the callback if available when upload is success */ -function findCode( - uploadGit, - problemName, - fileName, - msg, - action, - cb = undefined, -) { - /* Get the submission details url from the submission page. */ - var submissionURL; - const e = document.getElementsByClassName('status-column__3SUg'); - if (checkElem(e)) { - // for normal problem submisson - const submissionRef = e[1].innerHTML.split(' ')[1]; - submissionURL = - 'https://leetcode.com' + - submissionRef.split('=')[1].slice(1, -1); - } else { - // for a submission in explore section - const submissionRef = document.getElementById('result-state'); - submissionURL = submissionRef.href; - } +function findCode(uploadGit, problemNameSlug, fileName, msg, action, cb = undefined) { + const currentURL = window.location.href; + const questionSlug = currentURL.split('/')[4]; + const variables = { + questionSlug: questionSlug, + limit: 20, + offset: 0, + lastKey: null, + status: 10 + }; - if (submissionURL != undefined) { - /* Request for the submission details page */ - const xhttp = new XMLHttpRequest(); - xhttp.onreadystatechange = function () { - if (this.readyState == 4 && this.status == 200) { - /* received submission details as html reponse. */ - var doc = new DOMParser().parseFromString( - this.responseText, - 'text/html', - ); - /* the response has a js object called pageData. */ - /* Pagedata has the details data with code about that submission */ - var scripts = doc.getElementsByTagName('script'); - for (var i = 0; i < scripts.length; i++) { - var text = scripts[i].innerText; - if (text.includes('pageData')) { - /* Considering the pageData as text and extract the substring - which has the full code */ - var firstIndex = text.indexOf('submissionCode'); - var lastIndex = text.indexOf('editCodeUrl'); - var slicedText = text.slice(firstIndex, lastIndex); - /* slicedText has code as like as. (submissionCode: 'Details code'). */ - /* So finding the index of first and last single inverted coma. */ - var firstInverted = slicedText.indexOf("'"); - var lastInverted = slicedText.lastIndexOf("'"); - /* Extract only the code */ - var codeUnicoded = slicedText.slice( - firstInverted + 1, - lastInverted, - ); - /* The code has some unicode. Replacing all unicode with actual characters */ - var code = codeUnicoded.replace( - /\\u[\dA-F]{4}/gi, - function (match) { - return String.fromCharCode( - parseInt(match.replace(/\\u/g, ''), 16), - ); - }, - ); - - /* - for a submisssion in explore section we do not get probStat beforehand - so, parse statistics from submisson page - */ - if (!msg) { - slicedText = text.slice( - text.indexOf('runtime'), - text.indexOf('memory'), - ); - const resultRuntime = slicedText.slice( - slicedText.indexOf("'") + 1, - slicedText.lastIndexOf("'"), - ); - slicedText = text.slice( - text.indexOf('memory'), - text.indexOf('total_correct'), - ); - const resultMemory = slicedText.slice( - slicedText.indexOf("'") + 1, - slicedText.lastIndexOf("'"), + const requestOptions = { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + query: constant.url.payload.getAllSubmissions, + variables: variables + }) + }; + + /* Fetching submission ID from graphql query to fetch code of the submission */ + fetch(constant.url.apiURL, requestOptions) + .then(response => response.json()) + .then((submissions) => { + if (!submissions) return; + + const submissionId = submissions.data.questionSubmissionList.submissions[0].id; + + const variables = { + submissionId: submissionId + } + + const requestOptions = { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + query: constant.url.payload.getSubmission, + variables: variables + }) + }; + + /* Fetching code based on the submission id extracted from the above request */ + fetch(constant.url.apiURL, requestOptions) + .then(response => response.json()) + .then((submission) => { + let code = submission.data.submissionDetails.code; + + code = code.replace( + /\\u[\dA-F]{4}/gi, + function (match) { + return String.fromCharCode( + parseInt(match.replace(/\\u/g, ''), 16), ); - msg = `Time: ${resultRuntime}, Memory: ${resultMemory} - LeetHub`; - } + }, + ); - if (code != null) { - setTimeout(function () { - uploadGit( - btoa(unescape(encodeURIComponent(code))), - problemName, - fileName, - msg, - action, - true, - cb, - ); - }, 2000); - } + if (code != null) { + setTimeout(function () { + uploadGit(btoa(code), problemNameSlug, fileName, msg, action, true, cb); + }, 5000); } - } - } - }; - - xhttp.open('GET', submissionURL, true); - xhttp.send(); - } + }); + }); } +/* Function for parsing the difficulty level of the problem. */ +function parseProblemDifficulty() { + let difficulty = null; -function convertToSlug(string) { - const a = - 'àáâäæãåāăąçćčđďèéêëēėęěğǵḧîïíīįìłḿñńǹňôöòóœøōõőṕŕřßśšşșťțûüùúūǘůűųẃẍÿýžźż·/_,:;'; - const b = - 'aaaaaaaaaacccddeeeeeeeegghiiiiiilmnnnnoooooooooprrsssssttuuuuuuuuuwxyyzzz------'; - const p = new RegExp(a.split('').join('|'), 'g'); + const difficultySelectors = [constant.elementTags.difficulty.easy, + constant.elementTags.difficulty.medium, + constant.elementTags.difficulty.hard]; - return string - .toString() - .toLowerCase() - .replace(/\s+/g, '-') // Replace spaces with - - .replace(p, (c) => b.charAt(a.indexOf(c))) // Replace special characters - .replace(/&/g, '-and-') // Replace & with 'and' - .replace(/[^\w\-]+/g, '') // Remove all non-word characters - .replace(/\-\-+/g, '-') // Replace multiple - with single - - .replace(/^-+/, '') // Trim - from start of text - .replace(/-+$/, ''); // Trim - from end of text -} -function getProblemNameSlug() { - const questionElem = document.getElementsByClassName( - 'content__u3I1 question-content__JfgR', - ); - const questionDescriptionElem = document.getElementsByClassName( - 'question-description__3U1T', - ); - let questionTitle = 'unknown-problem'; - if (checkElem(questionElem)) { - let qtitle = document.getElementsByClassName('css-v3d350'); - if (checkElem(qtitle)) { - questionTitle = qtitle[0].innerHTML; - } - } else if (checkElem(questionDescriptionElem)) { - let qtitle = document.getElementsByClassName('question-title'); - if (checkElem(qtitle)) { - questionTitle = qtitle[0].innerText; - } + const selectedElement = document.querySelector(difficultySelectors.join(', ')); + + if (selectedElement) { + difficulty = selectedElement.innerText; } - return addLeadingZeros(convertToSlug(questionTitle)); + return difficulty } + /* Parser function for the question and tags */ function parseQuestion() { - var questionUrl = window.location.href; - if (questionUrl.endsWith('/submissions/')) { - questionUrl = questionUrl.substring( - 0, - questionUrl.lastIndexOf('/submissions/') + 1, - ); - } - const questionElem = document.getElementsByClassName( - 'content__u3I1 question-content__JfgR', - ); - const questionDescriptionElem = document.getElementsByClassName( - 'question-description__3U1T', - ); + const questionElem = document.getElementsByClassName(constant.elementTags.questionTag); if (checkElem(questionElem)) { const qbody = questionElem[0].innerHTML; + difficulty = parseProblemDifficulty(); - // Problem title. - let qtitle = document.getElementsByClassName('css-v3d350'); - if (checkElem(qtitle)) { - qtitle = qtitle[0].innerHTML; - } else { - qtitle = 'unknown-problem'; - } - - // Problem difficulty, each problem difficulty has its own class. - const isHard = document.getElementsByClassName('css-t42afm'); - const isMedium = document.getElementsByClassName('css-dcmtd5'); - const isEasy = document.getElementsByClassName('css-14oi08n'); - - if (checkElem(isEasy)) { - difficulty = 'Easy'; - } else if (checkElem(isMedium)) { - difficulty = 'Medium'; - } else if (checkElem(isHard)) { - difficulty = 'Hard'; - } - // Final formatting of the contents of the README for each problem - const markdown = `

${qtitle}

${difficulty}


${qbody}`; - return markdown; - } else if (checkElem(questionDescriptionElem)) { - let questionTitle = document.getElementsByClassName( - 'question-title', - ); - if (checkElem(questionTitle)) { - questionTitle = questionTitle[0].innerText; - } else { - questionTitle = 'unknown-problem'; - } - - const questionBody = questionDescriptionElem[0].innerHTML; - const markdown = `

${questionTitle}


${questionBody}`; - + /* Markdown content initialization */ + const markdown = `

${difficulty}


${qbody}`; return markdown; } - return null; } /* Parser function for time/space stats */ function parseStats() { - const probStats = document.getElementsByClassName('data__HC-i'); - if (!checkElem(probStats)) { + const problemStats = document.getElementsByClassName(constant.elementTags.problemStatsTag); + const percentileStats = document.getElementsByClassName(constant.elementTags.percentileStatsTag); + + const percentageRegex = constant.regex.percentageRegex; + + const time = problemStats.item(0).textContent; + const timePercentile = percentileStats.item(0).textContent.match(percentageRegex)[0]; + + const space = problemStats.item(1).textContent; + const spacePercentile = percentileStats.item(1).textContent.match(percentageRegex)[0]; + + if (!checkElem(problemStats)) { return null; } - const time = probStats[0].textContent; - const timePercentile = probStats[1].textContent; - const space = probStats[2].textContent; - const spacePercentile = probStats[3].textContent; // Format commit message return `Time: ${time} (${timePercentile}), Space: ${space} (${spacePercentile}) - LeetHub`; } -document.addEventListener('click', (event) => { - const element = event.target; - const oldPath = window.location.pathname; - - /* Act on Post button click */ - /* Complex since "New" button shares many of the same properties as "Post button */ - if ( - element.classList.contains('icon__3Su4') || - element.parentElement.classList.contains('icon__3Su4') || - element.parentElement.classList.contains( - 'btn-content-container__214G', - ) || - element.parentElement.classList.contains('header-right__2UzF') - ) { - setTimeout(function () { - /* Only post if post button was clicked and url changed */ - if ( - oldPath !== window.location.pathname && - oldPath === - window.location.pathname.substring(0, oldPath.length) && - !Number.isNaN(window.location.pathname.charAt(oldPath.length)) - ) { - const date = new Date(); - const currentDate = `${date.getDate()}/${date.getMonth()}/${date.getFullYear()} at ${date.getHours()}:${date.getMinutes()}`; - const addition = `[Discussion Post (created on ${currentDate})](${window.location}) \n`; - const problemName = window.location.pathname.split('/')[2]; // must be true. - - uploadGit( - addition, - problemName, - 'README.md', - discussionMsg, - 'update', - ); - } - }, 1000); - } -}); - -// /* function to get the notes if there is any -// the note should be opened atleast once for this to work -// this is because the dom is populated after data is fetched by opening the note */ -// function getNotesIfAny() { -// // there are no notes on expore -// if (document.URL.startsWith('https://leetcode.com/explore/')) -// return ''; - -// notes = ''; -// if ( -// checkElem(document.getElementsByClassName('notewrap__eHkN')) && -// checkElem( -// document -// .getElementsByClassName('notewrap__eHkN')[0] -// .getElementsByClassName('CodeMirror-code'), -// ) -// ) { -// notesdiv = document -// .getElementsByClassName('notewrap__eHkN')[0] -// .getElementsByClassName('CodeMirror-code')[0]; -// if (notesdiv) { -// for (i = 0; i < notesdiv.childNodes.length; i++) { -// if (notesdiv.childNodes[i].childNodes.length == 0) continue; -// text = notesdiv.childNodes[i].childNodes[0].innerText; -// if (text) { -// notes = `${notes}\n${text.trim()}`.trim(); -// } -// } -// } -// } -// return notes.trim(); -// } - -const loader = setInterval(() => { - let code = null; - let probStatement = null; - let probStats = null; - let probType; - const successTag = document.getElementsByClassName('success__3Ai7'); - const resultState = document.getElementById('result-state'); - var success = false; - // check success tag for a normal problem - if ( - checkElem(successTag) && - successTag[0].className === 'success__3Ai7' && - successTag[0].innerText.trim() === 'Success' - ) { - console.log(successTag[0]); - success = true; - probType = NORMAL_PROBLEM; - } - - // check success state for a explore section problem - else if ( - resultState && - resultState.className === 'text-success' && - resultState.innerText === 'Accepted' - ) { - success = true; - probType = EXPLORE_SECTION_PROBLEM; - } - - if (success) { - probStatement = parseQuestion(); - probStats = parseStats(); +function getProblemNameSlug() { + const problemNameElement = document.querySelector(constant.elementTags.problemNameTag); + if (problemNameElement) { + const problemName = problemNameElement.textContent; + chrome.storage.local.set({ problemName: problemName }); + return addLeadingZeros(convertToSlug(problemName)); } + return null; +} - if (probStatement !== null) { - switch (probType) { - case NORMAL_PROBLEM: - successTag[0].classList.add('marked_as_success'); - break; - case EXPLORE_SECTION_PROBLEM: - resultState.classList.add('marked_as_success'); - break; - default: - console.error(`Unknown problem type ${probType}`); - return; - } - - const problemName = getProblemNameSlug(); - const language = findLanguage(); - if (language !== null) { - // start upload indicator here - startUpload(); - chrome.storage.local.get('stats', (s) => { - const { stats } = s; - const filePath = problemName + problemName + language; - let sha = null; - if ( - stats !== undefined && - stats.sha !== undefined && - stats.sha[filePath] !== undefined - ) { - sha = stats.sha[filePath]; - } - - /* Only create README if not already created */ - if (sha === null) { - /* @TODO: Change this setTimeout to Promise */ - uploadGit( - btoa(unescape(encodeURIComponent(probStatement))), - problemName, - 'README.md', - readmeMsg, - 'upload', - ); +/* Interval function to check if code has been submitted */ +function loaderFunction() { + try { + const submitButton = document.querySelector(constant.elementTags.submitButtonTag); + let currentURL = window.location.href; + + /* Fetches problem statement and problem name from description page */ + if ((currentURL.endsWith('/description/') || currentURL.includes('/problems/')) && !currentURL.endsWith('/submissions/')) { + const problemStatement = parseQuestion(); + const problemNameSlug = getProblemNameSlug(); + if (problemStatement != null && problemNameSlug != null) { + try { + chrome.storage.local.set({ problemStatement, problemNameSlug }); + } catch (err) { + console.error(err); } - }); + } + } - /* get the notes and upload it */ - /* only upload notes if there is any */ - notes = getNotesIfAny(); - if (notes.length > 0) { + submitButton.addEventListener('click', function () { + clearInterval(loaderInterval); + if (!flag) { setTimeout(function () { - if (notes != undefined && notes.length != 0) { - console.log('Create Notes'); - // means we can upload the notes too - uploadGit( - btoa(unescape(encodeURIComponent(notes))), - problemName, - 'NOTES.md', - createNotesMsg, - 'upload', - ); + currentURL = window.location.href; + if (currentURL.endsWith('/submissions/')) { + try { + + // Checking if code has been accepted or not + successTag = document.querySelector(constant.elementTags.successTag).textContent; + + if (checkElem(successTag) && successTag === 'Accepted') { + success = true; + problemType = NORMAL_PROBLEM; + problemStats = parseStats(); + languageExtension = findLanguageExtension(); + + chrome.storage.local.get(['problemStatement', 'problemNameSlug', 'problemName'], function (result) { + let problemStatement = result.problemStatement; + const problemNameSlug = result.problemNameSlug; + const problemName = result.problemName; + + const questionUrl = currentURL.substring(0, currentURL.indexOf('/submissions/')); + + problemStatement = `

${problemName}

` + problemStatement; + + if (languageExtension && problemStatement && problemNameSlug && problemName) { + startUpload(); + + uploadGit(btoa(problemStatement), problemNameSlug, 'README.md', readmeMsg, 'upload'); + + findCode(uploadGit, problemNameSlug, problemNameSlug + languageExtension, problemStats, 'upload', + // callback is called when the code upload to git is a success + () => { + if (uploadState['countdown']) { + clearTimeout(uploadState['countdown']); + } + delete uploadState['countdown']; + uploadState.uploading = false; + markUploaded(); + flag = false; + loaderInterval = setInterval(loaderFunction, 1000); + }, + ); + } + }); + } + } catch (err) { + console.error(err); + } } - }, 500); + }, 5000); + flag = true; } - - /* Upload code to Git */ - setTimeout(function () { - findCode( - uploadGit, - problemName, - problemName + language, - probStats, - 'upload', - // callback is called when the code upload to git is a success - () => { - if (uploadState['countdown']) - clearTimeout(uploadState['countdown']); - delete uploadState['countdown']; - uploadState.uploading = false; - markUploaded(); - }, - ); // Encode `code` to base64 - }, 1000); - } + }); } -}, 1000); + catch (err) { + // console.error(err); + } +} + +let flag = false; +let successTag = null; +let success = false; +let problemType; +let problemStats; +let languageExtension; + +let loaderInterval = setInterval(loaderFunction, 1000); /* Sync to local storage */ chrome.storage.local.get('isSync', (data) => { @@ -839,10 +721,14 @@ chrome.storage.local.get('isSync', (data) => { if (!data || !data.isSync) { keys.forEach((key) => { chrome.storage.sync.get(key, (data) => { - chrome.storage.local.set({ [key]: data[key] }); + chrome.storage.local.set({ + [key]: data[key] + }); }); }); - chrome.storage.local.set({ isSync: true }, (data) => { + chrome.storage.local.set({ + isSync: true + }, (data) => { console.log('LeetHub Synced to local values'); }); } else { From a3262ad97df76bf7c6d04df00ddfc373056b849e Mon Sep 17 00:00:00 2001 From: mustafabawany Date: Sun, 13 Aug 2023 06:18:35 -0700 Subject: [PATCH 3/7] Updated popup UI --- css/popup.css | 12 ++++ manifest.json | 1 + popup.html | 194 ++++++++++++++++++++++---------------------------- 3 files changed, 97 insertions(+), 110 deletions(-) diff --git a/css/popup.css b/css/popup.css index a6dcf7f4..e9ce6fbd 100644 --- a/css/popup.css +++ b/css/popup.css @@ -26,6 +26,18 @@ body { margin-bottom: 0px; } +#social-icon-container { + display: flex; + justify-content: space-between; + width: 100%; + margin-top: 1rem; + margin-bottom: 1rem; +} + +#socials p { + font-weight: bold; +} + .onboarding { font-family: sans-serif; border-top: solid black 1px; diff --git a/manifest.json b/manifest.json index 795f250b..3b66df35 100644 --- a/manifest.json +++ b/manifest.json @@ -5,6 +5,7 @@ "homepage_url": "https://github.com/QasimWani/LeetHub", "version": "1.1.2", "author": "Qasim Wani", + "co-author": "Mustafa Bawany", "browser_action": { "default_icon": "assets/thumbnail.png", "default_popup": "popup.html" diff --git a/popup.html b/popup.html index 31791f1a..b7507813 100644 --- a/popup.html +++ b/popup.html @@ -1,123 +1,97 @@ - - - - - - - + + + + - -
-
-

- LeetHub -

-

Sync your code from LeetCode to GitHub

-
- - + + + - - + +
+
+

+ LeetHub +

+

Sync your code from LeetCode to GitHub

+
+ + + + + - - - -
- - - - + +
+
+

Qasim Wani

+ + + + +
+
+

Mustafa Bawany

+ + + +
+
+ + + + - - - - + \ No newline at end of file From b77b53a71e2580984c4f703096a2bec39befd4e2 Mon Sep 17 00:00:00 2001 From: mustafabawany Date: Sun, 13 Aug 2023 10:48:01 -0700 Subject: [PATCH 4/7] Final fixes for new UI --- scripts/leetcode.js | 263 ++++++++++++++++++++++++++++---------------- 1 file changed, 167 insertions(+), 96 deletions(-) diff --git a/scripts/leetcode.js b/scripts/leetcode.js index c9624c86..26fdb493 100644 --- a/scripts/leetcode.js +++ b/scripts/leetcode.js @@ -1,7 +1,6 @@ /* Constants used through out the code */ const constant = { elementTags: { - questionTag: "xFUwe", problemStatsTag: "mt-3", percentileStatsTag: "mt-2", difficulty: { @@ -9,7 +8,6 @@ const constant = { medium: ".text-yellow", /* .text-yellow is for medium problem */ hard: ".text-pink" /* .text-pink is for hard problem */ }, - problemNameTag: "a.mr-2.text-label-1", submitButtonTag: '[data-e2e-locator="console-submit-button"]', successTag: 'span[data-e2e-locator="submission-result"]', }, @@ -102,6 +100,26 @@ const constant = { compileError lastTestcase } + }`, + getQuestionTitle: `query consolePanelConfig($titleSlug: String!) { + question(titleSlug: $titleSlug) { + questionId + questionFrontendId + questionTitle + enableDebugger + enableRunCode + enableSubmit + enableTestMode + exampleTestcaseList + metaData + } + }`, + getProblemStatement: `query questionContent($titleSlug: String!) { + question(titleSlug: $titleSlug) { + content + mysqlSchemas + dataSchemas + } }` } }, @@ -133,7 +151,7 @@ const readmeMsg = 'Create README - LeetHub'; const discussionMsg = 'Prepend discussion post - LeetHub'; const createNotesMsg = 'Attach NOTES - LeetHub'; -// problem types +/* problem types */ const NORMAL_PROBLEM = 0; const EXPLORE_SECTION_PROBLEM = 1; @@ -145,7 +163,7 @@ let uploadState = { uploading: false }; -// *------------------------------------------------ UTILITIES------------------------------------------------------ +/* ------------------------------------------------ UTILITIES------------------------------------------------------ */ /* Util function to check if an element exists */ function checkElem(elem) { @@ -217,7 +235,7 @@ function parseCode() { } -// *-----------------------------------------GIT FUNCTIONS------------------------------------------------------------ +/* ----------------------------------------- GIT FUNCTIONS ------------------------------------------------------------ */ /* we will need specific anchor element that is specific to the page you are in Eg. Explore */ function insertToAnchorElement(elem) { @@ -286,7 +304,7 @@ function startUpload() { } } -// Helper function to check if a file already exists in the directory +/* Helper function to check if a file already exists in the directory */ function checkFileExists(token, hook, directory, filename, cb) { const URL = `https://api.github.com/repos/${hook}/contents/${directory}/${filename}`; const xhr = new XMLHttpRequest(); @@ -313,7 +331,7 @@ function checkFileExists(token, hook, directory, filename, cb) { xhr.send(); } -// Main function for uploading code to GitHub repo, and callback cb is called if success +/* Main function for uploading code to GitHub repo, and callback cb is called if success */ const upload = (token, hook, code, directory, filename, msg, cb = undefined) => { checkFileExists(token, hook, directory, filename, (fileExists, sha) => { // Define Payload @@ -472,7 +490,7 @@ function markUploaded() { } -// *------------------------------------------------ LEETCODE WEB PAGE PARSING ------------------------------------------------------ +/* ------------------------------------------------ LEETCODE WEB PAGE PARSING FUNCTIONS ------------------------------------------------------ */ /* Get file extension for submission */ function findLanguageExtension() { @@ -515,12 +533,12 @@ function findCode(uploadGit, problemNameSlug, fileName, msg, action, cb = undefi .then(response => response.json()) .then((submissions) => { if (!submissions) return; - + const submissionId = submissions.data.questionSubmissionList.submissions[0].id; const variables = { submissionId: submissionId - } + } const requestOptions = { method: 'POST', @@ -576,16 +594,35 @@ function parseProblemDifficulty() { /* Parser function for the question and tags */ function parseQuestion() { - const questionElem = document.getElementsByClassName(constant.elementTags.questionTag); - if (checkElem(questionElem)) { - const qbody = questionElem[0].innerHTML; - difficulty = parseProblemDifficulty(); - - /* Markdown content initialization */ - const markdown = `

${difficulty}


${qbody}`; - return markdown; - } - return null; + const currentURL = window.location.href; + const titleSlug = currentURL.split('/')[4]; + const variables = { + titleSlug: titleSlug, + }; + + const requestOptions = { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + query: constant.url.payload.getProblemStatement, + variables: variables + }) + }; + + /* Fetching question title and question id from graphql query to fetch problem statement */ + return new Promise((resolve, reject) => { + fetch(constant.url.apiURL, requestOptions) + .then(response => response.json()) + .then((questionData) => { + const problemStatement = questionData.data.question.content; + resolve(problemStatement); + }) + .catch((error) => { + reject(error); + }); + }) } /* Parser function for time/space stats */ @@ -605,103 +642,137 @@ function parseStats() { return null; } - // Format commit message + // Format commit message return `Time: ${time} (${timePercentile}), Space: ${space} (${spacePercentile}) - LeetHub`; } function getProblemNameSlug() { - const problemNameElement = document.querySelector(constant.elementTags.problemNameTag); - if (problemNameElement) { - const problemName = problemNameElement.textContent; - chrome.storage.local.set({ problemName: problemName }); - return addLeadingZeros(convertToSlug(problemName)); - } - return null; + const currentURL = window.location.href; + const titleSlug = currentURL.split('/')[4]; + const variables = { + titleSlug: titleSlug, + }; + + const requestOptions = { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + query: constant.url.payload.getQuestionTitle, + variables: variables + }) + }; + + /* Fetching question title and question id from graphql query to fetch problem statement */ + return new Promise((resolve, reject) => { + fetch(constant.url.apiURL, requestOptions) + .then(response => response.json()) + .then((questionData) => { + const problemName = questionData.data.question.questionId + ". " + questionData.data.question.questionTitle; + const problemNameSlug = addLeadingZeros(convertToSlug(problemName)); + resolve({ problemName, problemNameSlug }); + }) + .catch((error) => { + reject(error); + }); + }) } -/* Interval function to check if code has been submitted */ -function loaderFunction() { - try { - const submitButton = document.querySelector(constant.elementTags.submitButtonTag); - let currentURL = window.location.href; +function parserFunction() { + return new Promise((resolve, reject) => { + setTimeout(function () { + // Get the current URL + currentURL = window.location.href; - /* Fetches problem statement and problem name from description page */ - if ((currentURL.endsWith('/description/') || currentURL.includes('/problems/')) && !currentURL.endsWith('/submissions/')) { - const problemStatement = parseQuestion(); - const problemNameSlug = getProblemNameSlug(); - if (problemStatement != null && problemNameSlug != null) { + // Get the current URL + if (currentURL.endsWith('/submissions/')) { try { - chrome.storage.local.set({ problemStatement, problemNameSlug }); + + // Checking if code has been accepted or not + successTag = document.querySelector(constant.elementTags.successTag).textContent; + + if (checkElem(successTag) && successTag === 'Accepted') { + problemType = NORMAL_PROBLEM; + + // Parse problem statistics + problemStats = parseStats(); + + // Find language extension of the submission + languageExtension = findLanguageExtension(); + + // Get problem name and slug + getProblemNameSlug() + .then(({ problemName, problemNameSlug }) => { + // Parse the problem statement + parseQuestion() + .then((problemStatement) => { + const questionUrl = currentURL.substring(0, currentURL.indexOf('/submissions/')); + + // Modify the problem statement to include a link to the question + problemStatement = `

${problemName}

` + problemStatement; + + // Check if all required data is available + if (languageExtension && problemStatement && problemNameSlug && problemName) { + startUpload(); + + uploadGit(btoa(problemStatement), problemNameSlug, 'README.md', readmeMsg, 'upload'); + + findCode( + uploadGit, + problemNameSlug, + problemNameSlug + languageExtension, + problemStats, + 'upload', + // Callback is called when the code upload to Git is successful + () => { + if (uploadState['countdown']) { + clearTimeout(uploadState['countdown']); + } + delete uploadState['countdown']; + uploadState.uploading = false; + markUploaded(); + } + ); + } + }); + }); + } } catch (err) { console.error(err); } } - } - - submitButton.addEventListener('click', function () { - clearInterval(loaderInterval); - if (!flag) { - setTimeout(function () { - currentURL = window.location.href; - if (currentURL.endsWith('/submissions/')) { - try { - - // Checking if code has been accepted or not - successTag = document.querySelector(constant.elementTags.successTag).textContent; - - if (checkElem(successTag) && successTag === 'Accepted') { - success = true; - problemType = NORMAL_PROBLEM; - problemStats = parseStats(); - languageExtension = findLanguageExtension(); - - chrome.storage.local.get(['problemStatement', 'problemNameSlug', 'problemName'], function (result) { - let problemStatement = result.problemStatement; - const problemNameSlug = result.problemNameSlug; - const problemName = result.problemName; - - const questionUrl = currentURL.substring(0, currentURL.indexOf('/submissions/')); - - problemStatement = `

${problemName}

` + problemStatement; + }, 5000); + }); +} - if (languageExtension && problemStatement && problemNameSlug && problemName) { - startUpload(); +/* Interval function to check if code has been submitted */ +function loaderFunction() { + try { - uploadGit(btoa(problemStatement), problemNameSlug, 'README.md', readmeMsg, 'upload'); + const submitButton = document.querySelector(constant.elementTags.submitButtonTag); - findCode(uploadGit, problemNameSlug, problemNameSlug + languageExtension, problemStats, 'upload', - // callback is called when the code upload to git is a success - () => { - if (uploadState['countdown']) { - clearTimeout(uploadState['countdown']); - } - delete uploadState['countdown']; - uploadState.uploading = false; - markUploaded(); - flag = false; - loaderInterval = setInterval(loaderFunction, 1000); - }, - ); - } - }); - } - } catch (err) { - console.error(err); - } - } - }, 5000); - flag = true; - } - }); + if (!flag) { + submitButton.addEventListener('click', function () { + clearInterval(loaderInterval); + parserFunction() + .then(() => { + loaderInterval = setInterval(loaderFunction, 1000); + }) + .catch((error) => { + console.error(error); + }); + }); + flag = true; + } } catch (err) { - // console.error(err); + console.error(err); } } let flag = false; let successTag = null; -let success = false; let problemType; let problemStats; let languageExtension; @@ -736,5 +807,5 @@ chrome.storage.local.get('isSync', (data) => { } }); -// inject the style +/* inject the style */ injectStyle(); \ No newline at end of file From 9590696b66b5d467dbe73869f3349cdc488e0976 Mon Sep 17 00:00:00 2001 From: mustafabawany Date: Fri, 29 Sep 2023 12:25:40 -0700 Subject: [PATCH 5/7] Language extension parsing issue resolved --- scripts/leetcode.js | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/scripts/leetcode.js b/scripts/leetcode.js index 26fdb493..2d8c5940 100644 --- a/scripts/leetcode.js +++ b/scripts/leetcode.js @@ -492,19 +492,6 @@ function markUploaded() { /* ------------------------------------------------ LEETCODE WEB PAGE PARSING FUNCTIONS ------------------------------------------------------ */ -/* Get file extension for submission */ -function findLanguageExtension() { - const languageElement = document.querySelector('div.relative.notranslate button div'); - const language = languageElement.textContent; - if (language !== undefined && constant.languages[language] !== undefined) { - - // Return the respective file extension or language identifier - return constant.languages[language]; - } - return null; -} - - /* Function for finding and parsing the full code. */ function findCode(uploadGit, problemNameSlug, fileName, msg, action, cb = undefined) { const currentURL = window.location.href; @@ -557,6 +544,9 @@ function findCode(uploadGit, problemNameSlug, fileName, msg, action, cb = undefi .then((submission) => { let code = submission.data.submissionDetails.code; + // Find language extension of the submission + let languageExtension = submission.data.submissionDetails.lang.name; + code = code.replace( /\\u[\dA-F]{4}/gi, function (match) { @@ -568,7 +558,7 @@ function findCode(uploadGit, problemNameSlug, fileName, msg, action, cb = undefi if (code != null) { setTimeout(function () { - uploadGit(btoa(code), problemNameSlug, fileName, msg, action, true, cb); + uploadGit(btoa(code), problemNameSlug, fileName + "." + languageExtension, msg, action, true, cb); }, 5000); } }); @@ -633,10 +623,10 @@ function parseStats() { const percentageRegex = constant.regex.percentageRegex; const time = problemStats.item(0).textContent; - const timePercentile = percentileStats.item(0).textContent.match(percentageRegex)[0]; + const timePercentile = percentileStats.item(2).textContent ? percentileStats.item(2).textContent.match(percentageRegex)[0] : null; const space = problemStats.item(1).textContent; - const spacePercentile = percentileStats.item(1).textContent.match(percentageRegex)[0]; + const spacePercentile = percentileStats.item(3).textContent ? percentileStats.item(3).textContent.match(percentageRegex)[0] : null; if (!checkElem(problemStats)) { return null; @@ -686,7 +676,7 @@ function parserFunction() { currentURL = window.location.href; // Get the current URL - if (currentURL.endsWith('/submissions/')) { + if (!currentURL.endsWith('/description/')) { try { // Checking if code has been accepted or not @@ -698,9 +688,6 @@ function parserFunction() { // Parse problem statistics problemStats = parseStats(); - // Find language extension of the submission - languageExtension = findLanguageExtension(); - // Get problem name and slug getProblemNameSlug() .then(({ problemName, problemNameSlug }) => { @@ -713,7 +700,7 @@ function parserFunction() { problemStatement = `

${problemName}

` + problemStatement; // Check if all required data is available - if (languageExtension && problemStatement && problemNameSlug && problemName) { + if (problemStatement && problemNameSlug && problemName) { startUpload(); uploadGit(btoa(problemStatement), problemNameSlug, 'README.md', readmeMsg, 'upload'); @@ -721,7 +708,7 @@ function parserFunction() { findCode( uploadGit, problemNameSlug, - problemNameSlug + languageExtension, + problemNameSlug, problemStats, 'upload', // Callback is called when the code upload to Git is successful @@ -755,6 +742,7 @@ function loaderFunction() { if (!flag) { submitButton.addEventListener('click', function () { clearInterval(loaderInterval); + successTag = null; parserFunction() .then(() => { loaderInterval = setInterval(loaderFunction, 1000); @@ -775,7 +763,6 @@ let flag = false; let successTag = null; let problemType; let problemStats; -let languageExtension; let loaderInterval = setInterval(loaderFunction, 1000); From 42e07cdf2fe15f4eecbc010c28a1173670c3c2e5 Mon Sep 17 00:00:00 2001 From: Muhammad Mustafa Bawany Date: Sun, 26 Nov 2023 08:01:47 -0800 Subject: [PATCH 6/7] Update README.md --- README.md | 35 +---------------------------------- 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/README.md b/README.md index 9af85584..7fb145e2 100644 --- a/README.md +++ b/README.md @@ -27,13 +27,6 @@

-
- - LeetHub - Automatically sync your code b/w Leetcode & GitHub. | Product Hunt - - - [![Chrome](https://user-images.githubusercontent.com/53124886/111952712-34f12300-8aee-11eb-9fdd-ad579a1eb235.png)](https://chrome.google.com/webstore/detail/leethub/aciombdipochlnkbpcbgdpjffcfdbggi) [![Firefox](https://user-images.githubusercontent.com/53124886/126341427-4a4e57aa-767a-467e-83d2-b31fa3564441.png)](https://addons.mozilla.org/en-US/firefox/addon/leethub/) -
@@ -59,21 +52,6 @@ As of now, GitHub is developers' #1 portfolio. LeetHub just makes it much easier

2. There's no easy way of accessing your leetcode problems in one place!
Moreover, pushing code manually to GitHub from Leetcode is very time consuming. So, why not just automate it entirely without spending a SINGLE additional second on it?

-## How does LeetHub work? - -

Your LeetHub portfolio could look like this!

-

It's as simple as:

-
    -
  1. After installation, launch LeetHub.
  2. -
  3. Click on "authorize with GitHub" button to automatically set up your account with LeetHub.
  4. -
  5. Setup an existing/new repository with LeetHub (private by default) by clicking "Get Started" button.
  6. -
  7. Begin Leetcoding! To view your progress, simply click on the extension!
  8. -
- - -#### BONUS: Star [this repository](https://github.com/QasimWani/LeetHub) for further development of features. If you want a particular feature, simply [request](https://github.com/QasimWani/LeetHub/labels/feature) for it! - - ## Why did I build LeetHub?

The coding interview is arguably the most important part of your interview process, given you get the interview first. As someone who's received multiple internship offers from Fortune 100 companies, getting the interview in the first place is not easy!
@@ -86,7 +64,7 @@ And that's what LeetHub is supposed to do: indirectly improving your coding skil ![leetcode view](assets/extension/leetcode.png) -# How to set up LeetHub for local development? +# How does LeetHub work?

  1. Fork this repo and clone to your local machine
  2. @@ -94,17 +72,6 @@ And that's what LeetHub is supposed to do: indirectly improving your coding skil
  3. Enable Developer mode by toggling the switch on top right corner
  4. Click 'Load unpacked'
  5. Select the entire LeetHub folder
  6. -
  7. Run "npm run setup" to install the developer dependencies
-Other npm commands available: - -``` -npm run Show list of commands available -npm run format Auto-format JavaScript, HTML/CSS -npm run format-test Test all code is formatted properly -npm run lint Lint JavaScript -npm run lint-test Test all code is linted properly -``` - #### And that should be it! Get Hacking... From 08243501e8f8c09f98dc20b02e1654df55910e55 Mon Sep 17 00:00:00 2001 From: mustafabawany Date: Sun, 17 Dec 2023 13:58:17 +0500 Subject: [PATCH 7/7] Fixed stats parsing on latest UI --- scripts/leetcode.js | 38 +++++++++++++------------------------- 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/scripts/leetcode.js b/scripts/leetcode.js index 2d8c5940..ad3be863 100644 --- a/scripts/leetcode.js +++ b/scripts/leetcode.js @@ -493,7 +493,7 @@ function markUploaded() { /* ------------------------------------------------ LEETCODE WEB PAGE PARSING FUNCTIONS ------------------------------------------------------ */ /* Function for finding and parsing the full code. */ -function findCode(uploadGit, problemNameSlug, fileName, msg, action, cb = undefined) { +function findCode(uploadGit, problemNameSlug, fileName, action, cb = undefined) { const currentURL = window.location.href; const questionSlug = currentURL.split('/')[4]; const variables = { @@ -545,7 +545,7 @@ function findCode(uploadGit, problemNameSlug, fileName, msg, action, cb = undefi let code = submission.data.submissionDetails.code; // Find language extension of the submission - let languageExtension = submission.data.submissionDetails.lang.name; + let languageExtension = constant.languages[submission.data.submissionDetails.lang.verboseName]; code = code.replace( /\\u[\dA-F]{4}/gi, @@ -556,9 +556,16 @@ function findCode(uploadGit, problemNameSlug, fileName, msg, action, cb = undefi }, ); + const timePercentile = parseFloat(submission.data.submissionDetails.runtimePercentile).toFixed(2); + const time = submission.data.submissionDetails.runtimeDisplay; + const space = submission.data.submissionDetails.memory; + const spacePercentile = parseFloat(submission.data.submissionDetails.memoryPercentile).toFixed(2); + + const msg = formatStats(time, timePercentile, space, spacePercentile); + if (code != null) { setTimeout(function () { - uploadGit(btoa(code), problemNameSlug, fileName + "." + languageExtension, msg, action, true, cb); + uploadGit(btoa(code), problemNameSlug, fileName + languageExtension, msg, action, true, cb); }, 5000); } }); @@ -615,25 +622,10 @@ function parseQuestion() { }) } -/* Parser function for time/space stats */ -function parseStats() { - const problemStats = document.getElementsByClassName(constant.elementTags.problemStatsTag); - const percentileStats = document.getElementsByClassName(constant.elementTags.percentileStatsTag); - - const percentageRegex = constant.regex.percentageRegex; - - const time = problemStats.item(0).textContent; - const timePercentile = percentileStats.item(2).textContent ? percentileStats.item(2).textContent.match(percentageRegex)[0] : null; - - const space = problemStats.item(1).textContent; - const spacePercentile = percentileStats.item(3).textContent ? percentileStats.item(3).textContent.match(percentageRegex)[0] : null; - - if (!checkElem(problemStats)) { - return null; - } - +/* Formatter function for time/space stats */ +function formatStats(time, timePercentile, space, spacePercentile) { // Format commit message - return `Time: ${time} (${timePercentile}), Space: ${space} (${spacePercentile}) - LeetHub`; + return `Time: ${time} (${timePercentile}%), Space: ${space} (${spacePercentile}%) - LeetHub`; } function getProblemNameSlug() { @@ -685,9 +677,6 @@ function parserFunction() { if (checkElem(successTag) && successTag === 'Accepted') { problemType = NORMAL_PROBLEM; - // Parse problem statistics - problemStats = parseStats(); - // Get problem name and slug getProblemNameSlug() .then(({ problemName, problemNameSlug }) => { @@ -709,7 +698,6 @@ function parserFunction() { uploadGit, problemNameSlug, problemNameSlug, - problemStats, 'upload', // Callback is called when the code upload to Git is successful () => {