diff --git a/.eslintrc.json b/.eslintrc.json index f9b22b793c2998a2d5b65850b80b8a459bab32f4..45479a73085e8ebd20c8ec58258f1b985854a6fe 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,24 +1,67 @@ { - "root": true, - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaVersion": 6, - "sourceType": "module" - }, - "plugins": [ - "@typescript-eslint" + "root": true, + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 6, + "sourceType": "module" + }, + "plugins": [ + "@typescript-eslint", + "prettier" + ], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", + "prettier" + ], + "rules": { + "@typescript-eslint/semi": "off", + "@typescript-eslint/explicit-function-return-type": "off", + "@typescript-eslint/camelcase": ["off"], + "@typescript-eslint/no-use-before-define": ["error", { "functions": false }], + "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }], + "@typescript-eslint/no-non-null-assertion":["off"], + "@typescript-eslint/explicit-module-boundary-types":["off"], + "@typescript-eslint/naming-convention": [ + "error", + { + "selector": [ + "classProperty", + "objectLiteralProperty", + "typeProperty", + "classMethod", + "objectLiteralMethod", + "typeMethod", + "accessor", + "enumMember" + ], + "format": null, + "modifiers": ["requiresQuotes"] + } ], - "rules": { - "@typescript-eslint/naming-convention": "warn", - "@typescript-eslint/semi": "warn", - "curly": "warn", - "eqeqeq": "warn", - "no-throw-literal": "warn", - "semi": "off" - }, - "ignorePatterns": [ - "out", - "dist", - "**/*.d.ts" + "curly": "error", + "eqeqeq": "error", + "no-throw-literal": "error", + "semi": [ + "error", + "never" + ], + "indent": [ + "error", + "tab", + { + "SwitchCase": 1, + "ignoredNodes": [ + "ConditionalExpression" + ] + } + ], + "prefer-const": [ + "error", + { + "destructuring": "all" + } ] -} + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 0b60dfa12fb992ff3c1555855471510558356a46..71c63a7acbae2307ebb30758e9eb8e6b316911ab 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ out -dist node_modules .vscode-test/ *.vsix +yarn-error.log +yarn.lock +package-lock.json diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000000000000000000000000000000000000..36246ca537904524c1bc34d0fb17e5dac44e3a3a --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,8 @@ +{ + "trailingComma": "es5", + "tabWidth": 4, + "semi": false, + "singleQuote": true, + "useTabs": true, + "printWidth": 120 +} \ No newline at end of file diff --git a/.vscodeignore b/.vscodeignore index 389996760c6238122bee7c4edf1584c194f77a57..c06f4a7b8528ff4e5bd14a1ca700ad22ace2d288 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -1,8 +1,8 @@ .vscode/** .vscode-test/** +out/test/** src/** .gitignore -.yarnrc vsc-extension-quickstart.md **/tsconfig.json **/.eslintrc.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f2b46c8854abc9a9c0f36c09fefaa78ddb019ea..e343908591ac055d8dadab150ac15383c1f2d1c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,247 @@ -# Change Log +# Changelog -All notable changes to the "leetcode-design" extension will be documented in this file. +All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. -Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. +### [0.0.9](https://github.com/supperchong/algorithm/compare/v0.0.8...v0.0.9) (2022-05-24) -## [Unreleased] -- Initial release \ No newline at end of file +### Bug Fixes + +* change domain ([c2a814e](https://github.com/supperchong/algorithm/commit/c2a814e2af6b0e5c042bba8fce95aa729d5842b9)) + +### 0.0.8 (2022-03-14) + + +### Features + +* add ask for auto import algm ([e1c5159](https://github.com/supperchong/algorithm/commit/e1c51595782a892d628b8762134e8927dba3b059)) +* add build codeLense ([78074fa](https://github.com/supperchong/algorithm/commit/78074fa6560ebf4ecc55420b9a009e324a79dbb0)) +* add history view ([01757a2](https://github.com/supperchong/algorithm/commit/01757a2338011545f1d2f76fde990f875fae6a99)) +* add memo ([ec21de5](https://github.com/supperchong/algorithm/commit/ec21de54918e9919ee66ecd88a9f74d39776e097)) +* add solution link ([9ca75ec](https://github.com/supperchong/algorithm/commit/9ca75ec97280ac7fa82b9f34f51f3703945ce117)) +* initial ([00fb843](https://github.com/supperchong/algorithm/commit/00fb84374ed1c8fe70522ca298f950b6f5e4b466)) +* support auto add testcase when submit fail ([cc80120](https://github.com/supperchong/algorithm/commit/cc801207de495e95b666836ef0808c4d590865b9)) +* support c++ ([9b787e4](https://github.com/supperchong/algorithm/commit/9b787e41160baf9e86b7a2315f56db829db70cc0)) +* support character type ([4da7a39](https://github.com/supperchong/algorithm/commit/4da7a3916b4d5be1dd7563bada9b1d7f07c4a965)) +* support display locked questions ([f06bcf8](https://github.com/supperchong/algorithm/commit/f06bcf835a8bc8fc0c366745b36332e6787f8874)) +* support golang ([ca149cc](https://github.com/supperchong/algorithm/commit/ca149cc944dbddb6f47a686979754c3befa4174b)) +* support java ([ea6d595](https://github.com/supperchong/algorithm/commit/ea6d595cd29faf8eb3925f1264357ca9588e94d8)) +* support python ([05c288d](https://github.com/supperchong/algorithm/commit/05c288d7a2ebeb559b74a0aa439178b995d7ad65)) +* support python3 ([0366e5c](https://github.com/supperchong/algorithm/commit/0366e5c9accb4db59b859e34a4d24ad2453992c5)) +* support shell ([777e135](https://github.com/supperchong/algorithm/commit/777e1350b9ee72e01454ebf9f9a2fdc1125736dc)) +* support sql ([06f22ce](https://github.com/supperchong/algorithm/commit/06f22ceca87178132959e3c5ca017df461b375ff)) + + +### Bug Fixes + +* add algm version check ([dfb5737](https://github.com/supperchong/algorithm/commit/dfb573789964b1138ef1328f9e08ec6a43527a1d)) +* auto refresh question when login ([b3969c1](https://github.com/supperchong/algorithm/commit/b3969c1739747515c3016b7cc7830584799518fe)) +* change the result of the serialize ([41d4724](https://github.com/supperchong/algorithm/commit/41d47245eefbf8631cc036877152dd1ece478ab8)) +* change the result of the serialize ([9b964df](https://github.com/supperchong/algorithm/commit/9b964dfe23dcc20a65b0eef0c383c1061ccf16cd)) +* check the file ext ([18dc04a](https://github.com/supperchong/algorithm/commit/18dc04a21ec0bca478d71cbfba75ae50987d613a)) +* complement metaData type ([fe4e64c](https://github.com/supperchong/algorithm/commit/fe4e64cc7976b23502a95bcdbabf990e7062e8f1)) +* delete cache when refresh require ([beb27ac](https://github.com/supperchong/algorithm/commit/beb27ac9d6a2bed712070c70ad3a0db9d4f501e0)) +* **en:** support fetch submission detail ([b2a987a](https://github.com/supperchong/algorithm/commit/b2a987a4274f216565d7b3c78502ffdd65ae89d1)) +* ensure the folder in the memo unique ([#4](https://github.com/supperchong/algorithm/issues/4)) ([3313a56](https://github.com/supperchong/algorithm/commit/3313a560f92a53183bf15b6f4ef4d2549df56690)) +* fix buildcode view highlight ([dfaf3a0](https://github.com/supperchong/algorithm/commit/dfaf3a01ecc430df03fb72bdd69036d5dff09b30)) +* fix code and question in same column ([a9bbaaa](https://github.com/supperchong/algorithm/commit/a9bbaaad4fe54bf1e38bb6e5c1ec001453224964)) +* fix duplicate tag ([907544a](https://github.com/supperchong/algorithm/commit/907544a6677198188568b682445316f7d0cb6519)) +* fix envFile merge ([#3](https://github.com/supperchong/algorithm/issues/3)) ([ad395a1](https://github.com/supperchong/algorithm/commit/ad395a1c8d5c45570824fa869e21094e568a2cd7)) +* fix error message ([c611bbf](https://github.com/supperchong/algorithm/commit/c611bbf72c5dc1554a2c894bffd32d566ef24d22)) +* fix esbuild and algm install ([5c200f9](https://github.com/supperchong/algorithm/commit/5c200f96278b70802a197b5c6afd0414f4886b03)) +* fix login but not refresh ([cbd664a](https://github.com/supperchong/algorithm/commit/cbd664a402d472396538134335333f4a199b5ba9)) +* fix request err handle ([d5f547d](https://github.com/supperchong/algorithm/commit/d5f547de70cfae50cddc2a4238012fda6600dfd7)) +* fix request submissions params ([31903b5](https://github.com/supperchong/algorithm/commit/31903b58d8eed3b1b413510a1f58a25db7b66fb4)) +* fix spelling errors ([0d41b27](https://github.com/supperchong/algorithm/commit/0d41b276fa8911550db5700c0d919ad30b80579a)), closes [#13](https://github.com/supperchong/algorithm/issues/13) +* fix submissions null error ([06e04de](https://github.com/supperchong/algorithm/commit/06e04de28349413a5ca7701553114d10d83af86d)) +* fix tag empty ([2f86bd2](https://github.com/supperchong/algorithm/commit/2f86bd2ffd771d7ef8f32be1a5b3e156ccdad20a)) +* fix the test process not exit ([1f8b2c6](https://github.com/supperchong/algorithm/commit/1f8b2c6997a86b12649dc2a77b109fe3a3671c7c)), closes [#14](https://github.com/supperchong/algorithm/issues/14) +* fix type null error ([44140f8](https://github.com/supperchong/algorithm/commit/44140f82f9788e97f67893d2894dfcda23fcd610)) +* import ListNode and TreeNode in js and ts ([f72e125](https://github.com/supperchong/algorithm/commit/f72e125a4854ff553a3cfc9e826021378c93b518)) +* **java:** add missing comma ([b4a2c74](https://github.com/supperchong/algorithm/commit/b4a2c7486885046bedd4842e6c7cecc7743d237d)) +* move @babel/core to dependencies ([b52fe63](https://github.com/supperchong/algorithm/commit/b52fe630ed61d97211a4ac78f3b817ea18adbe1e)) +* only algorithmic questions support testing ([22424f8](https://github.com/supperchong/algorithm/commit/22424f8f490f832ade1744e1824f65582d3220ce)) +* only check esbuild when debug ts ([533902f](https://github.com/supperchong/algorithm/commit/533902f9a086fcf1741016fcaf3a1f94c7fc1f9c)) +* only check esbuild when debug ts ([11b04ae](https://github.com/supperchong/algorithm/commit/11b04ae2c4e192e469228e091f56003526681590)) +* **python:** change None to null ([f373977](https://github.com/supperchong/algorithm/commit/f37397794592c41ca09d290a08126fd56c2562df)) +* record multiple versions ([5912b54](https://github.com/supperchong/algorithm/commit/5912b54f3b3e5b3ed75aed2c1b2bd10d250a30f2)) +* remove repeated code ([9a11f3c](https://github.com/supperchong/algorithm/commit/9a11f3c2baa46d6003a7cb42ea5b75f1d97b439b)) +* remove repeated code ([a7db1e9](https://github.com/supperchong/algorithm/commit/a7db1e992950cccf1a4a838ae80fa452d4401adc)) +* remove require.resolve due to cache ([e9239e8](https://github.com/supperchong/algorithm/commit/e9239e8bcc7f27ed38fb60f96fb23e233e3b0013)) +* remove unuse module ([a2ed4b2](https://github.com/supperchong/algorithm/commit/a2ed4b20b0e26af53fe79120b1a9dd7461f5a9d9)) +* support cpp debug for m1 ([52c9fae](https://github.com/supperchong/algorithm/commit/52c9fae3012f6f289adf4989ba36dd7e966672d3)) +* support long type ([b08589a](https://github.com/supperchong/algorithm/commit/b08589a97bde7523f491c2909a34c98ad2a4b792)), closes [#33](https://github.com/supperchong/algorithm/issues/33) +* support other building code highlight ([8f6ad1c](https://github.com/supperchong/algorithm/commit/8f6ad1c71471492cf25e4c416edd03ee90b03fd3)) +* **ts:** support TreeNode and ListNode in test ([f019506](https://github.com/supperchong/algorithm/commit/f0195068125ba919e5895c812122c76897a13e48)) +* use codeLang to handle js/ts ([abac4c9](https://github.com/supperchong/algorithm/commit/abac4c9c43d542c70bd83577e2ddb708dbb44c39)) +* use copy instead of rename ([0772526](https://github.com/supperchong/algorithm/commit/077252657f873b765f17fc7e996f5f7ebaa2c28a)) +* use require to check whether esbuild ([269371b](https://github.com/supperchong/algorithm/commit/269371bb418b4c2f3aaa2faf4ef3e4d567ca4128)) + +### 0.0.7 (2021-10-12) + + +### Features + +* add ask for auto import algm ([e1c5159](https://github.com/supperchong/algorithm/commit/e1c51595782a892d628b8762134e8927dba3b059)) +* add build codeLense ([78074fa](https://github.com/supperchong/algorithm/commit/78074fa6560ebf4ecc55420b9a009e324a79dbb0)) +* add history view ([01757a2](https://github.com/supperchong/algorithm/commit/01757a2338011545f1d2f76fde990f875fae6a99)) +* add memo ([ec21de5](https://github.com/supperchong/algorithm/commit/ec21de54918e9919ee66ecd88a9f74d39776e097)) +* add solution link ([9ca75ec](https://github.com/supperchong/algorithm/commit/9ca75ec97280ac7fa82b9f34f51f3703945ce117)) +* initial ([00fb843](https://github.com/supperchong/algorithm/commit/00fb84374ed1c8fe70522ca298f950b6f5e4b466)) +* support auto add testcase when submit fail ([cc80120](https://github.com/supperchong/algorithm/commit/cc801207de495e95b666836ef0808c4d590865b9)) +* support c++ ([9b787e4](https://github.com/supperchong/algorithm/commit/9b787e41160baf9e86b7a2315f56db829db70cc0)) +* support character type ([4da7a39](https://github.com/supperchong/algorithm/commit/4da7a3916b4d5be1dd7563bada9b1d7f07c4a965)) +* support display locked questions ([f06bcf8](https://github.com/supperchong/algorithm/commit/f06bcf835a8bc8fc0c366745b36332e6787f8874)) +* support golang ([ca149cc](https://github.com/supperchong/algorithm/commit/ca149cc944dbddb6f47a686979754c3befa4174b)) +* support java ([ea6d595](https://github.com/supperchong/algorithm/commit/ea6d595cd29faf8eb3925f1264357ca9588e94d8)) +* support python ([05c288d](https://github.com/supperchong/algorithm/commit/05c288d7a2ebeb559b74a0aa439178b995d7ad65)) +* support python3 ([0366e5c](https://github.com/supperchong/algorithm/commit/0366e5c9accb4db59b859e34a4d24ad2453992c5)) +* support shell ([777e135](https://github.com/supperchong/algorithm/commit/777e1350b9ee72e01454ebf9f9a2fdc1125736dc)) +* support sql ([06f22ce](https://github.com/supperchong/algorithm/commit/06f22ceca87178132959e3c5ca017df461b375ff)) + + +### Bug Fixes + +* add algm version check ([dfb5737](https://github.com/supperchong/algorithm/commit/dfb573789964b1138ef1328f9e08ec6a43527a1d)) +* auto refresh question when login ([b3969c1](https://github.com/supperchong/algorithm/commit/b3969c1739747515c3016b7cc7830584799518fe)) +* change the result of the serialize ([41d4724](https://github.com/supperchong/algorithm/commit/41d47245eefbf8631cc036877152dd1ece478ab8)) +* change the result of the serialize ([9b964df](https://github.com/supperchong/algorithm/commit/9b964dfe23dcc20a65b0eef0c383c1061ccf16cd)) +* check the file ext ([18dc04a](https://github.com/supperchong/algorithm/commit/18dc04a21ec0bca478d71cbfba75ae50987d613a)) +* complement metaData type ([fe4e64c](https://github.com/supperchong/algorithm/commit/fe4e64cc7976b23502a95bcdbabf990e7062e8f1)) +* delete cache when refresh require ([beb27ac](https://github.com/supperchong/algorithm/commit/beb27ac9d6a2bed712070c70ad3a0db9d4f501e0)) +* **en:** support fetch submission detail ([b2a987a](https://github.com/supperchong/algorithm/commit/b2a987a4274f216565d7b3c78502ffdd65ae89d1)) +* ensure the folder in the memo unique ([#4](https://github.com/supperchong/algorithm/issues/4)) ([3313a56](https://github.com/supperchong/algorithm/commit/3313a560f92a53183bf15b6f4ef4d2549df56690)) +* fix buildcode view highlight ([dfaf3a0](https://github.com/supperchong/algorithm/commit/dfaf3a01ecc430df03fb72bdd69036d5dff09b30)) +* fix code and question in same column ([a9bbaaa](https://github.com/supperchong/algorithm/commit/a9bbaaad4fe54bf1e38bb6e5c1ec001453224964)) +* fix duplicate tag ([907544a](https://github.com/supperchong/algorithm/commit/907544a6677198188568b682445316f7d0cb6519)) +* fix envFile merge ([#3](https://github.com/supperchong/algorithm/issues/3)) ([ad395a1](https://github.com/supperchong/algorithm/commit/ad395a1c8d5c45570824fa869e21094e568a2cd7)) +* fix error message ([c611bbf](https://github.com/supperchong/algorithm/commit/c611bbf72c5dc1554a2c894bffd32d566ef24d22)) +* fix esbuild and algm install ([5c200f9](https://github.com/supperchong/algorithm/commit/5c200f96278b70802a197b5c6afd0414f4886b03)) +* fix login but not refresh ([cbd664a](https://github.com/supperchong/algorithm/commit/cbd664a402d472396538134335333f4a199b5ba9)) +* fix request err handle ([d5f547d](https://github.com/supperchong/algorithm/commit/d5f547de70cfae50cddc2a4238012fda6600dfd7)) +* fix request submissions params ([31903b5](https://github.com/supperchong/algorithm/commit/31903b58d8eed3b1b413510a1f58a25db7b66fb4)) +* fix spelling errors ([0d41b27](https://github.com/supperchong/algorithm/commit/0d41b276fa8911550db5700c0d919ad30b80579a)), closes [#13](https://github.com/supperchong/algorithm/issues/13) +* fix submissions null error ([06e04de](https://github.com/supperchong/algorithm/commit/06e04de28349413a5ca7701553114d10d83af86d)) +* fix tag empty ([2f86bd2](https://github.com/supperchong/algorithm/commit/2f86bd2ffd771d7ef8f32be1a5b3e156ccdad20a)) +* fix the test process not exit ([1f8b2c6](https://github.com/supperchong/algorithm/commit/1f8b2c6997a86b12649dc2a77b109fe3a3671c7c)), closes [#14](https://github.com/supperchong/algorithm/issues/14) +* fix type null error ([44140f8](https://github.com/supperchong/algorithm/commit/44140f82f9788e97f67893d2894dfcda23fcd610)) +* import ListNode and TreeNode in js and ts ([f72e125](https://github.com/supperchong/algorithm/commit/f72e125a4854ff553a3cfc9e826021378c93b518)) +* **java:** add missing comma ([b4a2c74](https://github.com/supperchong/algorithm/commit/b4a2c7486885046bedd4842e6c7cecc7743d237d)) +* move @babel/core to dependencies ([b52fe63](https://github.com/supperchong/algorithm/commit/b52fe630ed61d97211a4ac78f3b817ea18adbe1e)) +* only algorithmic questions support testing ([22424f8](https://github.com/supperchong/algorithm/commit/22424f8f490f832ade1744e1824f65582d3220ce)) +* only check esbuild when debug ts ([533902f](https://github.com/supperchong/algorithm/commit/533902f9a086fcf1741016fcaf3a1f94c7fc1f9c)) +* only check esbuild when debug ts ([11b04ae](https://github.com/supperchong/algorithm/commit/11b04ae2c4e192e469228e091f56003526681590)) +* **python:** change None to null ([f373977](https://github.com/supperchong/algorithm/commit/f37397794592c41ca09d290a08126fd56c2562df)) +* record multiple versions ([5912b54](https://github.com/supperchong/algorithm/commit/5912b54f3b3e5b3ed75aed2c1b2bd10d250a30f2)) +* remove repeated code ([9a11f3c](https://github.com/supperchong/algorithm/commit/9a11f3c2baa46d6003a7cb42ea5b75f1d97b439b)) +* remove repeated code ([a7db1e9](https://github.com/supperchong/algorithm/commit/a7db1e992950cccf1a4a838ae80fa452d4401adc)) +* remove require.resolve due to cache ([e9239e8](https://github.com/supperchong/algorithm/commit/e9239e8bcc7f27ed38fb60f96fb23e233e3b0013)) +* remove unuse module ([a2ed4b2](https://github.com/supperchong/algorithm/commit/a2ed4b20b0e26af53fe79120b1a9dd7461f5a9d9)) +* support cpp debug for m1 ([52c9fae](https://github.com/supperchong/algorithm/commit/52c9fae3012f6f289adf4989ba36dd7e966672d3)) +* support other building code highlight ([8f6ad1c](https://github.com/supperchong/algorithm/commit/8f6ad1c71471492cf25e4c416edd03ee90b03fd3)) +* **ts:** support TreeNode and ListNode in test ([f019506](https://github.com/supperchong/algorithm/commit/f0195068125ba919e5895c812122c76897a13e48)) +* use codeLang to handle js/ts ([abac4c9](https://github.com/supperchong/algorithm/commit/abac4c9c43d542c70bd83577e2ddb708dbb44c39)) +* use copy instead of rename ([0772526](https://github.com/supperchong/algorithm/commit/077252657f873b765f17fc7e996f5f7ebaa2c28a)) +* use require to check whether esbuild ([269371b](https://github.com/supperchong/algorithm/commit/269371bb418b4c2f3aaa2faf4ef3e4d567ca4128)) + +### [0.0.6](https://github.com/supperchong/algorithm/compare/v0.0.5...v0.0.6) (2021-07-08) + + +### Bug Fixes + +* fix the test process not exit ([1f8b2c6](https://github.com/supperchong/algorithm/commit/1f8b2c6997a86b12649dc2a77b109fe3a3671c7c)), closes [#14](https://github.com/supperchong/algorithm/issues/14) + +### [0.0.5](https://github.com/supperchong/algorithm/compare/v0.0.4...v0.0.5) (2021-07-05) + + +### Bug Fixes + +* fix spelling errors ([0d41b27](https://github.com/supperchong/algorithm/commit/0d41b276fa8911550db5700c0d919ad30b80579a)), closes [#13](https://github.com/supperchong/algorithm/issues/13) + +### 0.0.4 (2021-06-16) + + +### Features + +* add ask for auto import algm ([e1c5159](https://github.com/supperchong/algorithm/commit/e1c51595782a892d628b8762134e8927dba3b059)) +* add build codeLense ([78074fa](https://github.com/supperchong/algorithm/commit/78074fa6560ebf4ecc55420b9a009e324a79dbb0)) +* add history view ([01757a2](https://github.com/supperchong/algorithm/commit/01757a2338011545f1d2f76fde990f875fae6a99)) +* add memo ([ec21de5](https://github.com/supperchong/algorithm/commit/ec21de54918e9919ee66ecd88a9f74d39776e097)) +* add solution link ([9ca75ec](https://github.com/supperchong/algorithm/commit/9ca75ec97280ac7fa82b9f34f51f3703945ce117)) +* initial ([00fb843](https://github.com/supperchong/algorithm/commit/00fb84374ed1c8fe70522ca298f950b6f5e4b466)) +* support auto add testcase when submit fail ([cc80120](https://github.com/supperchong/algorithm/commit/cc801207de495e95b666836ef0808c4d590865b9)) +* support c++ ([9b787e4](https://github.com/supperchong/algorithm/commit/9b787e41160baf9e86b7a2315f56db829db70cc0)) +* support golang ([ca149cc](https://github.com/supperchong/algorithm/commit/ca149cc944dbddb6f47a686979754c3befa4174b)) +* support java ([ea6d595](https://github.com/supperchong/algorithm/commit/ea6d595cd29faf8eb3925f1264357ca9588e94d8)) +* support python ([05c288d](https://github.com/supperchong/algorithm/commit/05c288d7a2ebeb559b74a0aa439178b995d7ad65)) +* support python3 ([0366e5c](https://github.com/supperchong/algorithm/commit/0366e5c9accb4db59b859e34a4d24ad2453992c5)) +* support shell ([777e135](https://github.com/supperchong/algorithm/commit/777e1350b9ee72e01454ebf9f9a2fdc1125736dc)) +* support sql ([06f22ce](https://github.com/supperchong/algorithm/commit/06f22ceca87178132959e3c5ca017df461b375ff)) + + +### Bug Fixes + +* add algm version check ([dfb5737](https://github.com/supperchong/algorithm/commit/dfb573789964b1138ef1328f9e08ec6a43527a1d)) +* auto refresh question when login ([b3969c1](https://github.com/supperchong/algorithm/commit/b3969c1739747515c3016b7cc7830584799518fe)) +* change the result of the serialize ([41d4724](https://github.com/supperchong/algorithm/commit/41d47245eefbf8631cc036877152dd1ece478ab8)) +* check the file ext ([18dc04a](https://github.com/supperchong/algorithm/commit/18dc04a21ec0bca478d71cbfba75ae50987d613a)) +* fix buildcode view highlight ([dfaf3a0](https://github.com/supperchong/algorithm/commit/dfaf3a01ecc430df03fb72bdd69036d5dff09b30)) +* **en:** support fetch submission detail ([b2a987a](https://github.com/supperchong/algorithm/commit/b2a987a4274f216565d7b3c78502ffdd65ae89d1)) +* change the result of the serialize ([9b964df](https://github.com/supperchong/algorithm/commit/9b964dfe23dcc20a65b0eef0c383c1061ccf16cd)) +* complement metaData type ([fe4e64c](https://github.com/supperchong/algorithm/commit/fe4e64cc7976b23502a95bcdbabf990e7062e8f1)) +* delete cache when refresh require ([beb27ac](https://github.com/supperchong/algorithm/commit/beb27ac9d6a2bed712070c70ad3a0db9d4f501e0)) +* ensure the folder in the memo unique ([#4](https://github.com/supperchong/algorithm/issues/4)) ([3313a56](https://github.com/supperchong/algorithm/commit/3313a560f92a53183bf15b6f4ef4d2549df56690)) +* fix code and question in same column ([a9bbaaa](https://github.com/supperchong/algorithm/commit/a9bbaaad4fe54bf1e38bb6e5c1ec001453224964)) +* fix envFile merge ([#3](https://github.com/supperchong/algorithm/issues/3)) ([ad395a1](https://github.com/supperchong/algorithm/commit/ad395a1c8d5c45570824fa869e21094e568a2cd7)) +* fix error message ([c611bbf](https://github.com/supperchong/algorithm/commit/c611bbf72c5dc1554a2c894bffd32d566ef24d22)) +* fix esbuild and algm install ([5c200f9](https://github.com/supperchong/algorithm/commit/5c200f96278b70802a197b5c6afd0414f4886b03)) +* fix request err handle ([d5f547d](https://github.com/supperchong/algorithm/commit/d5f547de70cfae50cddc2a4238012fda6600dfd7)) +* fix request submissions params ([31903b5](https://github.com/supperchong/algorithm/commit/31903b58d8eed3b1b413510a1f58a25db7b66fb4)) +* fix submissions null error ([06e04de](https://github.com/supperchong/algorithm/commit/06e04de28349413a5ca7701553114d10d83af86d)) +* import ListNode and TreeNode in js and ts ([f72e125](https://github.com/supperchong/algorithm/commit/f72e125a4854ff553a3cfc9e826021378c93b518)) +* only algorithmic questions support testing ([22424f8](https://github.com/supperchong/algorithm/commit/22424f8f490f832ade1744e1824f65582d3220ce)) +* only check esbuild when debug ts ([533902f](https://github.com/supperchong/algorithm/commit/533902f9a086fcf1741016fcaf3a1f94c7fc1f9c)) +* only check esbuild when debug ts ([11b04ae](https://github.com/supperchong/algorithm/commit/11b04ae2c4e192e469228e091f56003526681590)) +* remove require.resolve due to cache ([e9239e8](https://github.com/supperchong/algorithm/commit/e9239e8bcc7f27ed38fb60f96fb23e233e3b0013)) +* remove unuse module ([a2ed4b2](https://github.com/supperchong/algorithm/commit/a2ed4b20b0e26af53fe79120b1a9dd7461f5a9d9)) +* support other building code highlight ([8f6ad1c](https://github.com/supperchong/algorithm/commit/8f6ad1c71471492cf25e4c416edd03ee90b03fd3)) +* **java:** add missing comma ([b4a2c74](https://github.com/supperchong/algorithm/commit/b4a2c7486885046bedd4842e6c7cecc7743d237d)) +* **python:** change None to null ([f373977](https://github.com/supperchong/algorithm/commit/f37397794592c41ca09d290a08126fd56c2562df)) +* use copy instead of rename ([0772526](https://github.com/supperchong/algorithm/commit/077252657f873b765f17fc7e996f5f7ebaa2c28a)) +* **ts:** support TreeNode and ListNode in test ([f019506](https://github.com/supperchong/algorithm/commit/f0195068125ba919e5895c812122c76897a13e48)) +* move @babel/core to dependencies ([b52fe63](https://github.com/supperchong/algorithm/commit/b52fe630ed61d97211a4ac78f3b817ea18adbe1e)) +* record multiple versions ([5912b54](https://github.com/supperchong/algorithm/commit/5912b54f3b3e5b3ed75aed2c1b2bd10d250a30f2)) +* remove repeated code ([9a11f3c](https://github.com/supperchong/algorithm/commit/9a11f3c2baa46d6003a7cb42ea5b75f1d97b439b)) +* remove repeated code ([a7db1e9](https://github.com/supperchong/algorithm/commit/a7db1e992950cccf1a4a838ae80fa452d4401adc)) +* use codeLang to handle js/ts ([abac4c9](https://github.com/supperchong/algorithm/commit/abac4c9c43d542c70bd83577e2ddb708dbb44c39)) +* use require to check whether esbuild ([269371b](https://github.com/supperchong/algorithm/commit/269371bb418b4c2f3aaa2faf4ef3e4d567ca4128)) + +### [0.0.3](https://github.com/supperchong/algorithm/compare/v0.0.2...v0.0.3) (2021-03-16) + + +### Features + +* add ask for auto import algm ([e1c5159](https://github.com/supperchong/algorithm/commit/e1c51595782a892d628b8762134e8927dba3b059)) + + +### Bug Fixes + +* fix code and question in same column ([a9bbaaa](https://github.com/supperchong/algorithm/commit/a9bbaaad4fe54bf1e38bb6e5c1ec001453224964)) +* fix error message ([c611bbf](https://github.com/supperchong/algorithm/commit/c611bbf72c5dc1554a2c894bffd32d566ef24d22)) +* fix esbuild and algm install ([5c200f9](https://github.com/supperchong/algorithm/commit/5c200f96278b70802a197b5c6afd0414f4886b03)) +* fix request err handle ([d5f547d](https://github.com/supperchong/algorithm/commit/d5f547de70cfae50cddc2a4238012fda6600dfd7)) +* record multiple versions ([5912b54](https://github.com/supperchong/algorithm/commit/5912b54f3b3e5b3ed75aed2c1b2bd10d250a30f2)) + +### [0.0.2](https://github.com/supperchong/algorithm/compare/v0.0.1...v0.0.2) (2021-03-13) + + +### Bug Fixes + +* move @babel/core to dependencies ([b52fe63](https://github.com/supperchong/algorithm/commit/b52fe630ed61d97211a4ac78f3b817ea18adbe1e)) + +### 0.0.1 (2021-03-13) + + +### Features + +* initial ([00fb843](https://github.com/supperchong/algorithm/commit/00fb84374ed1c8fe70522ca298f950b6f5e4b466)) diff --git a/README.md b/README.md index 33a392d7c650d183e8948a50bfb98832ef2abcbe..e00120df1fc80a51b2b27ccc6cf77bccc1019634 100644 --- a/README.md +++ b/README.md @@ -1,70 +1,204 @@ -# leetcode-design README +# algorithm -This is the README for your extension "leetcode-design". After writing up a brief description, we recommend including the following sections. +An excellent vscode extension for leetcode. -## Features +## Document | [中文文档](./docs/README_zh-CN.md) -Describe specific features of your extension including screenshots of your extension in action. Image paths are relative to this README file. +## Quick Start -For example if there is an image subfolder under your extension project workspace: +![Quick Start](./images/debug.gif) -\!\[feature X\]\(images/feature-x.png\) +## Support -> Tip: Many popular extensions utilize animations. This is an excellent way to show off your extension! We recommend short, focused animations that are easy to follow. +- javascript +- typescript +- python3 +- golang +- java +- c++ +- shell +- sql + +**will support other language soon** + +## Main Features + +- write testcase in the file and run test in local, support link list and tree + +- debug the testcase + +- memo + +- multi-solution and history + +- support import module, bundle code and copy the build code.(only support js/ts) + +- contain contest (Do not submit directly when you attending weekly contest, + copy the code and submit in browser instead.) + +## Other Features + +- search question +- contain daily challenge +- support login in https://leetcode.com/ and https://leetcode.cn/ ## Requirements -If you have any requirements or dependencies, add a section describing those and how to install and configure them. +- javascript/typescript + + - Nodejs 12+ + + > The `test` and `debug` will use `node` to execute. + > Make sure that `node` is in your PATH environment variable.If you're using nvm, you may need to set the `algorithm.nodePath` in the VS Code settings. + +- python3 + + - Make sure that `python3` is in your PATH environment variable. + - install the official Python extension(https://code.visualstudio.com/docs/python/python-tutorial) + +- golang + + - Make sure that `go` is in your PATH environment variable. + - install the official golang extension + +- java + + - Make sure that `java`,`javac` is in your PATH environment variable.Or [set javaPath and javacPath](#setting) + - install the official java extension (https://code.visualstudio.com/docs/java/java-tutorial) + > ensure the extension `Debugger for Java`>=v0.33.1 or the extension `Java Extension Pack`>=v0.14.0 + +- c++ + + - Install GCC C++ compiler (g++).And make sure that `g++` is in your PATH environment variable. + - Install the C++ extension for VS Code. + more detail in the website (https://code.visualstudio.com/docs/cpp/config-linux) + +## Pick a question + +Click the question in the `algorithm view` + +## Switch code lang + +press `ctrl+shift+p` and run the Command `algorithm:switch default language` + +## Switch database + +press `ctrl+shift+p` and run the Command `algorithm:switch default database` + +## shortcut buttons + +> Just click the shortcut button in the `view toolbar` to + +- refresh question +- search question +- login in +- switch endpoint +- collapse all + +![shortcut buttons](./images/shortcut.png) + +## Switch endpoint + +### current support: + +- leetcode.com +- leetcode.cn + +> Note: The accounts of different endpoints are not shared. + +## Login in + +The way to login in referred to the official extension [vscode-leetcode](https://github.com/LeetCode-OpenSource/vscode-leetcode). + +- leetcode.com support github and cookie login. +- leetcode.cn support account,github and cookie login. + +## Test in the file + +The code contains default testcase from question preview. + +By clicking the test codelens hover in the vscode to run the test in local. + +You can add customized testcase in the code like `// @test(param)=result`. +![test](./images/test.png) + +## Debug + +You only need to set breakpoints on the testcase line and set breakpoints for the code. + +:tada: Then enjoy debugging! + +![debug](./images/debug.png) + +> Note:If you are debugging java,ensure the extension `Debugger for Java`>=v0.33.1 or the extension `Java Extension Pack`>=v0.14.0. If you build error when debugging,press `ctrl+shift+p` and run the Command `Java:Clean Java Language Server Workspace`. + +> Note:If you are debugging c++ in m1, you need install the vscode extension named `CodeLLDB` + +## Submit -## Extension Settings +Click the submit hover to submit your code. You can use build to view the final submitted code. -Include if your extension adds any VS Code settings through the `contributes.configuration` extension point. +![build.png](./images/build.png) -For example: +## Memo -This extension contributes the following settings: +You can create different folders and add questions to them. +![memo](./images/memo.gif) -* `myExtension.enable`: enable/disable this extension -* `myExtension.thing`: set to `blah` to do something +## Multi-solution and History -## Known Issues +![solution](./images/history.png) -Calling out known issues can help limit users opening duplicate issues against your extension. +1. Click the history codelens, you will see the answers and submit history. +2. Add the comment `@desc $(method name)` in the code, it will generate description or comment when `submit` or use `new leetcode answer` command. +3. Right click the mouse,you will see the `new leetcode answer` command.This command will save your old answer and init a new answer.You can scan it in 4. +4. the old answers +5. submit solution save in local +6. submit solution save in leetcode -## Release Notes +## Weekly Contest -Users appreciate release notes as you update your extension. +When you participate in Weekly Contest, you may choose c++,java,python. Because they have the built-in library like STL that contains priority queue,order set etc. -### 1.0.0 +Now you have another choice. -Initial release of ... +### **Attention!** -### 1.0.1 +Do not submit directly when you attend weekly contest,click `build` and then +click `copy` to copy code , finally paste the code in browser and submit. -Fixed issue #. +### build code & copy code -### 1.1.0 +This is useful in the weekly contest. -Added features X, Y, and Z. +- click the build codelens hover. ------------------------------------------------------------------------------------------------------------ -## Following extension guidelines +![build.png](./images/build.png) -Ensure that you've read through the extensions guidelines and follow the best practices for creating your extension. +- focus the code view then click the copy icon. -* [Extension Guidelines](https://code.visualstudio.com/api/references/extension-guidelines) +![copy.png](./images/copy.png) -## Working with Markdown +> The code import module [algm](https://github.com/supperchong/algm) which contains many useful function and data structure, such as `priority queue`,`Segment tree`, `union–find` ,`skip list`. :rocket: Thanks to treeshake and rollup, the bundle code is very clean. -**Note:** You can author your README using Visual Studio Code. Here are some useful editor keyboard shortcuts: +## Setting -* Split the editor (`Cmd+\` on macOS or `Ctrl+\` on Windows and Linux) -* Toggle preview (`Shift+CMD+V` on macOS or `Shift+Ctrl+V` on Windows and Linux) -* Press `Ctrl+Space` (Windows, Linux, macOS) to see a list of Markdown snippets +press `ctrl+,` or open `file->Preferences->Settings`, you will see User and Workspace setting. Workspace setting will override User setting. +open `Extensions->algorithm`,you will see the settings: -### For more information +| Setting Name | Description | Default Value | +| --------------- | ------------------------------------------------------------------------------------------------- | ------------- | +| Auto Import Str | The string will be inserted at the beginning of the coding file | "" | +| Base Dir | The path of the folder to save the problem files | $HOME/.alg | +| Code Lang | default code language | JavaScript | +| Lang | Specify the active endpoint.support leetcode.com and leetcode.cn | leetcode.com | +| Node Path | The absolute pathname of the executable that started the Node.js process. eg: /usr/local/bin/node | node | +| javaPath | The absolute pathname of java | java | +| javacPath | The absolute pathname of javac | javac | +| Database | default sql language | MySQL | +| displayLock | if true, will display the locked questions. | false | -* [Visual Studio Code's Markdown Support](http://code.visualstudio.com/docs/languages/markdown) -* [Markdown Syntax Reference](https://help.github.com/articles/markdown-basics/) +## Thanks -**Enjoy!** +Thanks to the official extension [vscode-leetcode](https://github.com/LeetCode-OpenSource/vscode-leetcode), the algorithm extension +has reference some design and the login method. diff --git a/docs/README_zh-CN.md b/docs/README_zh-CN.md new file mode 100644 index 0000000000000000000000000000000000000000..96d04382bc0bb484755a9b2fd3447ccb9b5f3585 --- /dev/null +++ b/docs/README_zh-CN.md @@ -0,0 +1,186 @@ +# algorithm + +An excellent vscode extension for leetcode. + +## Quick Start + +![Quick Start](../images/debug.gif) + +## Support + +- javascript +- typescript +- python3 +- golang +- java +- c++ +- shell +- sql + +**将会很快支持其它语言** + +## Main Features + +- 代码里包含默认测试用例,也可以添加自定义的测试用例,点击测试按钮 自动在本地运行,支持链表和二叉树。 + +- debug 指定测试用例 + +- 备忘录 + +- 一题多解和提交历史 + +- 支持 import module, 打包代码, 快速复制打包的代码.(此功能仅支持 js/ts) + +- 包含周赛 (正式比赛时直接使用 submit 是无效的,应该使用复制代码,然后在浏览器提交.) + +## Other Features + +- 搜索题目 +- 每日一题 +- 支持同时登录 https://leetcode.com/ 和 https://leetcode.cn/ + +## 运行条件 + +- javascript/typescript + + - Nodejs 12+ + + > 默认会使用 node 执行测试和 debug,如果是使用 nvm 安装的,需要设置选项`algorithm.nodePath` + +- python3 + + - python3 + - 安装官方 Python 插件(https://code.visualstudio.com/docs/python/python-tutorial) + +- golang + + - 确保 `go` 在环境变量里 + - 安装 golang 官方插件 + +- java + + - 确保`java`,`javac`在环境变量里,或者[设置 javaPath 和 javacPath](#Setting). + - 安装 java 官方插件(https://code.visualstudio.com/docs/java/java-tutorial) + +- c++ + + - 安装 GCC C++编译器(g++).确保`g++`在环境变量里. + - 安装 c++插件.(https://code.visualstudio.com/docs/cpp/config-linux) + +## 选择题目 + +在 `algorithm view` 选择题目 + +## 切换语言 + +按 `ctrl+shift+p` 选择 `algorithm:switch default language`,目前支持 javascript,typescript,python3,golang,java,c++ + +## 切换数据库 + +按 `ctrl+shift+p` 选择 `algorithm:switch default database`,选择 `MySQL`,`MS SQL Server`,`Oracle` + +## 快捷按钮 + +> `view toolbar`有以下几种按钮 + +- refresh question +- search question +- login in +- switch endpoint +- collapse all + +![shortcut buttons](../images/shortcut.png) + +## 切换 leetcode 版本 + +### 目前支持: + +- leetcode.com +- leetcode.cn + +> Note: 账户不互通. + +## 登录 + +登录方式参考了官方插件 [vscode-leetcode](https://github.com/LeetCode-OpenSource/vscode-leetcode). + +- leetcode.com 支持 github 和 cookie. +- leetcode.cn 支持 账号密码,github 和 cookie. + +## 运行测试 + +代码里包含默认测试用例,也可以自定义添加测试用例,点击测试按钮 自动在本地运行。 + +![test](../images/test.png) + +## Debug + +只需要在一个测试用例前设置断点,然后给函数添加断点,点击 debug 按钮,便可以运行 debug。 +支持 javascript,typescript,python3,golang,java。 + +:tada: + +![debug](../images/debug.png) + +> Note: 如果你正在调试 java,确保已经打开的问题没有语法错误,否则将会编译失败,因为所有问题在同一个目录下,而 java 相关插件只支持一个目录一个项目。比如你打开了问题 1,但是没有补全代码,然后开始 debug 问题 2,这时候会报语法错误,因为问题 1 应该返回一个值。如果语法正确后编译仍然失败尝试按住 `ctrl+shift+p` ,然后执行命令 `Java:Clean Java Language Server Workspace`. + +> Note:如果你在 mac m1 上调试 c++, 需要安装 vscode 插件 `CodeLLDB` + +## 提交 + +点击 submit 提交代码. 你可以使用 build 查看最终提交的代码. + +![build.png](../images/build.png) + +## 备忘录 + +可以在备忘录里新建不同文件夹,例如 dfs,bfs 等,然后将题目添加进去 +![memo](../images/memo.gif) + +## 一题多解和提交历史 + +![solution](./images/history.png) + +1. 点击 history,右边将会出现多种解法列表和提交历史。 +2. 在代码里添加注释 `@desc $(method name)`,在保存多解和提交的时候会自动生成备注。 +3. 右击鼠标可以看到命令`new leetcode answer`。这个命令将会保存解答,同时初始化新的解答。保存的解答可以在 4 中查看。 +4. 保存的多种解答 +5. 保存在本地的提交 +6. 保存在 leetcode 的提交 + +### **注意!** + +正式比赛时直接使用 submit 是无效的,应该先点击 build,再点击 copy, 最后在浏览器提交. + +### build code & copy code + +- 点击 build + +![build.png](../images/build.png) + +- 点击 copy + +![copy.png](../images/copy.png) + +> 如果使用 js/ts 的话, 会自动导入包 [algm](https://github.com/supperchong/algm) ,包含了许多方便的函数和数据结构, 如 优先队列,线段树, 并查集 ,跳跃表等等. :rocket: 由于 treeshake , 打包后的代码不包含多余的代码. + +## Setting + +按 `ctrl+,` 或者打开 `file->Preferences->Settings`。 +选择 `Extensions->algorithm`,将会看到: + +| Setting Name | Description | Default Value | +| --------------- | ------------------------------------------------ | ------------- | +| Auto Import Str | 字符串的值将会插入到代码前面 | "" | +| Base Dir | 题目保存目录 | $HOME/.alg | +| Code Lang | 使用的语言 | JavaScript | +| Lang | 使用指定的终端 | leetcode.com | +| Node Path | nodejs 可执行文件的路径. eg: /usr/local/bin/node | node | +| javaPath | java 可执行文件的路径. | java | +| javacPath | javac 可执行文件的路径. | javac | +| Database | 执行 sql 所用的数据库 | MySQL | +| displayLock | 展示锁住的题目 | false | + +## 感谢 + +感谢官方插件[vscode-leetcode](https://github.com/LeetCode-OpenSource/vscode-leetcode), 本插件参考了登录方式和一些设计 diff --git a/media/algorithm.svg b/media/algorithm.svg index 521f93956b83a413577a0f4a9daf3177f105ed9a..0f886ca49d1fc2cbd27d4197f356bb529b19cb56 100644 --- a/media/algorithm.svg +++ b/media/algorithm.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/media/leetcoding.svg b/media/leetcoding.svg new file mode 100644 index 0000000000000000000000000000000000000000..521f93956b83a413577a0f4a9daf3177f105ed9a --- /dev/null +++ b/media/leetcoding.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/package.json b/package.json index 82f1fcf5458aa068cb715a041b2cb5e1898192f0..d9eed3b86ec1e25b889ac58c9e7e2fbf638bd764 100644 --- a/package.json +++ b/package.json @@ -1,15 +1,16 @@ { "name": "leetcode-design", - "displayName": "leetcode-design", - "description": "", - "version": "0.0.1", - "engines": { - "vscode": "^1.69.0" - }, - "categories": [ - "Other" - ], - "icon": "images/algorithm.png", + "displayName": "leetcode-design", + "description": "solve, test, debug question for leetcode", + "version": "0.0.1", + "engines": { + "vscode": "^1.46.0" + }, + "publisher": "chenwei", + "categories": [ + "Other" + ], + "icon": "images/algorithm.png", "activationEvents": [ "onCommand:workbench.action.tasks.runTask", "onView:questions", @@ -26,88 +27,32 @@ ], "repository": { "type": "git", - "url": "https://github.com/supperchong/algorithm.git" + "url": "https://gitee.com/chen_wei_coolboy/leetcode-design.git" }, "main": "./out/extension.js", "contributes": { - "configuration": { - "title": "leetcode-design", - "properties": { - "algorithm.nodePath": { - "type": "string", - "default": "node", - "description": "The absolute pathname of the executable that started the Node.js process. eg: /usr/local/bin/node", - "scope": "window" - }, - "algorithm.javacPath": { - "type": "string", - "default": "javac", - "description": "The absolute pathname of the executable that started the javac process.", - "scope": "window" - }, - "algorithm.javaPath": { - "type": "string", - "default": "java", - "description": "The absolute pathname of the executable that started the java process.", - "scope": "window" - }, - "algorithm.lang": { - "type": "string", - "default": "en", - "enum": [ - "en", - "cn" - ], - "enumDescriptions": [ - "US", - "中国版" - ], - "scope": "window" - }, - "algorithm.codeLang": { - "type": "string", - "default": "JavaScript", - "enum": [ - "JavaScript", - "TypeScript", - "Python3", - "Go", - "Java", - "C++" - ], - "scope": "window" - }, - "algorithm.database": { - "type": "string", - "default": "MySQL", - "enum": [ - "MySQL", - "MS SQL Server", - "Oracle" - ], - "scope": "window" - }, - "algorithm.autoImportStr": { - "type": "string", - "default": "", - "description": "The string will be inserted at the beginning of the coding file", - "scope": "window" - }, - "algorithm.baseDir": { - "type": "string", - "default": "", - "description": "The path of the folder to save the problem files.", - "scope": "window" - }, - "algorithm.autoImportAlgm": { - "type": "boolean", - "description": "if true, will auto import algm at the beginning of the coding file." + "viewsContainers": { + "activitybar": [ + { + "id": "package-leetcoding", + "title": "leetcoding", + "icon": "media/leetcoding.svg" + } + ] + }, + "views": { + "package-leetcoding": [ + { + "id": "questions", + "name": "题目列表", + "contextualTitle": "Package Explorer" }, - "algorithm.displayLock": { - "type": "boolean", - "description": "if true, will display the locked questions." + { + "id": "memo", + "name": "备忘录", + "contextualTitle": "memo" } - } + ] }, "menus": { "editor/title": [ @@ -201,7 +146,7 @@ }, { "command": "algorithm.switchEndpoint", - "title": "切换模式:中文/英文", + "title": "切换 中文/English", "icon": "$(globe)", "category": "algorithm" }, @@ -281,28 +226,9 @@ "category": "algorithm" } ], - "viewsContainers": { - "activitybar": [ - { - "id": "package-leetcode-design", - "title": "leetcode-design", - "icon": "media/algorithm.svg" - } - ] - }, - "views": { - "package-leetcode-design": [ - { - "id": "questions", - "name": "问题列表", - "contextualTitle": "Package Explorer" - }, - { - "id": "memo", - "name": "备忘录", - "contextualTitle": "memo" - } - ] + "configuration": { + "title": "algorithm", + "properties": {} }, "taskDefinitions": [ { @@ -312,25 +238,63 @@ } ] }, - "scripts": { - "vscode:prepublish": "yarn run compile", - "compile": "tsc -p ./", - "watch": "tsc -watch -p ./", - "pretest": "yarn run compile && yarn run lint", - "lint": "eslint src --ext ts", - "test": "node ./out/test/runTest.js" - }, - "devDependencies": { - "@types/vscode": "^1.69.0", - "@types/glob": "^7.2.0", - "@types/mocha": "^9.1.1", - "@types/node": "16.x", - "@typescript-eslint/eslint-plugin": "^5.30.0", - "@typescript-eslint/parser": "^5.30.0", - "eslint": "^8.18.0", - "glob": "^8.0.3", - "mocha": "^10.0.0", - "typescript": "^4.7.4", - "@vscode/test-electron": "^2.1.5" - } + "scripts": { + "vscode:prepublish": "yarn run compile", + "compile": "tsc -p ./", + "lint": "eslint src --fix --ext ts", + "prettier-format": "prettier --config .prettierrc.json src/**/*.ts --write", + "watch": "tsc -watch -p ./", + "pretest": "yarn run compile && yarn run lint", + "test": "node ./out/test/runTest.js", + "unitTest": "node node_modules/mocha/bin/mocha ./src/test/unit" + }, + "husky": { + "hooks": { + "pre-commit": "npm run prettier-format && npm run lint" + } + }, + "devDependencies": { + "@types/babel__core": "^7.1.9", + "@types/esprima": "^4.0.2", + "@types/glob": "^7.1.1", + "@types/mocha": "^7.0.2", + "@types/node": "^13.11.0", + "@types/request": "^2.48.5", + "@types/vscode": "^1.46.0", + "@typescript-eslint/eslint-plugin": "^4.26.0", + "@typescript-eslint/parser": "^4.26.0", + "eslint": "^6.8.0", + "eslint-config-prettier": "^8.3.0", + "eslint-plugin-prettier": "^3.4.0", + "glob": "^7.1.6", + "husky": "^6.0.0", + "mocha": "^7.1.2", + "prettier": "^2.3.0", + "typescript": "^4.3.2", + "vscode-test": "^1.3.0" + }, + "dependencies": { + "@babel/core": "^7.13.10", + "@babel/preset-typescript": "^7.13.0", + "@rollup/plugin-babel": "^5.0.4", + "@rollup/plugin-node-resolve": "^11.2.1", + "@rollup/plugin-typescript": "^8.2.0", + "@rollup/plugin-virtual": "^2.1.0", + "acorn": "^8.0.4", + "algm": "^0.1.6", + "ast-types": "^0.14.2", + "axios": "^0.21.1", + "cheerio": "^1.0.0-rc.3", + "compressing": "^1.5.1", + "fs-extra": "^9.1.0", + "highlight.js": "^11.0.0", + "markdown-it": "^10.0.0", + "pretty-object-string": "2.0.0-beta.3", + "pretty-tag": "^0.1.1", + "recast": "^0.20.4", + "request": "^2.88.2", + "rimraf": "^3.0.2", + "rollup": "^2.40.0", + "source-map": "^0.7.3" + } } diff --git a/src/api/api.cn.ts b/src/api/api.cn.ts new file mode 100644 index 0000000000000000000000000000000000000000..cc5e307c4bf9ac6db3233f509499271d436da8c1 --- /dev/null +++ b/src/api/api.cn.ts @@ -0,0 +1,531 @@ +import axios, { AxiosError, AxiosRequestConfig } from 'axios' +import { cache } from '../cache' +import { + ConciseQuestion, + MapIdConciseQuestion, + CheckContestOptions, + CheckOptions, + SubmitContestOptions, + CheckResponse, + SubmitOptions, + SubmitResponse, + TagData, + favoritesData, + QuestionTranslationData, + TodayRecordData, + DailyQuestionRecordData, + DailyQuestionRecord, + QuestionData, + GraphqlRequestData, + ContestData, + SubmissionsOptions, + SubmissionsResponse, + UpdateCommentOptions, + UpdateCommentResponse, + SubmissionDetailOptions, + SubmissionDetailResponse, + TodayRecord, + Translation, + Question, +} from '../model/question.cn' +import { Problems, ErrorStatus, FlagType, Tag, checkParams, ContestDetail } from '../model/common' +import { showLoginMessage } from '../login/index' + +import { getDb } from '../db' +import { GraphRes } from '../model/common' +import { log, DomainCN } from '../config' +import { sortQuestions } from '../util' +import { uniqueArr } from '../common/util' +export const MAPIDQUESTION = 'MapIdQuestion' +const monthEns = [ + 'january', + 'february', + 'march', + 'april', + 'may', + 'june', + 'july', + 'august', + 'september', + 'october', + 'november', + 'december', +] +const curCategories = [ + { + label: '面试题', + category_slug: 'lcci', + }, + { + label: '剑指 Offer', + category_slug: 'lcof', + }, +] +type Category = 'all' | 'algorithms' | 'database' | 'shell' | 'concurrency' | 'lcof' | 'lcci' + +async function getHeaders() { + const cookie = await cache.getCookie() + return { + 'user-agent': + 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36', + // 'x-requested-with': "XMLHttpRequest", + ...cookie, + } +} +// export async function fetchAllQuestions() { +// const url = 'https://leetcode-cn.com/graphql' +// const headers = await getHeaders() +// axios.request({ +// url, +// headers, +// data: { +// operationName: "getQuestionTranslation", +// query: `query getQuestionTranslation($lang: String) {\n translations: allAppliedQuestionTranslations(lang: $lang) {\n title\n questionId\n __typename\n }\n}\n`, +// variables: {} +// } +// }) +// } + +async function request(config: AxiosRequestConfig): Promise { + const headers = await getHeaders() + + return axios + .request({ + ...config, + headers: { + ...config.headers, + ...headers, + }, + }) + .then((res) => res.data) + .catch(async (err: AxiosError) => { + if (err.response) { + if (err.response.status === ErrorStatus.Unlogin) { + showLoginMessage() + } else if (err.response.status === ErrorStatus.InvalidCookie) { + showLoginMessage() + } + } + if (err.message) { + log.appendLine(err.message) + } + + return Promise.reject(err) + }) +} +async function graphql(data: GraphqlRequestData): Promise { + const headers = await getHeaders() + return request>({ + url: `${DomainCN}/graphql`, + data, + method: 'POST', + headers: { + origin: DomainCN, + referer: `${DomainCN}/problemset/all/`, + ...headers, + }, + }).then((res) => { + if (res.errors) { + return Promise.reject(res.errors) + } + return res.data + }) +} +const config = { + allQuestions: { + operationName: 'getQuestionTranslation', + query: `query getQuestionTranslation($lang: String) {\n translations: allAppliedQuestionTranslations(lang: $lang) {\n title\n questionId\n __typename\n }\n}\n`, + variables: {}, + }, + getQuestionsByCategory(category: Category): AxiosRequestConfig { + return { + url: `${DomainCN}/api/problems/${category}/`, + method: 'GET', + } + }, + tags: { + url: `${DomainCN}/problems/api/tags/`, + referer: `${DomainCN}/problemset/all/`, + }, + favorites: { + url: `${DomainCN}/problems/api/favorites/`, + referer: `${DomainCN}/problemset/all/`, + }, + contests: { + operationName: null, + variables: {}, + query: '{\n brightTitle\n allContests {\n title\n titleSlug\n startTime\n duration\n originStartTime\n isVirtual\n __typename\n }\n}\n', + }, + getChapters() { + const monthIndex = new Date().getMonth() + const year = new Date().getFullYear() + const monthEn = monthEns[monthIndex] + const cardSlug = `${monthEn}-leetcoding-challenge-${year}` + return { + operationName: 'GetChapters', + variables: { cardSlug: cardSlug }, + query: 'query GetChapters($cardSlug: String!) {\n chapters(cardSlug: $cardSlug) {\n descriptionText\n id\n title\n slug\n __typename\n }\n}\n', + } + }, + getChapter(chapterId: string | number) { + const monthIndex = new Date().getMonth() + const year = new Date().getFullYear() + const monthEn = monthEns[monthIndex] + const cardSlug = `${monthEn}-leetcoding-challenge-${year}` + return { + operationName: 'GetChapter', + variables: { chapterId: chapterId, cardSlug: cardSlug }, + query: 'query GetChapter($chapterId: String, $cardSlug: String) {\n chapter(chapterId: $chapterId, cardSlug: $cardSlug) {\n ...ExtendedChapterDetail\n description\n __typename\n }\n}\n\nfragment ExtendedChapterDetail on ChapterNode {\n id\n title\n slug\n items {\n id\n title\n type\n info\n paidOnly\n chapterId\n isEligibleForCompletion\n prerequisites {\n id\n chapterId\n __typename\n }\n __typename\n }\n __typename\n}\n', + } + }, + todayRecord: { + operationName: 'questionOfToday', + variables: {}, + query: 'query questionOfToday {\n todayRecord {\n question {\n questionFrontendId\n titleSlug\n translatedTitle\n __typename\n }\n lastSubmission {\n id\n __typename\n }\n date\n userStatus\n __typename\n }\n}\n', + }, + getDailyQuestionRecords() { + const monthIndex = new Date().getMonth() + const year = new Date().getFullYear() + const monthEn = monthEns[monthIndex] + const cardSlug = `${monthEn}-leetcoding-challenge-${year}` + return { + operationName: 'GetChaptersWithItems', + variables: { cardSlug: cardSlug }, + query: 'query GetChaptersWithItems($cardSlug: String!) {\n chapters(cardSlug: $cardSlug) {\n ...ExtendedChapterDetail\n descriptionText\n __typename\n }\n}\n\nfragment ExtendedChapterDetail on ChapterNode {\n id\n title\n slug\n items {\n id\n title\n type\n info\n paidOnly\n chapterId\n isEligibleForCompletion\n prerequisites {\n id\n chapterId\n __typename\n }\n __typename\n }\n __typename\n}\n', + } + }, + getContest(titleSlug: string): AxiosRequestConfig { + return { + url: `${DomainCN}/contest/api/info/${titleSlug}/`, + method: 'GET', + } + }, + getQuestionDetail(titleSlug: string) { + return { + operationName: 'questionData', + variables: { titleSlug: titleSlug }, + query: 'query questionData($titleSlug: String!) {\n question(titleSlug: $titleSlug) {\n questionId\n questionFrontendId\n boundTopicId\n title\n titleSlug\n content\n translatedTitle\n translatedContent\n isPaidOnly\n difficulty\n likes\n dislikes\n isLiked\n similarQuestions\n contributors {\n username\n profileUrl\n avatarUrl\n __typename\n }\n langToValidPlayground\n topicTags {\n name\n slug\n translatedName\n __typename\n }\n companyTagStats\n codeSnippets {\n lang\n langSlug\n code\n __typename\n }\n stats\n hints\n solution {\n id\n canSeeDetail\n __typename\n }\n status\n sampleTestCase\n metaData\n judgerAvailable\n judgeType\n mysqlSchemas\n enableRunCode\n envInfo\n book {\n id\n bookName\n pressName\n source\n shortDescription\n fullDescription\n bookImgUrl\n pressImgUrl\n productUrl\n __typename\n }\n isSubscribed\n isDailyQuestion\n dailyRecordStatus\n editorType\n ugcQuestionId\n style\n __typename\n }\n}\n', + } + }, + getQuestionContest(titleSlug: string, weekname: string): AxiosRequestConfig { + return { + url: `${DomainCN}/contest/${weekname}/problems/${titleSlug}/`, + method: 'GET', + headers: { + referer: `${DomainCN}/contest/${weekname}/`, + }, + } + }, + getSubmitContest(options: SubmitContestOptions): AxiosRequestConfig { + const { titleSlug, weekname, question_id, typed_code } = options + checkParams(options, ['titleSlug', 'weekname', 'question_id', 'typed_code']) + return { + url: `${DomainCN}/contest/api/${weekname}/problems/${titleSlug}/submit/`, + method: 'POST', + headers: { + 'x-requested-with': 'XMLHttpRequest', + origin: DomainCN, + referer: `${DomainCN}/contest/${weekname}/problems/${titleSlug}/`, + }, + data: { + question_id: question_id, + data_input: '', + lang: 'javascript', + typed_code: typed_code, + test_mode: false, + judge_type: 'large', + }, + } + }, + getSubmit(options: SubmitOptions): AxiosRequestConfig { + const { titleSlug, question_id, typed_code, lang = 'javascript' } = options + checkParams(options, ['titleSlug', 'question_id', 'typed_code']) + return { + url: `${DomainCN}/problems/${titleSlug}/submit/`, + method: 'POST', + headers: { + referer: `${DomainCN}/problems/${titleSlug}/submissions/`, + origin: DomainCN, + }, + data: { + question_id, + lang, + typed_code, + test_mode: false, + test_judger: '', + questionSlug: titleSlug, + }, + } + }, + getCheck(options: CheckOptions): AxiosRequestConfig { + const { submission_id, titleSlug } = options + checkParams(options, ['submission_id', 'titleSlug']) + return { + url: `${DomainCN}/submissions/detail/${submission_id}/check/`, + method: 'GET', + headers: { + referer: `${DomainCN}/problems/${titleSlug}/submissions/`, + }, + } + }, + getContestCheck(options: CheckContestOptions): AxiosRequestConfig { + const { submission_id, titleSlug, weekname } = options + checkParams(options, ['submission_id', 'titleSlug', 'weekname']) + + return { + url: `${DomainCN}/submissions/detail/${submission_id}/check/`, + method: 'GET', + headers: { + referer: `${DomainCN}/contest/${weekname}/problems/${titleSlug}/`, + 'x-requested-with': 'XMLHttpRequest', + }, + } + }, + getSubmissions(options: SubmissionsOptions) { + const { titleSlug, limit = 40, offset = 0, lastKey = null } = options + return { + operationName: 'submissions', + variables: { + offset: offset, + limit: limit, + lastKey: lastKey, + questionSlug: titleSlug, + }, + query: 'query submissions($offset: Int!, $limit: Int!, $lastKey: String, $questionSlug: String!, $markedOnly: Boolean, $lang: String) {\n submissionList(offset: $offset, limit: $limit, lastKey: $lastKey, questionSlug: $questionSlug, markedOnly: $markedOnly, lang: $lang) {\n lastKey\n hasNext\n submissions {\n id\n statusDisplay\n lang\n runtime\n timestamp\n url\n isPending\n memory\n submissionComment {\n comment\n flagType\n __typename\n }\n __typename\n }\n __typename\n }\n}\n', + } + }, + getUpdateComment(options: UpdateCommentOptions) { + const { submissionId, flagType = FlagType.BLUE, comment } = options + return { + operationName: 'submissionCreateOrUpdateSubmissionComment', + variables: { + submissionId: submissionId, + flagType: flagType, + comment: comment, + }, + query: 'mutation submissionCreateOrUpdateSubmissionComment($submissionId: ID!, $flagType: SubmissionFlagTypeEnum!, $comment: String!) {\n submissionCreateOrUpdateSubmissionComment(comment: $comment, flagType: $flagType, submissionId: $submissionId) {\n ok\n __typename\n }\n}\n', + } + }, + getSubmissionDetail(options: SubmissionDetailOptions) { + const { id } = options + return { + operationName: 'mySubmissionDetail', + variables: { id: id }, + query: 'query mySubmissionDetail($id: ID!) {\n submissionDetail(submissionId: $id) {\n id\n code\n runtime\n memory\n rawMemory\n statusDisplay\n timestamp\n lang\n passedTestCaseCnt\n totalTestCaseCnt\n sourceUrl\n question {\n titleSlug\n title\n translatedTitle\n questionId\n __typename\n }\n ... on GeneralSubmissionNode {\n outputDetail {\n codeOutput\n expectedOutput\n input\n compileError\n runtimeError\n lastTestcase\n __typename\n }\n __typename\n }\n submissionComment {\n comment\n flagType\n __typename\n }\n __typename\n }\n}\n', + } + }, +} + +export const api = { + refreshQuestions, + getAllQuestions, + fetchTranslations(): Promise { + return graphql(config.allQuestions).then((data) => data.translations) + }, + fetchCategorieQuestions(categorie: Category): Promise { + return request(config.getQuestionsByCategory(categorie)) + }, + fetchContests() { + return graphql(config.contests).then((data) => data.allContests) + }, + fetchTags(): Promise { + return request(config.tags) + }, + fetchContest(titleSlug: string) { + return request(config.getContest(titleSlug)) + }, + fetchTodayRecord(): Promise { + return graphql(config.todayRecord).then((data) => data.todayRecord) + }, + /** + * 题单 + * @returns + */ + fetchFavorites(): Promise { + return request(config.favorites) + }, + fetchDailyQuestionRecords(): Promise<[DailyQuestionRecord]> { + return graphql(config.getDailyQuestionRecords()).then( + (data) => data.dailyQuestionRecords + ) + }, + fetchQuestionDetail(titleSlug: string): Promise { + if (cache.get(titleSlug)) { + return cache.get(titleSlug) + } + return graphql(config.getQuestionDetail(titleSlug)).then((data) => { + if (data && data.question && data.question.titleSlug === titleSlug) { + cache.set(titleSlug, data.question) + } + return cache.get(titleSlug) + }) + }, + fetchContestQuestionDetail(titleSlug: string, weekname: string): Promise { + return request(config.getQuestionContest(titleSlug, weekname)) + }, + submit(options: SubmitOptions): Promise { + return request(config.getSubmit(options)) + }, + submitContest(options: SubmitContestOptions): Promise { + return request(config.getSubmitContest(options)) + }, + check(options: CheckOptions): Promise { + return request(config.getCheck(options)) + }, + checkContest(options: CheckContestOptions): Promise { + return request(config.getContestCheck(options)) + }, + fetchSubmissions(options: SubmissionsOptions): Promise { + return graphql(config.getSubmissions(options)) + }, + updateComment(options: UpdateCommentOptions): Promise { + return graphql(config.getUpdateComment(options)) + }, + async fetchSubmissionDetail(options: SubmissionDetailOptions): Promise { + const submissionDetail = await graphql(config.getSubmissionDetail(options)) + if (submissionDetail.submissionDetail) { + return submissionDetail.submissionDetail?.code + } else { + return 'can not query' + } + }, +} +export async function getAllQuestions(): Promise { + const questions = cache.getQuestions() + if (questions.length) { + return questions + } + await refreshQuestions() + return cache.getQuestions() +} +export async function refreshQuestions(): Promise { + let questions: ConciseQuestion[] = [] + const data = await api.fetchCategorieQuestions('all') + questions = handleCategorieQuestions(data) + await setTranslations(questions) + sortQuestions(questions) + cache.setQuestions(questions) +} +async function getMapIdQuestion(): Promise { + if (cache.has(MAPIDQUESTION)) { + return cache.get(MAPIDQUESTION)! + } + const questions = await getAllQuestions() + const map: MapIdConciseQuestion = {} + for (let i = 0; i < questions.length; i++) { + const question = questions[i] + map[question.id] = question + } + cache.set(MAPIDQUESTION, map) + return map +} + +export async function getQuestionDetailById(id: string) { + const db = await getDb() + const out = await db.read(parseInt(id)) + if (out) { + return JSON.parse(out) + } +} +export async function saveQuestionDetail(question) { + const db = await getDb() + await db.add(JSON.stringify(question), Number(question.questionId), Number(question.questionFrontendId)) +} +export function getCategories() { + return curCategories +} +export async function getQuestionsByCategory(category: string) { + const c = curCategories.find((c) => c.category_slug === category) + if (!c) { + return [] + } + const label = c.label + const questions = await getAllQuestions() + return questions.filter((q) => q.fid.startsWith(label)) +} +export async function getTags() { + let tags: Tag[] | null | undefined = cache.getTags() + if (!tags) { + const data = await api.fetchTags() + tags = data.topics + cache.setTags(tags) + } + + return uniqueArr(tags.map((tag) => tag.translatedName || tag.name)) +} +export async function getQuestionsByTag(translatedName: string) { + const tags = cache.getTags() || [] + const tag = tags.find((tag) => tag.translatedName === translatedName || tag.name === translatedName) + + if (tag && tag.questions) { + const map = await getMapIdQuestion() + return tag.questions.map((id) => map[id]).filter((v) => !!v) + } + return [] +} +export async function getQuestionsByDifficult(difficult: string) { + const mapDifficultLevel = { + easy: 1, + medium: 2, + hard: 3, + } + const questions = await getAllQuestions() + return questions.filter((q) => q.level === mapDifficultLevel[difficult]) +} +function handleCategorieQuestions(data) { + const { stat_status_pairs } = data + const questions = stat_status_pairs.map((v) => ({ + fid: v.stat.frontend_question_id, + level: v.difficulty.level, + id: v.stat.question_id, + title: v.stat.question__title, + slug: v.stat.question__title_slug, + acs: v.stat.total_acs, + submitted: v.stat.total_submitted, + paid_only: v.paid_only, + status: v.status, + name: v.stat.question__title, + })) + return questions +} +async function setTranslations(questions) { + const translationsQuestions = await api.fetchTranslations() + const mapIdTitle = {} + for (let i = 0; i < translationsQuestions.length; i++) { + const { questionId, title } = translationsQuestions[i] + mapIdTitle[questionId] = title + } + for (let i = 0; i < questions.length; i++) { + const question = questions[i] + question.name = mapIdTitle[question.id] || question.title + } +} + +/** + * 获取 favorites 名称列表 + * @returns favoritesData[] + */ +export const getFavorites = async () => { + const list = await api.fetchFavorites() + cache.setFavorites(list) + return list +} + +/** + * 获取 favorites 题目列表 + */ +export const fetchFavoriteLists = async (difficult: string, fid: string) => { + const mapDifficultLevel = { + easy: 1, + medium: 2, + hard: 3, + } + const questions = await getAllQuestions() + const list = questions.map((v) => { + return v.fid + }) + console.log('list', list) + return questions.filter((q) => q.level === mapDifficultLevel[difficult] && q.fid.includes(fid)) +} + + diff --git a/src/api/api.ts b/src/api/api.ts new file mode 100644 index 0000000000000000000000000000000000000000..f0f7090e9fc11389efbb41058b31f6653ea4087c --- /dev/null +++ b/src/api/api.ts @@ -0,0 +1,472 @@ +import axios, { AxiosRequestConfig, AxiosError } from 'axios' +import { cache } from '../cache' +import { + ChapterItemRes, + ChaptersRes, + ChapterRes, + ConciseQuestion, + MapIdConciseQuestion, + CheckContestOptions, + CheckOptions, + SubmitContestOptions, + CheckResponse, + SubmitOptions, + SubmitResponse, + TagData, + DailyQuestionRecordData, + QuestionData, + GraphqlRequestData, + ContestData, + ChaptersProgressRes, + SubmissionsOptions, + SubmissionsResponse, + SubmissionDetailOptions, + Question, +} from '../model/question' +import { checkParams, ContestDetail, Problems, Tag } from '../model/common' +import { getDb } from '../db' +import { GraphRes, ErrorStatus } from '../model/common' +import { showLoginMessage } from '../login/index' +import { log, DomainEN } from '../config' +import { sortQuestions } from '../util' +import { parseSubmissionDetailHtml } from '../common/util' +import { MAPIDQUESTION } from './api.cn' + +const monthEns = [ + 'january', + 'february', + 'march', + 'april', + 'may', + 'june', + 'july', + 'august', + 'september', + 'october', + 'november', + 'december', +] + +type Category = 'algorithms' | 'database' | 'shell' | 'concurrency' | 'all' + +async function getHeaders() { + const cookie = await cache.getCookie() + return { + 'user-agent': + 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36', + // 'x-requested-with': "XMLHttpRequest", + ...cookie, + } +} + +async function request(config: AxiosRequestConfig): Promise { + const headers = await getHeaders() + + return axios + .request({ + ...config, + headers: { + ...config.headers, + ...headers, + }, + }) + .then((res) => res.data) + .catch(async (err: AxiosError) => { + if (err.response) { + if (err.response.status === ErrorStatus.Unlogin) { + showLoginMessage() + } else if (err.response.status === ErrorStatus.InvalidCookie) { + showLoginMessage() + } + } + if (err.message) { + log.appendLine(err.message) + } + return Promise.reject(err) + }) +} +async function graphql(data: GraphqlRequestData): Promise { + const headers = await getHeaders() + return request>({ + url: `${DomainEN}/graphql`, + data, + method: 'POST', + headers: { + origin: DomainEN, + referer: `${DomainEN}/problemset/all/`, + ...headers, + }, + }).then((res) => { + if (res.errors) { + return Promise.reject(res.errors) + } + return res.data + }) +} + +const config = { + allQuestions: { + operationName: 'getQuestionTranslation', + query: `query getQuestionTranslation($lang: String) {\n translations: allAppliedQuestionTranslations(lang: $lang) {\n title\n questionId\n __typename\n }\n}\n`, + variables: {}, + }, + getQuestionsByCategory(category: Category): AxiosRequestConfig { + return { + url: `${DomainEN}/api/problems/${category}/`, + method: 'GET', + } + }, + tags: { + url: `${DomainEN}/problems/api/tags/`, + referer: `${DomainEN}/problemset/all/`, + }, + contests: { + operationName: null, + variables: {}, + query: '{\n brightTitle\n allContests {\n title\n titleSlug\n startTime\n duration\n originStartTime\n isVirtual\n __typename\n }\n}\n', + }, + getChapters() { + const monthIndex = new Date().getMonth() + const year = new Date().getFullYear() + const monthEn = monthEns[monthIndex] + const cardSlug = `${monthEn}-leetcoding-challenge-${year}` + return { + operationName: 'GetChapters', + variables: { cardSlug: cardSlug }, + query: 'query GetChapters($cardSlug: String!) {\n chapters(cardSlug: $cardSlug) {\n descriptionText\n id\n title\n slug\n __typename\n }\n}\n', + } + }, + getChapter(chapterId: string | number) { + const monthIndex = new Date().getMonth() + const year = new Date().getFullYear() + const monthEn = monthEns[monthIndex] + const cardSlug = `${monthEn}-leetcoding-challenge-${year}` + return { + operationName: 'GetChapter', + variables: { chapterId: chapterId, cardSlug: cardSlug }, + query: 'query GetChapter($chapterId: String, $cardSlug: String) {\n chapter(chapterId: $chapterId, cardSlug: $cardSlug) {\n ...ExtendedChapterDetail\n description\n __typename\n }\n}\n\nfragment ExtendedChapterDetail on ChapterNode {\n id\n title\n slug\n items {\n id\n title\n type\n info\n paidOnly\n chapterId\n isEligibleForCompletion\n prerequisites {\n id\n chapterId\n __typename\n }\n __typename\n }\n __typename\n}\n', + } + }, + getChapterItem(itemId: string) { + return { + operationName: 'GetItem', + variables: { itemId: itemId }, + query: 'query GetItem($itemId: String!) {\n item(id: $itemId) {\n id\n title\n type\n paidOnly\n lang\n isEligibleForCompletion\n hasAppliedTimeTravelTicket\n question {\n questionId\n title\n titleSlug\n __typename\n }\n article {\n id\n title\n __typename\n }\n video {\n id\n __typename\n }\n htmlArticle {\n id\n __typename\n }\n webPage {\n id\n __typename\n }\n __typename\n }\n isCurrentUserAuthenticated\n validTimeTravelTicketCount\n}\n', + } + }, + getChaptersProgress() { + const monthIndex = new Date().getMonth() + const year = new Date().getFullYear() + const monthEn = monthEns[monthIndex] + const cardSlug = `${monthEn}-leetcoding-challenge-${year}` + return { + operationName: 'GetOrCreateExploreSession', + variables: { cardSlug: cardSlug }, + query: 'mutation GetOrCreateExploreSession($cardSlug: String!) {\n getOrCreateExploreSession(cardSlug: $cardSlug) {\n ok\n errors\n progress\n cardId\n __typename\n }\n}\n', + } + }, + getDailyQuestionRecords() { + const monthIndex = new Date().getMonth() + const year = new Date().getFullYear() + const monthEn = monthEns[monthIndex] + const cardSlug = `${monthEn}-leetcoding-challenge-${year}` + + return { + operationName: 'GetChaptersWithItems', + variables: { cardSlug: cardSlug }, + query: 'query GetChaptersWithItems($cardSlug: String!) {\n chapters(cardSlug: $cardSlug) {\n ...ExtendedChapterDetail\n descriptionText\n __typename\n }\n}\n\nfragment ExtendedChapterDetail on ChapterNode {\n id\n title\n slug\n items {\n id\n title\n type\n info\n paidOnly\n chapterId\n isEligibleForCompletion\n prerequisites {\n id\n chapterId\n __typename\n }\n __typename\n }\n __typename\n}\n', + } + }, + getContest(titleSlug: string): AxiosRequestConfig { + return { + url: `${DomainEN}/contest/api/info/${titleSlug}/`, + method: 'GET', + } + }, + getQuestionDetail(titleSlug: string) { + return { + operationName: 'questionData', + variables: { titleSlug: titleSlug }, + query: 'query questionData($titleSlug: String!) {\n question(titleSlug: $titleSlug) {\n questionId\n questionFrontendId\n boundTopicId\n title\n titleSlug\n content\n translatedTitle\n translatedContent\n isPaidOnly\n difficulty\n likes\n dislikes\n isLiked\n similarQuestions\n exampleTestcases\n contributors {\n username\n profileUrl\n avatarUrl\n __typename\n }\n topicTags {\n name\n slug\n translatedName\n __typename\n }\n companyTagStats\n codeSnippets {\n lang\n langSlug\n code\n __typename\n }\n stats\n hints\n solution {\n id\n canSeeDetail\n paidOnly\n hasVideoSolution\n paidOnlyVideo\n __typename\n }\n status\n sampleTestCase\n metaData\n judgerAvailable\n judgeType\n mysqlSchemas\n enableRunCode\n enableTestMode\n enableDebugger\n envInfo\n libraryUrl\n adminUrl\n __typename\n }\n}\n', + } + }, + getQuestionContest(titleSlug: string, weekname: string): AxiosRequestConfig { + return { + url: `${DomainEN}/contest/${weekname}/problems/${titleSlug}/`, + method: 'GET', + headers: { + referer: `${DomainEN}/contest/${weekname}/`, + }, + } + }, + getSubmitContest(options: SubmitContestOptions): AxiosRequestConfig { + const { titleSlug, weekname, question_id, typed_code } = options + checkParams(options, ['titleSlug', 'weekname', 'question_id', 'typed_code']) + return { + url: `${DomainEN}/contest/api/${weekname}/problems/${titleSlug}/submit/`, + method: 'POST', + headers: { + 'x-requested-with': 'XMLHttpRequest', + origin: DomainEN, + referer: `${DomainEN}/contest/${weekname}/problems/${titleSlug}/`, + }, + data: { + question_id: question_id, + data_input: '', + lang: 'javascript', + typed_code: typed_code, + test_mode: false, + judge_type: 'large', + }, + } + }, + getSubmit(options: SubmitOptions): AxiosRequestConfig { + const { titleSlug, question_id, typed_code, lang = 'javascript' } = options + checkParams(options, ['titleSlug', 'question_id', 'typed_code']) + return { + url: `${DomainEN}/problems/${titleSlug}/submit/`, + method: 'POST', + headers: { + referer: `${DomainEN}/problems/${titleSlug}/submissions/`, + origin: DomainEN, + }, + data: { + question_id, + lang, + typed_code, + test_mode: false, + test_judger: '', + questionSlug: titleSlug, + }, + } + }, + getCheck(options: CheckOptions): AxiosRequestConfig { + const { submission_id, titleSlug } = options + checkParams(options, ['submission_id', 'titleSlug']) + return { + url: `${DomainEN}/submissions/detail/${submission_id}/check/`, + method: 'GET', + headers: { + referer: `${DomainEN}/problems/${titleSlug}/submissions/`, + }, + } + }, + getContestCheck(options: CheckContestOptions): AxiosRequestConfig { + const { submission_id, titleSlug, weekname } = options + checkParams(options, ['submission_id', 'titleSlug', 'weekname']) + + return { + url: `${DomainEN}/submissions/detail/${submission_id}/check/`, + method: 'GET', + headers: { + referer: `${DomainEN}/contest/${weekname}/problems/${titleSlug}/`, + 'x-requested-with': 'XMLHttpRequest', + }, + } + }, + getSubmissions(options: SubmissionsOptions) { + const { titleSlug, limit = 40, offset = 0, lastKey = null } = options + return { + operationName: 'Submissions', + variables: { + questionSlug: titleSlug, + offset: offset, + limit: limit, + lastKey: lastKey, + }, + query: 'query Submissions($offset: Int!, $limit: Int!, $lastKey: String, $questionSlug: String!) {\n submissionList(offset: $offset, limit: $limit, lastKey: $lastKey, questionSlug: $questionSlug) {\n lastKey\n hasNext\n submissions {\n id\n statusDisplay\n lang\n runtime\n timestamp\n url\n isPending\n memory\n __typename\n }\n __typename\n }\n}\n', + } + }, + getSubmissionDetail(options: SubmissionDetailOptions): AxiosRequestConfig { + const { id: submission_id } = options + return { + url: `${DomainEN}/submissions/detail/${submission_id}/`, + method: 'GET', + headers: { + 'x-requested-with': 'XMLHttpRequest', + }, + } + }, +} +export const api = { + refreshQuestions, + getAllQuestions, + fetchCategorieQuestions(categorie: Category) { + return request(config.getQuestionsByCategory(categorie)) + }, + fetchContests() { + return graphql(config.contests).then((data) => data.allContests) + }, + fetchTags() { + return request(config.tags) + }, + fetchContest(titleSlug: string) { + return request(config.getContest(titleSlug)) + }, + fetchChapters() { + return graphql(config.getChapters()) + }, + fetchChapter(chapterId: string | number) { + return graphql(config.getChapter(chapterId)) + }, + fetchChapterProgress() { + return graphql(config.getChaptersProgress()) + }, + fetchDailyQuestionRecords() { + return graphql(config.getDailyQuestionRecords()).then( + (data) => data.dailyQuestionRecords + ) + }, + fetchChapterItem(id: string) { + return graphql(config.getChapterItem(id)) + }, + async fetchQuestionDetailByItemId(id: string) { + const { item } = await api.fetchChapterItem(id) + return api.fetchQuestionDetail(item.question.titleSlug) + }, + fetchQuestionDetail(titleSlug: string): Promise { + if (cache.get(titleSlug)) { + return cache.get(titleSlug) + } + return graphql(config.getQuestionDetail(titleSlug)).then((data) => { + if (data && data.question && data.question.titleSlug === titleSlug) { + cache.set(titleSlug, data.question) + } + return cache.get(titleSlug) + }) + }, + fetchContestQuestionDetail(titleSlug: string, weekname: string) { + return request(config.getQuestionContest(titleSlug, weekname)) + }, + submit(options: SubmitOptions) { + return request(config.getSubmit(options)) + }, + submitContest(options: SubmitContestOptions) { + return request(config.getSubmitContest(options)) + }, + check(options: CheckOptions) { + return request(config.getCheck(options)) + }, + checkContest(options: CheckContestOptions) { + return request(config.getContestCheck(options)) + }, + fetchSubmissions(options: SubmissionsOptions) { + return graphql(config.getSubmissions(options)) + }, + async fetchSubmissionDetail(options: SubmissionDetailOptions) { + const html = await request(config.getSubmissionDetail(options)) + const detail = handleSubmissionDetail(html) + if (typeof detail === 'undefined') { + return Promise.reject('can not query') + } + return detail + }, +} +export async function fetchAllQuestions() { + const url = `${DomainEN}/graphql` + const headers = await getHeaders() + axios.request({ + url, + headers, + data: { + operationName: 'getQuestionTranslation', + query: `query getQuestionTranslation($lang: String) {\n translations: allAppliedQuestionTranslations(lang: $lang) {\n title\n questionId\n __typename\n }\n}\n`, + variables: {}, + }, + }) +} + +export async function getAllQuestions() { + const questions = cache.getQuestions() + if (questions.length) { + return questions + } + await refreshQuestions() + return cache.getQuestions() +} +export async function refreshQuestions() { + let questions: ConciseQuestion[] = [] + const data = await api.fetchCategorieQuestions('all') + questions = handleCategorieQuestions(data) + sortQuestions(questions) + cache.setQuestions(questions) +} +async function getMapIdQuestion(): Promise { + if (cache.has(MAPIDQUESTION)) { + return cache.get(MAPIDQUESTION)! + } + const questions = await getAllQuestions() + const map: MapIdConciseQuestion = {} + for (let i = 0; i < questions.length; i++) { + const question = questions[i] + map[question.id] = question + } + cache.set(MAPIDQUESTION, map) + return map +} + +export async function getQuestionDetailById(id: string) { + const db = await getDb() + const out = await db.read(parseInt(id)) + if (out) { + return JSON.parse(out) + } +} +export async function saveQuestionDetail(question) { + const db = await getDb() + await db.add(JSON.stringify(question), Number(question.questionId), Number(question.questionFrontendId)) +} +export async function getTags() { + let tags: Tag[] | null | undefined = cache.getTags() + if (!tags) { + const data = await api.fetchTags() + tags = data.topics + cache.setTags(tags) + } + + return tags.map((tag) => tag.translatedName || tag.name) +} +export async function getQuestionsByTag(translatedName: string) { + const tags = cache.getTags() || [] + const tag = tags.find((tag) => tag.translatedName === translatedName || tag.name === translatedName) + + if (tag && tag.questions) { + const map = await getMapIdQuestion() + return tag.questions.map((id) => map[id]).filter((v) => !!v) + } + return [] +} +export async function getQuestionsByDifficult(difficult) { + const mapDifficultLevel = { + easy: 1, + medium: 2, + hard: 3, + } + const questions = await getAllQuestions() + return questions.filter((q) => q.level === mapDifficultLevel[difficult]) +} +function handleCategorieQuestions(data) { + const { stat_status_pairs } = data + const questions = stat_status_pairs.map((v) => ({ + fid: String(v.stat.frontend_question_id), + level: v.difficulty.level, + id: v.stat.question_id, + title: v.stat.question__title, + slug: v.stat.question__title_slug, + acs: v.stat.total_acs, + submitted: v.stat.total_submitted, + paid_only: v.paid_only, + status: v.status, + name: v.stat.question__title, + })) + return questions +} + +function handleSubmissionDetail(html: string): string | undefined { + const question = parseSubmissionDetailHtml(html) + if (question) { + return question.submissionCode + } else { + return + } +} diff --git a/src/api/index.ts b/src/api/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..d0b75af913e8ece4dc44394513ffbc72b6f56220 --- /dev/null +++ b/src/api/index.ts @@ -0,0 +1,120 @@ +import { config } from '../config' +import * as apiCn from './api.cn' +import * as apiEn from './api' +import { getDb } from '../db' +import * as modelCn from '../model/question.cn' +import * as modelEn from '../model/question' + +export const api = { + async fetchQuestionDetailById(id: string | number) { + if (typeof id === 'string') { + id = parseInt(id) + } + const db = await getDb() + const out = await db.read(id) + if (out) { + return JSON.parse(out) + } + }, + async fetchQuestionDetail(titleSlug: string) { + if (config.lang === 'en') { + return apiEn.api.fetchQuestionDetail(titleSlug) + } else { + return apiCn.api.fetchQuestionDetail(titleSlug) + } + }, + async fetchContestQuestionDetail(titleSlug: string, weekname: string) { + if (config.lang === 'en') { + return apiEn.api.fetchContestQuestionDetail(titleSlug, weekname) + } else { + return apiCn.api.fetchContestQuestionDetail(titleSlug, weekname) + } + }, + async fetchQuestionByItemId(id: string) { + if (config.lang === 'en') { + const res = await apiEn.api.fetchChapterItem(id) + return res.item.question + } + }, + async saveQuestionDetail(question) { + const db = await getDb() + await db.add(JSON.stringify(question), Number(question.questionId), Number(question.questionFrontendId)) + }, + async submitContest(options: modelCn.SubmitContestOptions | modelEn.SubmitContestOptions) { + if (config.lang === 'en') { + return apiEn.api.submitContest(options) + } else { + return apiCn.api.submitContest(options) + } + }, + async submit(options: modelCn.SubmitOptions | modelEn.SubmitOptions) { + if (config.lang === 'en') { + return apiEn.api.submit(options) + } else { + return apiCn.api.submit(options) + } + }, + + async check(options: modelCn.CheckOptions | modelEn.CheckOptions) { + if (config.lang === 'en') { + return apiEn.api.check(options) + } else { + return apiCn.api.check(options) + } + }, + checkContest(options: modelCn.CheckContestOptions | modelEn.CheckContestOptions) { + if (config.lang === 'en') { + return apiEn.api.checkContest(options) + } else { + return apiCn.api.checkContest(options) + } + }, + async getAllQuestions() { + if (config.lang === 'en') { + return apiEn.api.getAllQuestions() + } else { + return apiCn.api.getAllQuestions() + } + }, + async fetchSubmissions(options: modelCn.SubmissionsOptions | modelEn.SubmissionsOptions) { + if (config.lang === 'en') { + return apiEn.api.fetchSubmissions(options) + } else { + return apiCn.api.fetchSubmissions(options) + } + }, + async fetchSubmissionDetail(options: modelCn.SubmissionDetailOptions) { + if (config.lang === 'en') { + return apiEn.api.fetchSubmissionDetail(options) + } else { + return apiCn.api.fetchSubmissionDetail(options) + } + }, +} + +export async function refreshQuestions() { + if (config.lang === 'en') { + await apiEn.api.refreshQuestions() + } else { + await apiCn.api.refreshQuestions() + } +} + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +function handleCategorieQuestions(data) { + const { stat_status_pairs } = data + const questions = stat_status_pairs.map((v) => ({ + fid: String(v.stat.frontend_question_id), + level: v.difficulty.level, + id: v.stat.question_id, + title: v.stat.question__title, + slug: v.stat.question__title_slug, + acs: v.stat.total_acs, + submitted: v.stat.total_submitted, + paid_only: v.paid_only, + status: v.status, + name: v.stat.question__title, + })) + return questions +} +export { apiEn, apiCn } diff --git a/src/babelPlugin.ts b/src/babelPlugin.ts new file mode 100644 index 0000000000000000000000000000000000000000..7b5f4fedd90f138c7622f0c4b4245e1f9018c1cd --- /dev/null +++ b/src/babelPlugin.ts @@ -0,0 +1,124 @@ +import { types as t } from '@babel/core' +const regexp = /^@get\((-?\d+|Infinity|-Infinity)\)$/ + +function generatelogicalExpression(arr: t.Expression[]) { + if (arr.length === 2) { + return t.logicalExpression('&&', arr[0], arr[1]) + } else if (arr.length > 2) { + return t.logicalExpression('&&', arr[0], generatelogicalExpression(arr.slice(1))) + } else { + return arr[0] + } +} + +function toBinaryExpression(node) { + return t.binaryExpression('>=', node, t.numericLiteral(0)) +} +type NumberProperty = t.Identifier | t.NumericLiteral | t.BinaryExpression +type ComputeProperty = t.Identifier | t.BinaryExpression +function isValidNumberProperty(property: t.Expression | t.Identifier | t.PrivateName): property is NumberProperty { + return property.type === 'Identifier' || property.type === 'NumericLiteral' || property.type === 'BinaryExpression' +} +function isValidComputeProperty(property: NumberProperty): property is ComputeProperty { + return property.type === 'Identifier' || property.type === 'BinaryExpression' +} +export function outBoundArrayPlugin() { + return { + visitor: { + VariableDeclaration(path: babel.NodePath) { + if ( + t.isVariableDeclaration(path.node) && + path.node.leadingComments && + path.node.leadingComments.find((v) => regexp.test(v.value)) + ) { + const comment = path.node.leadingComments.find((v) => regexp.test(v.value)) as t.Comment + const regexpResult = regexp.exec(comment.value) as RegExpExecArray + const numStr = regexpResult[1] + let numNode: t.Identifier | t.UnaryExpression | t.NumericLiteral + if (numStr === 'Infinity') { + numNode = t.identifier('Infinity') + } else if (numStr === '-Infinity') { + numNode = t.unaryExpression('-', t.identifier('Infinity')) + } else { + numNode = t.numericLiteral(parseInt(numStr)) + } + const declaration = path.node.declarations[0] + const id = declaration.id + if (!t.isIdentifier(id)) { + return + } + const name = id.name + const bind = path.scope.bindings[name] + const referencePaths = bind.referencePaths + referencePaths.forEach((r) => { + let nodes: ComputeProperty[] = [] + while (r.parentPath && r.parentPath.node.type === 'MemberExpression' && r.parentPath.node.computed) { + const node = r.parentPath.node + if (!isValidNumberProperty(node.property)) { + return + } + if (isValidComputeProperty(node.property)) { + nodes.push(node.property) + } + + r = r.parentPath + } + + if (nodes.length && !(r.key === 'left' && r.parentPath && r.parentPath.type === 'AssignmentExpression')) { + nodes = nodes.map((node) => toBinaryExpression(node)) + r.replaceWith( + t.conditionalExpression( + generatelogicalExpression(nodes), + r.node as t.MemberExpression, + numNode + ) + ) + } + }) + } + }, + }, + } +} + +export function generateAddTestCommentPlugin(funcName: string, comment: string) { + return function addTestCommentPlugin() { + return { + visitor: { + VariableDeclaration(path: babel.NodePath) { + const funcDeclaration = path.node.declarations.find((dec) => { + return ( + dec.id.type === 'Identifier' && + dec.id.name === funcName && + dec.init?.type === 'FunctionExpression' + ) + }) + if (funcDeclaration) { + path.addComment('leading', comment, true) + path.stop() + } + }, + FunctionDeclaration(path: babel.NodePath) { + const name = path.node.id?.name + if (name === funcName) { + path.addComment('leading', comment, true) + path.stop() + } + }, + }, + } + } +} + +export function removeExtraTypePlugin() { + return { + visitor: { + ClassDeclaration(path: babel.NodePath) { + const extraTypes = ['ListNode', 'TreeNode'] + if (path.node.id && extraTypes.includes(path.node.id.name)) { + path.remove() + } + }, + }, + } +} diff --git a/src/cache.ts b/src/cache.ts new file mode 100644 index 0000000000000000000000000000000000000000..823bd0ab80de866b729e6ed745727f4df61b60c2 --- /dev/null +++ b/src/cache.ts @@ -0,0 +1,147 @@ +import { ConciseQuestion, MapIdConciseQuestion, Tag, Favorites } from './model/common' +import fs = require('fs') +import { config, Config, log } from './config' +import { reRequire } from './util' +const COOKIE = 'cookie' +const TAG = 'tag' +const FAVORITES = 'favorites' +export const ALLQUESTIONS = 'allQuestions' +export const MAPIDQUESTION = 'MapIdQuestion' +interface CacheMap { + [COOKIE]: Cookie + [TAG]: Tag[] + [ALLQUESTIONS]: ConciseQuestion[] + [MAPIDQUESTION]: MapIdConciseQuestion + [titleSlug: string]: any +} +interface Cookie { + cookie: string + 'x-csrftoken': string +} +class Cache { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + private cacheMap: Partial = {} + config: Config + constructor() { + this.config = config + } + removeCache() { + this.cacheMap = {} + } + get(key: T) { + return this.cacheMap[key] + } + set(key: T, value: R) { + this.cacheMap[key] = value + } + has(key: string) { + return key in this.cacheMap + } + async getCookie() { + const { cookiePath } = config + if (this.has(COOKIE)) { + return this.get(COOKIE) + } + try { + const cookie = reRequire(cookiePath) + this.set(COOKIE, cookie) + return this.get(COOKIE) + } catch (err) { + return null + } + } + getQuestions(): ConciseQuestion[] { + const { questionPath } = config + if (this.has(ALLQUESTIONS)) { + return this.get(ALLQUESTIONS) || [] + } + try { + const allQuestions = reRequire(questionPath) + let filterPrivilegeQuestions = allQuestions + if (!config.displayLock) { + filterPrivilegeQuestions = allQuestions.filter((v) => !v.paid_only) + } + this.set(ALLQUESTIONS, filterPrivilegeQuestions) + return this.get(ALLQUESTIONS) || [] + } catch (err) { + return [] + } + } + + setQuestions(questions: ConciseQuestion[]) { + const { questionPath } = config + let filterPrivilegeQuestions = questions + if (!config.displayLock) { + filterPrivilegeQuestions = questions.filter((v) => !v.paid_only) + } + this.set(ALLQUESTIONS, filterPrivilegeQuestions) + fs.writeFile( + questionPath, + JSON.stringify(filterPrivilegeQuestions), + { + encoding: 'utf8', + }, + (err) => { + if (err) { + log.append(err.message) + } + } + ) + } + updateQuestion(id: number, params: Partial) { + const questions: ConciseQuestion[] | undefined = this.get(ALLQUESTIONS) + if (questions) { + const question = questions.find((q) => q.id === id) + if (question) { + Object.assign(question, params) + this.setQuestions(questions) + } + } + } + getTags() { + const { tagPath } = config + if (this.has(TAG)) { + return this.get(TAG) + } + try { + const tags = reRequire(tagPath) + this.set(TAG, tags) + return this.get(TAG) + } catch (err) { + return null + } + } + setTags(tags: Tag[]) { + const { tagPath } = config + this.set(TAG, tags) + fs.writeFile( + tagPath, + JSON.stringify(tags), + { + encoding: 'utf8', + }, + (err) => { + if (err) { + log.append(err.message) + } + } + ) + } + setFavorites(list: Favorites[]) { + const { favoritsPath } = config + this.set(FAVORITES, list) + fs.writeFile( + favoritsPath, + JSON.stringify(list), + { + encoding: 'utf8', + }, + (err) => { + if (err) { + log.append(err.message) + } + } + ) + } +} +export const cache = new Cache() diff --git a/src/child_process/execTestCode.ts b/src/child_process/execTestCode.ts new file mode 100644 index 0000000000000000000000000000000000000000..d6f7e6025df66b768a525f9637d7dc189a746718 --- /dev/null +++ b/src/child_process/execTestCode.ts @@ -0,0 +1,146 @@ +import rollup = require('rollup') +import resolve from '@rollup/plugin-node-resolve' +import rollupBabelPlugin from '@rollup/plugin-babel' +import { transformSync } from '@babel/core' +import * as path from 'path' +import * as fs from 'fs' +import sourceMap = require('source-map') +import { TestResult, handleArgsType } from '../common/util' +import { outBoundArrayPlugin } from '../babelPlugin' +import { Script } from 'vm' +import { handleMsg } from '../common/util' +import { CodeLang, getFileLang } from '../common/langConfig' +import presetTs = require('@babel/preset-typescript') +import { TestOptions } from '../common/lang' +const virtual = require('@rollup/plugin-virtual') + +const defaultTimeout = 10000 +const supportCodeLang = [CodeLang.JavaScript, CodeLang.TypeScript] +let options = '' +process.stdin.on('data', (data) => { + options += data +}) +process.stdin.on('end', async () => { + try { + const msg = await execTestCase(JSON.parse(options.toString())) + console.log(msg) + } catch (err) { + console.log(err) + } +}) +async function execTestCase(options: TestOptions) { + const { caseList, filePath, metaData } = options + const lang = getFileLang(filePath) + if (!supportCodeLang.includes(lang)) { + return `${lang} is currently not supported` + } + const output = await buildCode(filePath, lang) + const code = output[0].code + const list: TestResult[] = [] + for (const { args, result: expect } of caseList) { + const originArgs = [...args] + + const finalCode = handleArgsType(metaData, code, args) + const script = new Script(finalCode, {}) + try { + const result = script.runInNewContext( + { + console, + }, + { + timeout: defaultTimeout, + displayErrors: true, + lineOffset: 0, + } + ) + list.push({ + args: originArgs.join(','), + expect: expect, + result: result, + }) + } catch (err) { + return handleErrPosition(err, output[0].map as rollup.SourceMap, originArgs) + } + } + return handleMsg(list) +} + +async function buildCode(filePath: string, lang: CodeLang) { + if (lang === CodeLang.TypeScript) { + return buildTsCode(filePath) + } + return buildJsCode(filePath) +} +async function buildJsCode(filePath: string) { + const plugins = [ + resolve(), + rollupBabelPlugin({ + babelHelpers: 'bundled', + comments: false, + plugins: [outBoundArrayPlugin], + }), + ] + const bundle = await rollup.rollup({ + input: filePath, + treeshake: false, + plugins, + }) + const { output } = await bundle.generate({ + sourcemap: true, + sourcemapPathTransform: (r, s) => { + return path.join(path.parse(s).dir, r) + }, + }) + return output +} + +async function buildTsCode(filePath: string) { + const code = fs.readFileSync(filePath, { encoding: 'utf8' }) + const fileDir = path.parse(filePath).dir + const entry = transformSync(code, { + filename: filePath, + comments: false, + cwd: fileDir, + presets: [[presetTs, { onlyRemoveTypeImports: true }]], + plugins: [outBoundArrayPlugin], + }) + + const bundle = await rollup.rollup({ + input: 'entry', + treeshake: false, + plugins: [ + virtual({ + entry: entry?.code || "", + }), + resolve({ rootDir: fileDir, browser: false }), + ], + }) + const { output } = await bundle.generate({}) + return output +} + +async function handleErrPosition(err: Error, map: sourceMap.RawSourceMap, args: string[]) { + const consumer = await new sourceMap.SourceMapConsumer(map) + + const regexp = /evalmachine\.:(\d+):?(\d+)?/g + let msg = `× @test(${args.join(',')})\n` + const stack: string = err.stack as string + msg += stack.replace(regexp, (_, line, column) => { + line = parseInt(line) + column = parseInt(column) || 0 + const originPosition = consumer.originalPositionFor({ + line: line, + column: column, + }) + if (originPosition.source) { + if (column) { + return originPosition.source + ':' + originPosition.line + ':' + originPosition.column + } else { + return originPosition.source + ':' + originPosition.line + } + } + return _ + }) + consumer.destroy() + return msg +} diff --git a/src/commands.ts b/src/commands.ts new file mode 100644 index 0000000000000000000000000000000000000000..17a3232328171e1fd9fed0bc0ced3cbc8b0f37a8 --- /dev/null +++ b/src/commands.ts @@ -0,0 +1,389 @@ +import { getFuncNames, QuestionMeta, retry } from './common/util' +import { checkBeforeDebug, execWithProgress, execWithProgress2 } from './util' +import { log, updateConfig } from './config' +import { window } from 'vscode' +import { createPanel } from './webview/buildCodeWebview' +import { api, refreshQuestions } from './api/index' +import * as vscode from 'vscode' +import { QuestionsProvider, QuestionTree } from './provider/questionsProvider' +import { cache } from './cache' +import { checkParams, CheckResponse, ErrorStatus, Lang } from './model/common' +import { config } from './config' +import { selectLogin } from './login/input' +import { getQuestionDescription } from './webview/questionPreview' +import { databases, enableLang, getFileLang, isAlgorithm, isDataBase, isShell } from './common/langConfig' +import { normalizeQuestionLabel, writeFileAsync } from './common/util' +import { MemoFile } from './model/memo' +import { addFolder, addQuestion } from './memo/index' +import { MemoProvider, MemoTree } from './provider/memoProvider' +import { ResolverParam } from './provider/resolver' +import { Service } from './lang/common' +import { DataBaseParse } from './lang/database' +import { BashParse } from './lang/bash' +import { createSubmitHistoryPanel } from './webview/submitHistory' +import { submitStorage } from './history/storage' +import { answerStorage } from './history/answer' +import { + BuildCodeArguments, + GetDescriptionArguments, + SubmitCodeArguments, + TestCodeArguments, + ViewSubmitHistoryArguments, +} from './model/command' + +export async function testCodeCommand(...args: TestCodeArguments) { + const [ + { + filePath, + testCaseParam: { testCase }, + }, + ] = args + try { + const service = new Service(filePath) + const promise = service.execTest(testCase) + const msg = await execWithProgress(promise, 'wait test') + if (msg) { + log.appendLine(msg) + } + log.show() + } catch (err) { + console.log(err) + window.showInformationMessage(`parse params err: ${err}`) + } +} +async function openFolder() { + const items = [ + 'open questions folder in new window', + 'open questions folder in current window', + 'add questions folder at the start of workspace folders', + ] + + const uri = vscode.Uri.file(config.baseDir) + const pickItem = await window.showQuickPick(items) + if (pickItem === items[0]) { + const uri = vscode.Uri.file(config.baseDir) + return vscode.commands.executeCommand('vscode.openFolder', uri, { + forceNewWindow: true, + }) + } else if (pickItem === items[1]) { + return vscode.commands.executeCommand('vscode.openFolder', uri, { + forceNewWindow: false, + }) + } else if (pickItem === items[2]) { + return vscode.workspace.updateWorkspaceFolders(0, 0, { uri }) + } +} + +export async function buildCode(text: string, filePath: string): Promise { + if (isDataBase(filePath)) { + const parse = new DataBaseParse(filePath, text) + return parse.buildCode() + } else if (isShell(filePath)) { + const parse = new BashParse(filePath, text) + return parse.buildCode() + } + const service = new Service(filePath, text) + + return service.buildCode() +} + +// TODO +async function submitAsync(code: string, questionMeta: QuestionMeta): Promise { + checkParams(questionMeta, ['titleSlug', 'id']) + const { titleSlug, id } = questionMeta + const res = await api.submit({ + titleSlug: titleSlug, + question_id: id, + typed_code: code, + lang: questionMeta.lang, + }) + if (!res.submission_id) { + log.appendLine(JSON.stringify(res)) + log.show() + return Promise.reject(new Error('submit error')) + } + const fn = async () => { + const res2 = await api.check({ + submission_id: res.submission_id, + titleSlug: titleSlug, + }) + if (['PENDING', 'STARTED', 'SUCCESS'].includes(res2.state)) { + return res2 + } else { + console.log('check res', res2) + log.appendLine(JSON.stringify(res2)) + return Promise.reject(new Error('submit error')) + } + } + const verifyFn = (res: CheckResponse) => res.state === 'SUCCESS' + const result = await retry({ fn, verifyFn, time: 6 }) + return result +} +async function submitCode(text: string, filePath: string) { + const buildResult = await buildCode(text, filePath) + + const code = buildResult.code + const questionMeta = buildResult.questionMeta + const result = await submitAsync(code, questionMeta) + return { + result, + code, + questionMeta, + } +} +export async function debugCodeCommand(filePath: string) { + const uri = vscode.Uri.file(config.baseDir) + const p = vscode.workspace.getWorkspaceFolder(uri) + const workspaceFolders = vscode.workspace.workspaceFolders + if (!workspaceFolders?.find((w) => w.uri === p?.uri)) { + return openFolder() + } + const breaks = vscode.debug.breakpoints as vscode.SourceBreakpoint[] + if (!breaks.find((b) => b?.location?.uri.fsPath === filePath)) { + console.log('breakpoint not found') + window.showErrorMessage('please set breakpoint') + return + } + if (!checkBeforeDebug(filePath)) { + return + } + const service = new Service(filePath) + service.debugCodeCommand(p!, breaks) +} +export async function buildCodeCommand(...args: BuildCodeArguments) { + const [context, { text, filePath, langSlug }] = args + const { code } = await buildCode(text, filePath) + createPanel(context, code, langSlug) +} +// export async function buildCodeCommand(context: ExtensionContext, text: string, filePath: string, langSlug: string) { +// const { code } = await buildCode(text, filePath) +// createPanel(context, code, langSlug) +// } +export async function submitCommand(...args: SubmitCodeArguments) { + const [questionsProvider, { text, filePath }] = args + let message = '' + try { + const { result, questionMeta } = await execWithProgress(submitCode(text, filePath), 'wait submit') + + message = result.status_msg + submitStorage.saveSubmit({ + filePath: filePath, + text, + result, + desc: questionMeta.desc, + }) + if (message === 'Accepted') { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + cache.updateQuestion(parseInt(questionMeta.id!), { status: 'ac' }) + questionsProvider.refresh() + } else { + if (result.status_code === 11) { + //'Wrong Answer' + const inputLength = result?.input_formatted?.length || 0 + const maxLength = 300 + if (inputLength <= maxLength) { + const msg = `× @test(${result.input_formatted}) result: ${result.code_output} ,expect: ${result.expected_output}\n` + log.appendLine(msg) + log.show() + const codeLang = getFileLang(filePath) + + if (questionMeta.id && isAlgorithm(codeLang)) { + const questionDetail = await api.fetchQuestionDetailById(questionMeta.id) + try { + if (questionDetail) { + const metaData = JSON.parse(questionDetail.metaData) + const funcName = metaData.name + const comment = ` @test(${result.input_formatted})=${result.expected_output}` + const s = new Service(filePath) + const newCode = s.addComment(text, comment, funcName) + await writeFileAsync(filePath, newCode) + } + } catch (err) { + console.log('parse questionDetail error', questionDetail) + } + } + } + } + } + console.log(result) + window.showInformationMessage(message) + } catch (err) { + if ([ErrorStatus.InvalidCookie, ErrorStatus.Unlogin].includes(err?.response?.status)) { + return + } + console.log(err) + message = err.message + } + + window.showInformationMessage(message) +} + +interface BuildCode { + code: string + questionMeta: QuestionMeta +} + +export async function getDescriptionCommand(...args: GetDescriptionArguments) { + const [extensionPath, { text, filePath }] = args + //extensionPath: string, text: string, filePath: string + const { questionMeta } = getFuncNames(text, filePath) + getQuestionDescription(extensionPath, { + questionId: questionMeta.id, + titleSlug: questionMeta.titleSlug, + weekname: questionMeta.weekname, + }) +} + +export async function refreshCommand(questionsProvider: QuestionsProvider) { + const promise = refreshQuestions() + await execWithProgress2(promise, 'refresh questions') + questionsProvider.refresh() +} + +export async function signInCommand(questionsProvider: QuestionsProvider) { + try { + await selectLogin(questionsProvider) + } catch (err) { + if (err.code !== 2) { + window.showInformationMessage(err.message) + } + } +} + +class LangItem implements vscode.QuickPickItem { + constructor(public label: string, public description: string, public detail: string) { } +} +export async function switchEndpointCommand() { + const LangConfigs = [ + { + lang: Lang.en, + label: 'Leetcode', + description: 'leetcode.com', + detail: 'Enable Leetcode US', + }, + { + lang: Lang.cn, + label: '力扣', + description: 'leetcode.cn', + detail: '启用中国版Leetcode', + }, + ] + const items = LangConfigs.map((langConfig) => { + if (langConfig.lang === config.lang) { + return new LangItem('$(check)' + langConfig.label, langConfig.description, langConfig.detail) + } + return new LangItem(langConfig.label, langConfig.description, langConfig.detail) + }) + const [itemEN, itemCN] = items + const result = await window.showQuickPick(items) + if (result === itemEN) { + updateConfig('lang', Lang.en) + } else if (result === itemCN) { + updateConfig('lang', Lang.cn) + } +} + +class CodeLangItem implements vscode.QuickPickItem { + constructor(public label: string, public description: string) { } +} +export async function switchCodeLangCommand() { + // const langs: CodeLang[] = [CodeLang.JavaScript, CodeLang.TypeScript, CodeLang.Python3, CodeLang.Go] + const curLang = config.codeLang + const langLabels = enableLang.map((lang) => { + if (lang === curLang) { + return new CodeLangItem(lang, '$(check)') + } + return new CodeLangItem(lang, '') + }) + const pickItem = await window.showQuickPick(langLabels) + const pickIndex = langLabels.findIndex((v) => v === pickItem) + if (pickIndex !== -1) { + const pickLang = enableLang[pickIndex] + updateConfig('codeLang', pickLang) + } +} + +export async function switchDataBaseCommand() { + const curDataBase = config.database + const langLabels = databases.map((lang) => { + if (lang === curDataBase) { + return new CodeLangItem(lang, '$(check)') + } + return new CodeLangItem(lang, '') + }) + const pickItem = await window.showQuickPick(langLabels) + const pickIndex = langLabels.findIndex((v) => v === pickItem) + if (pickIndex !== -1) { + const pickLang = databases[pickIndex] + updateConfig('database', pickLang) + } +} + +export async function searchCommand() { + const questions = await api.getAllQuestions() + const items = questions.map((v) => normalizeQuestionLabel(v)) + const pickItem = await window.showQuickPick(items) + const index = items.findIndex((item) => item === pickItem) + if (index !== -1) { + const question = questions[index] + const param = { + id: question.id, + titleSlug: question.slug, + } + vscode.commands.executeCommand('algorithm.questionPreview', param) + } +} +export async function addFolderCommand(memoProvider: MemoProvider) { + const folderName = await window.showInputBox() + if (folderName) { + try { + addFolder(folderName) + memoProvider.refresh() + } catch (err) { + log.appendLine(err) + log.show() + } + } +} + +export async function memoFilePreviewCommand(memoFile: MemoFile) { + if (memoFile.type === 'question') { + vscode.commands.executeCommand('algorithm.questionPreview', memoFile.param) + } +} + +export async function addMemoFileCommand(memoProvider: MemoProvider, questionTree: QuestionTree) { + const folderNames = config.env.memo.map((v) => v.name) + const folderName = await window.showQuickPick(folderNames) + if (folderName) { + try { + addQuestion(folderName, questionTree.label, questionTree.param as Partial) + memoProvider.refresh() + } catch (err) { + log.appendLine(err) + log.show() + } + } +} + +export async function removeMemoFileCommand(memoProvider: MemoProvider, param: MemoTree) { + const isRemove = await MemoProvider.remove(param) + if (isRemove) { + memoProvider.refresh() + } +} + +export async function viewSubmitHistoryCommand(...args: ViewSubmitHistoryArguments) { + const [context, { text, filePath }] = args + + const { questionMeta } = getFuncNames(text, filePath) + if (!questionMeta.id) { + return + } + createSubmitHistoryPanel(context, questionMeta.id) +} + +export async function newAnswerCommand(uri: vscode.Uri) { + const filePath = uri.fsPath + answerStorage.newAnswer(filePath) +} diff --git a/src/common/lang.ts b/src/common/lang.ts new file mode 100644 index 0000000000000000000000000000000000000000..d6c9427d349ff0d2ef607cf3be1d75000b1f0c44 --- /dev/null +++ b/src/common/lang.ts @@ -0,0 +1,33 @@ +import { CaseList } from './util' + +export type MetaData = LanguageMetaData | DataBaseMetaData | ShellMetaData +interface Param { + name: string + type: string +} +interface ReturnType { + type: string +} +export interface LanguageMetaData { + name: string + params: Param[] + return: ReturnType +} +export interface DataBaseMetaData { + database: true + mssql: string[] + mysql: string[] + oraclesql: string[] +} +export interface ShellMetaData { + shell: true +} + +export interface TestOptions { + caseList: CaseList + metaData: LanguageMetaData + filePath: string + originCode: string +} +export type DebugOptions = Omit +export const defaultTimeout = 10000 diff --git a/src/common/langConfig.ts b/src/common/langConfig.ts new file mode 100644 index 0000000000000000000000000000000000000000..e920017f3e76c9c99a173b08c2001c2b5f1b378d --- /dev/null +++ b/src/common/langConfig.ts @@ -0,0 +1,265 @@ +import * as path from 'path' + +const langsConfig = { + algorithms: [ + { + lang: 'C++', + langSlug: 'cpp', + ext: '.cpp', + comment: '//', + fileNameSep: '.', + }, + { + lang: 'Java', + langSlug: 'java', + ext: '.java', + comment: '//', + fileNameSep: '.', + }, + { + lang: 'Python', + langSlug: 'python', + ext: '.py', + comment: '#', + fileNameSep: '_', + }, + { + lang: 'Python3', + langSlug: 'python3', + ext: '.py', + comment: '#', + fileNameSep: '_', + }, + { + lang: 'C', + langSlug: 'c', + ext: '.c', + comment: '//', + fileNameSep: '.', + }, + { + lang: 'C#', + langSlug: 'csharp', + ext: '.cs', + comment: '//', + fileNameSep: '.', + }, + { + lang: 'JavaScript', + langSlug: 'javascript', + ext: '.js', + comment: '//', + fileNameSep: '.', + }, + { + lang: 'Ruby', + langSlug: 'ruby', + ext: '.rb', + comment: '#', + fileNameSep: '.', + }, + { + lang: 'Swift', + langSlug: 'swift', + ext: '.swift', + comment: '//', + fileNameSep: '.', + }, + { + lang: 'Go', + langSlug: 'golang', + ext: '.go', + comment: '//', + fileNameSep: '.', + }, + { + lang: 'Scala', + langSlug: 'scala', + ext: '.scala', + comment: '//', + fileNameSep: '.', + }, + { + lang: 'Kotlin', + langSlug: 'kotlin', + ext: '.kt', + comment: '//', + fileNameSep: '.', + }, + { + lang: 'Rust', + langSlug: 'rust', + ext: '.rs', + comment: '//', + fileNameSep: '.', + }, + { + lang: 'PHP', + langSlug: 'php', + ext: '.php', + comment: '//', + fileNameSep: '.', + }, + { + lang: 'TypeScript', + langSlug: 'typescript', + ext: '.ts', + comment: '//', + fileNameSep: '.', + }, + ], + database: [ + { + lang: 'MySQL', + langSlug: 'mysql', + ext: '.sql', + comment: '#', + fileNameSep: '.', + }, + { + lang: 'MS SQL Server', + langSlug: 'mssql', + ext: '.sql', + comment: '#', + fileNameSep: '.', + }, + { + lang: 'Oracle', + langSlug: 'oraclesql', + ext: '.sql', + comment: '#', + fileNameSep: '.', + }, + ], + shell: [ + { + lang: 'Bash', + langSlug: 'bash', + ext: '.sh', + comment: '#', + fileNameSep: '.', + }, + ], +} +enum LangBaseComment { + Slash = '//', + Pound = '#', +} +export interface LangBase { + lang: CodeLang + langSlug: string + ext: string + comment: LangBaseComment + fileNameSep: '.' | '_' +} +export interface LangMap { + [langSlug: string]: LangBase +} +interface LangExtMap { + [ext: string]: LangBase +} +const allLangs = Object.values(langsConfig).reduce((prev, cur) => prev.concat(cur)) +export const langMap: LangMap = allLangs.reduce((prev, cur) => (prev[cur.langSlug] = cur) && prev, {}) +export const langExtMap: LangExtMap = allLangs.reduce((prev, cur) => (prev[cur.ext] = cur) && prev, {}) +export enum CodeLang { + 'C++' = 'C++', + 'C#' = 'C#', + Java = 'Java', + Python = 'Python', + Python3 = 'Python3', + C = 'C', + JavaScript = 'JavaScript', + Ruby = 'Ruby', + Swift = 'Swift', + Go = 'Go', + Scala = 'Scala', + Kotlin = 'Kotlin', + Rust = 'Rust', + PHP = 'PHP', + TypeScript = 'TypeScript', +} +export enum DataBase { + MySQL = 'MySQL', + 'MS SQL Server' = 'MS SQL Server', + 'Oracle' = 'Oracle', +} + +export function getFileLang(filePath: string): CodeLang { + const ext = path.extname(filePath) + const langItem = langExtMap[ext] + if (!langItem) { + throw new Error('file extname invalid') + } + return langItem.lang +} + +export function getFileLangSlug(filePath: string): string { + const ext = path.extname(filePath) + const langItem = langExtMap[ext] + if (!langItem) { + throw new Error('file extname invalid') + } + return langItem.langSlug +} +export function isDataBase(filePath: string): boolean { + const ext = path.extname(filePath) + return ext === '.sql' +} +export function isShell(filePath: string): boolean { + const ext = path.extname(filePath) + return ext === '.sh' +} +export function isAlgorithm(lang: CodeLang): boolean { + return !!langsConfig.algorithms.find((alg) => alg.lang === lang) +} +export function getFileComment(filePath: string): LangBaseComment { + const ext = path.extname(filePath) + const langItem = langExtMap[ext] + if (!langItem) { + throw new Error('file extname invalid') + } + return langItem.comment +} + +export const builtInLang = [CodeLang.JavaScript, CodeLang.TypeScript] +export const otherLang = [CodeLang.Python3, CodeLang.Go, CodeLang.Java, CodeLang['C++']] +export const enableLang = [...builtInLang, ...otherLang] +export const databases = [DataBase['MS SQL Server'], DataBase.MySQL, DataBase.Oracle] +export const enNameLangs = [CodeLang.Java, CodeLang['C++']] +export enum ExtraType { + ListNode = 'ListNode', + TreeNode = 'TreeNode', +} +export const highlightLangMap = { + cpp: 'cpp', + java: 'java', + python: 'python', + python3: 'python', + c: 'c', + csharp: 'csharp', + javascript: 'javascript', + ruby: 'ruby', + swift: 'swift', + golang: 'go', + scala: 'scala', + kotlin: 'kotlin', + rust: 'rust', + php: 'php', + typescript: 'typescript', +} +export function transformToHightlightLang(lang: string): string { + return highlightLangMap[lang] || lang +} +export function isSupportFile(filePath: string) { + if (isShell(filePath) || isDataBase(filePath)) { + return true + } + const ext = path.extname(filePath) + + const langItem = langExtMap[ext] + if (!langItem) { + return false + } + const lang = langItem.lang + return enableLang.includes(lang) +} diff --git a/src/common/parseContent.ts b/src/common/parseContent.ts new file mode 100644 index 0000000000000000000000000000000000000000..55496378ef67c8337801cadd37e2b5682abfec76 --- /dev/null +++ b/src/common/parseContent.ts @@ -0,0 +1,275 @@ +import { parse } from 'pretty-object-string' +import { escape2html } from './util' +const isSpace = (c) => /\s/.test(c) +const isWord = (c) => /\w/.test(c) +function delComment(src) { + const commentRegExp = /(\/\*([\s\S]*?)\*\/|('.*?')|(".*?")|\/\/(.*)$)/gm + return src.replace(commentRegExp, commentReplace) +} +function commentReplace(_match, _multi, _multiText, singlePrefix, double) { + return singlePrefix || double || '' +} +interface Demo { + input: Input[] + output: string +} +enum Kind { + scanContinue, + scanBeginTag, + scanTagText, + scanEndTag, + scanWord, + scanSpace, + scanInputFlag, + Identify, + scanEqual, + scanParam, + scanResult, +} +interface Input { + key?: string + value?: string +} +//TODO refactor +export class ParseContent { + public step: (char: string, next: string, i: number) => Kind = this.stateBegin + public prevStep: (char: string, next?: string) => Kind = this.stateBegin + public word = '' + public words: string[] = [] + public tagStatus = 0 + public exampleState = 0 + public demos: Demo[] = [] + constructor(public readonly content: string) { + this.content = delComment(escape2html(content.replace(/<[^>]*>/g, ''))) + this.init() + } + init() { + this.step = this.stateBegin + let input: Input[] = [] + const linkReg = /^\s*-?\d+->/ + const demos: Demo[] = [] + let identify + let i = 0 + try { + for (; i < this.content.length; i++) { + const c = this.content[i] + const n = this.content[i + 1] + + const out = this.step(c, n, i) + if (out === Kind.Identify) { + identify = this.word + this.word = '' + } else if (out === Kind.scanParam) { + let value = this.content.slice(i, i + 10) + let index, output + if (linkReg.test(value)) { + const result = this.parseLink(i) + index = result.index + output = result.output + } else { + value = this.content.slice(i) + const result = parse(value, { + partialIndex: true, + compress: true, + }) + index = result.index + output = result.output + } + input.push({ + key: identify, + value: output, + }) + + i = i + index - 1 + this.step = this.stateInputIdentity2 + } else if (out === Kind.scanResult) { + let value = this.content.slice(i, i + 10) + let index, output + if (linkReg.test(value)) { + const result = this.parseLink(i) + index = result.index + output = result.output + } else { + value = this.content.slice(i) + const result = parse(value, { + partialIndex: true, + compress: true, + }) + index = result.index + output = result.output + } + i = i + index - 1 + demos.push({ + input, + output: output, + }) + input = [] + this.word = '' + identify = '' + this.step = this.stateWord + } + } + } catch (err) { + console.log('content', this.content) + console.log(this.content.slice(i - 20, i)) + console.log(err) + } + this.demos = demos + } + static getTestCases(content: string) { + const p = new ParseContent(content) + return p.demos + } + parseLink(index) { + let numStr = '' + const output: number[] = [] + const start = index + + while (index < this.content.length && isSpace(this.content[index])) { + index++ + } + while (index < this.content.length && /[\d->N]/.test(this.content[index])) { + const char = this.content[index] + if (/\d/.test(char)) { + numStr += char + } else if (char === '-') { + const nextChar = this.content[index + 1] + if (nextChar === '>') { + output.push(parseInt(numStr)) + numStr = '' + } else if (/\d/.test(nextChar)) { + numStr = char + } + } else if (char === 'N') { + if (this.content.slice(index, index + 4) !== 'NULL') { + throw new Error('parse link error') + } + return { + index: index + 4 - start, + output: JSON.stringify(output), + } + } + index++ + } + output.push(parseInt(numStr)) + return { + index: index - start, + output: JSON.stringify(output), + } + } + lineEndAt(position) { + let i = position + while (this.content[i++]) { + if (this.content[i] === '\n') { + return i + } + } + return i + } + stateBegin(char: string): Kind { + if (isSpace(char)) { + return Kind.scanContinue + } + + this.step = this.stateWord + return this.stateWord(char) + } + stateWord(char: string): Kind { + if (isSpace(char)) { + this.word = '' + return Kind.scanSpace + } + this.word += char + if (this.exampleState === 1 && this.word === 'Input:') { + this.word = '' + this.exampleState = 0 + this.step = this.stateInputIdentityOrValue + } else if (this.word === 'Example') { + this.exampleState = 1 + } + return Kind.scanWord + } + stateInputIdentityOrValue(char: string, n: string, i: number): Kind { + if (isSpace(char)) { + return Kind.scanSpace + } + if (!/[a-zA-Z_]/.test(char) || /(true|false|null)/.test(this.content.slice(i, i + 6))) { + return Kind.scanParam + } + if (this.content.slice(i, i + 7) === 'Output:') { + //Compatibility Special Conditions id:53 + /** + * content Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum. + + Example: + + + Input: [-2,1,-3,4,-1,2,1,-5,4], + Output: 6 + Explanation: [4,-1,2,1] has the largest sum = 6. + + */ + this.step = this.stateOut + return this.step(char, n, i) + } + this.step = this.stateInputIdentity + return this.step(char, n, i) + } + stateInputIdentity(char: string, _n: string, _i: number): Kind { + if (isSpace(char)) { + if (!this.word) { + return Kind.scanSpace + } + this.step = this.stateEqual + return Kind.Identify + } + if (!isWord(char)) { + throw new Error('input identity invalid') + } + this.word += char + return Kind.scanWord + } + stateEqual(char: string): Kind { + if (isSpace(char)) { + return Kind.scanSpace + } + if (char === '=') { + this.step = this.stateParam + return Kind.scanEqual + } + throw new Error('parse equal error') + } + stateParam(char: string): Kind { + if (isSpace(char)) { + return Kind.scanSpace + } + return Kind.scanParam + } + stateInputIdentity2(char: string, n: string, i: number): Kind { + if (isSpace(char)) { + return Kind.scanSpace + } + if (char === ',') { + this.step = this.stateInputIdentityOrValue + return Kind.scanContinue + } + this.step = this.stateOut + return this.step(char, n, i) + } + stateOut(char: string): Kind { + if (isSpace(char)) { + return Kind.scanSpace + } + this.word += char + if (this.word === 'Output:') { + this.word = '' + this.step = this.stateResult + return Kind.scanContinue + } + return Kind.scanContinue + } + stateResult(char: string): Kind { + this.word += char + return Kind.scanResult + } +} diff --git a/src/common/transformCode.ts b/src/common/transformCode.ts new file mode 100644 index 0000000000000000000000000000000000000000..8539b557c0aadeffe57b94c50148ab54d357d39c --- /dev/null +++ b/src/common/transformCode.ts @@ -0,0 +1,49 @@ +import * as recast from 'recast' +import * as acorn from 'acorn' +import { builders, namedTypes } from 'ast-types' +import { FunctionDeclarationKind, VariableDeclarationKind } from 'ast-types/gen/kinds' + +function addAstComment(ast: namedTypes.File, comment: string, funName: string) { + const visitor = { + FunctionDeclaration: (node: FunctionDeclarationKind) => { + if (node.id && node.id.name === funName) { + insertLineComment(node, comment) + } + }, + VariableDeclaration: (node: VariableDeclarationKind) => { + if ( + node.declarations.find((declaration) => { + return ( + declaration.type === 'VariableDeclarator' && + declaration.id.type === 'Identifier' && + declaration.id.name === funName + ) + }) + ) { + insertLineComment(node, comment) + } + }, + } + const body = ast.program.body + for (const node of body) { + const fn = visitor[node.type] + if (fn) { + fn(node) + } + } +} +function insertLineComment(node: VariableDeclarationKind | FunctionDeclarationKind, comment: string) { + const commentNode = builders.commentLine(comment, true) + const originComments = node.comments || [] + const mergeComments = [commentNode, ...originComments] + + node.comments = mergeComments +} +export function addComment(source: string, comment: string, funName: string) { + const ast: namedTypes.File = recast.parse(source, { + parser: acorn, + }) + addAstComment(ast, comment, funName) + const output = recast.print(ast).code + return output +} diff --git a/src/common/util.ts b/src/common/util.ts new file mode 100644 index 0000000000000000000000000000000000000000..bc47984d4feef9cba32905083edc54cea132bf60 --- /dev/null +++ b/src/common/util.ts @@ -0,0 +1,755 @@ +import { parse } from 'pretty-object-string' +import fs = require('fs') +import fse = require('fs-extra') +import { promisify } from 'util' +import vm = require('vm') +import { SubmissionDetailPageData } from '../model/question' +import { CnContestPageData, CodeDefinition, CommonQuestion, ConciseQuestion } from '../model/common' +import * as path from 'path' +import axios from 'axios' +import * as compressing from 'compressing' +import { getFileComment } from './langConfig' +import * as cp from 'child_process' +import { tag } from 'pretty-tag' +import { LanguageMetaData } from './lang' + +import rimraf = require('rimraf') +import cheerio = require('cheerio') +const access = promisify(fs.access) +const mkdir = promisify(fs.mkdir) +const writeFileAsync = promisify(fs.writeFile) +const readFileAsync = promisify(fs.readFile) +const execFileAsync = promisify(cp.execFile) +const isSpace = (s: string) => /\s/.test(s) +const testRegExp = /\/\/\s*@test\(((?:"(?:\\.|[^"])*"|[^)])*)\)/ +const funcRegExp = /^(?:(\s*function)|(.*=\s*function))/ +const paramMetaRegExp = /@param {([^}]+)}/ +const returnRegExp = /@return {([^}]+)}/ +export const funcNameRegExp = /^(?:\s*function\s*([\w]+)\s*|\s*(?:(?:var|let|const)\s+([\w]+)\s*=\s*)?function)/ +export const tsFunctionRegExp = /function\s+(\w+)\((.*)\)\s*(?::(.+))?{/ +export const isTreeNode = (str: string) => /^TreeNode\s*(\|\s*null)?$/.test(str) +export const isListNode = (str: string) => /^ListNode\s*(\|\s*null)?$/.test(str) +export type TestCase = string[] +export interface TestCaseParam { + line: number + testCase: TestCase + funcName: string + paramsTypes: string[] + resultType: string +} +export interface Args { + args: string[] + result: string +} +export type CaseList = Args[] +export function isVersionGte(v1: string, v2: string) { + const arr1 = v1.split('.') + const arr2 = v2.split('.') + for (let i = 0; i < arr1.length; i++) { + if (arr1[i] > arr2[i]) { + return true + } else if (arr1[i] < arr2[i]) { + return false + } + } + return true +} +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export async function writeFile(filepath: string, data: any) { + const dir = path.dirname(filepath) + await fs.promises.mkdir(dir, { recursive: true }) + return writeFileAsync(filepath, data) +} +export function mkdirSync(dir: string) { + fs.mkdirSync(dir, { recursive: true }) +} +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function writeFileSync(filepath: string, data: any, options: fs.WriteFileOptions) { + fs.mkdirSync(path.dirname(filepath), { recursive: true }) + fs.writeFileSync(filepath, data, options) +} +export function normalizeQuestionLabel(question: ConciseQuestion) { + return question.fid + '. ' + question.name +} +export function normalizeQuestions(questions: ConciseQuestion[], type: string) { + return questions.map((question) => { + const isAC = question.status === 'ac' + return { + type: 'Question', + label: normalizeQuestionLabel(question), + id: type + question.id, + isLast: true, + isAC, + param: { + titleSlug: question.slug, + questionId: question.id, + }, + } + }) +} + +function detectEnableExt(text: string, filePath: string): boolean { + const commentToken = getFileComment(filePath) + const algorithmToken = `${commentToken} @algorithm` + let point = 0 + while (isSpace(text[point])) { + point++ + } + for (let i = 0; i < algorithmToken.length; i++) { + if (text[point++] !== algorithmToken[i]) { + return false + } + } + return true +} +function getJsTestCaseList(text: string): Array { + const testCaseList: TestCaseParam[] = [] + const lines = text.split(/\n/) + let isTest = false + let testCase: TestCase = [] + let paramsTypes: string[] = [] + let resultType = '' + for (let i = 0; i < lines.length; i++) { + if (testRegExp.test(lines[i])) { + isTest = true + testCase.push(lines[i]) + } else if (funcRegExp.test(lines[i])) { + if (isTest) { + const match = lines[i].match(funcNameRegExp) + if (match) { + const funcName = match[1] || match[2] + + testCaseList.push({ + line: i, + testCase, + funcName, + paramsTypes: [...paramsTypes], + resultType: resultType, + }) + paramsTypes = [] + resultType = '' + } + + isTest = false + testCase = [] + } + } else if (paramMetaRegExp.test(lines[i])) { + const match = lines[i].match(paramMetaRegExp) + if (match) { + paramsTypes.push(match[1]) + } + } else if (returnRegExp.test(lines[i])) { + const match = lines[i].match(returnRegExp) + if (match) { + resultType = match[1] + } + } + } + return testCaseList +} +function trimParams(param: string) { + return param + .split(',') + .map((v) => v.split(':')[1]) + .map((str) => str && str.trim()) +} +function trimResultType(resultType: string | undefined) { + return resultType && resultType.trim() +} +export function parseTsFunctionType(line: string) { + const match = line.match(tsFunctionRegExp) + if (match) { + return { + funcName: match[1], + paramsTypes: trimParams(match[2]), + resultType: trimResultType(match[3]) || '', + } + } + return null +} +function getTsTestCaseList(text: string) { + const testCaseList: TestCaseParam[] = [] + let testCase: TestCase = [] + let isTest = false + const lines = text.split(/\n/) + for (let i = 0; i < lines.length; i++) { + if (testRegExp.test(lines[i])) { + isTest = true + testCase.push(lines[i]) + } else { + if (isTest) { + const tsFunctionType = parseTsFunctionType(lines[i]) + if (tsFunctionType) { + const { funcName, paramsTypes, resultType } = tsFunctionType + testCaseList.push({ + line: i, + testCase, + funcName, + paramsTypes: [...paramsTypes], + resultType: resultType, + }) + isTest = false + testCase = [] + } + } + } + } + return testCaseList +} +export interface QuestionMeta { + id?: string + lang?: string + titleSlug?: string + weekname?: string + desc?: string +} +interface FunNamesMeta { + funcNames: string[] + questionMeta: QuestionMeta +} +function parseCode(text: string, filePath: string): FunNamesMeta { + const lines = text.split(/\n/) + const funcNames: string[] = [] + const comment = getFileComment(filePath) + const lcToken = + comment === '//' + ? /^\/\/ @algorithm @lc id=(\d+) lang=([\w+#]+)(?:\sweekname=([\w-]+))?/ + : /^# @algorithm @lc id=(\d+) lang=([\w+#]+)(?:\sweekname=([\w-]+))?/ + const titleSlugToken = comment === '//' ? /^\/\/ @title ([\w-]+)/ : /^# @title ([\w-]+)/ + const descToken = comment === '//' ? /^\/\/ @desc (.+)/ : /^# @desc (.+)/ + const questionMeta: QuestionMeta = {} + for (let i = 0; i < lines.length; i++) { + if (lcToken.test(lines[i])) { + const match = lines[i].match(lcToken) as RegExpMatchArray + const id = match[1] + const lang = match[2] + const weekname = match[3] + questionMeta.id = id + questionMeta.lang = lang + questionMeta.weekname = weekname + } else if (titleSlugToken.test(lines[i])) { + const match = lines[i].match(titleSlugToken) as RegExpMatchArray + questionMeta.titleSlug = match[1] + } else if (descToken.test(lines[i])) { + const match = lines[i].match(descToken) as RegExpMatchArray + questionMeta.desc = match[1] + } else { + const match = lines[i].match(funcNameRegExp) + if (match) { + const funcName = match[1] || match[2] + funcNames.push(funcName) + } + } + } + return { + funcNames, + questionMeta, + } +} + +export function getDesc(text: string, filePath: string) { + const lines = text.split(/\n/) + const comment = getFileComment(filePath) + const descToken = comment === '//' ? /^\/\/ @desc (.+)/ : /^# @desc (.+)/ + + for (let i = 0; i < lines.length; i++) { + if (descToken.test(lines[i])) { + const match = lines[i].match(descToken) as RegExpMatchArray + return match[1] + } + } +} +export async function existDir(dir: string): Promise { + try { + await access(dir, fs.constants.F_OK | fs.constants.W_OK) + return true + } catch (err) { + if (err.code === 'ENOENT') { + await mkdir(dir) + return false + } + throw err + } +} +export function existDirSync(dir: string) { + try { + fs.accessSync(dir, fs.constants.F_OK | fs.constants.W_OK) + return true + } catch (err) { + if (err.code === 'ENOENT') { + fs.mkdirSync(dir) + return false + } + throw err + } +} +export async function existFile(filepath: string): Promise { + try { + await access(filepath, fs.constants.F_OK | fs.constants.W_OK) + return true + } catch (err) { + if (err.code === 'ENOENT') { + await writeFile(filepath, Buffer.alloc(0)) + return true + } + throw err + } +} + +export function parseHtml(html: string): CommonQuestion | null { + const $ = cheerio.load(html, { decodeEntities: false }) + + const translatedContent = $('.question-content.default-content').html()?.trim() || '' + const content = translatedContent || '' + const scripts = $('script').filter(function () { + const text = $(this).html() + return !!(text?.includes('pageData') && text.includes('questionId')) + }) + const questionFrontendId = parseInt($('.question-title h3').html() || '-1').toString() + let question: CommonQuestion | null = null + if (scripts.length === 1) { + const text = scripts.html() + const Script = vm.Script + const script = new Script(text + ';pageData') + + const result: CnContestPageData = script.runInNewContext() + if (result) { + question = { + ...result, + translatedContent, + questionFrontendId, + metaData: JSON.stringify(result.metaData), + title: result.questionSourceTitle, + translatedTitle: result.questionTitle, + content, + titleSlug: result.questionTitleSlug, + codeSnippets: result.codeDefinition.map((v: CodeDefinition) => ({ + code: v.defaultCode, + lang: v.text, + langSlug: v.value, + })), + } + } + } + return question +} +export function parseSubmissionDetailHtml(html: string): SubmissionDetailPageData | null { + const $ = cheerio.load(html, { decodeEntities: false }) + const scripts = $('script').filter(function () { + const text = $(this).html() + return !!(text?.includes('pageData') && text.includes('questionId')) + }) + let pageData: SubmissionDetailPageData | null = null + if (scripts.length === 1) { + const text = scripts.html() + const Script = vm.Script + const script = new Script(text + ';pageData') + pageData = script.runInNewContext() + } + return pageData +} +export function escape2html(str: string) { + const map = { lt: '<', gt: '>', nbsp: ' ', amp: '&', quot: '"', '#39': "'" } + return str.replace(/&(lt|gt|nbsp|amp|quot|#39);/g, (_, key) => map[key]) +} + +async function sleep(ms: number) { + return new Promise((resolve) => { + return setTimeout(resolve, ms) + }) +} +export async function retry({ + fn, + time = 1, + delay = 1000, + verifyFn, +}: { + fn: () => Promise + time?: number + delay?: number + verifyFn: (arg: T) => boolean +}): Promise { + let count = time | 0 + while (count > 0) { + count-- + await sleep(delay) + const result = await fn() + if (verifyFn(result)) { + return result + } + } + return Promise.reject(new Error('retry timeout')) +} + +function parseTestCase(testCase: TestCase): CaseList { + const caseList: CaseList = [] + for (const argsLiteral of testCase) { + caseList.push(parseCommentTest(argsLiteral)) + } + return caseList +} +export function parseCommentTest(testComment: string): Args { + let index = testComment.indexOf('@test') + 4 + const params: string[] = [] + let result = '' + while (testComment[++index]) { + if (testComment[index] === '(') { + index++ + break + } + } + let { index: pos } = parse(testComment.slice(index), { partialIndex: true }) + while (pos) { + pos = pos + index + const param = testComment.slice(index, pos) + // param = JSON.parse(param) + params.push(param.trim()) + if (testComment[pos] === ',') { + index = pos + 1 + pos = parse(testComment.slice(index), { partialIndex: true }).index + } else if (testComment[pos] === ')') { + index = pos + break + } else { + console.log(testComment.slice(pos - 10, pos)) + throw new Error('parse CommentTest error:' + testComment) + } + } + while (testComment[++index]) { + if (testComment[index] === '=') { + index++ + break + } + } + + pos = parse(testComment.slice(index), { partialIndex: true }).index + if (pos) { + result = testComment.slice(index, pos + index) + } + return { + args: params, + result, + } +} +export function normalize(result: any, returnType: string) { + if (['TreeNode', 'ListNode'].includes(returnType)) { + return result + } else { + return JSON.stringify(result) + } +} + +/** + * + * @param args the params of function + * @param paramsTypes the type of params + * @param includeFunctionCall whether the building step contains function call + */ +export function deserializeParam(args: string[], paramsTypes: string[], includeFunctionCall: boolean) { + let hasTree = false + let hasList = false + for (let i = 0; i < paramsTypes.length; i++) { + const paramType = paramsTypes[i] + if (isTreeNode(paramType)) { + hasTree = true + if (includeFunctionCall) { + args[i] = `a.treeNode.deserialize("${args[i]}")` + } else { + args[i] = `treeNode.deserialize("${args[i]}")` + } + } else if (/TreeNode/.test(paramType)) { + console.warn('deserialize param meeting problem,args:', args[i]) + } else if (isListNode(paramType)) { + hasList = true + if (includeFunctionCall) { + args[i] = `a.listNode.deserialize("${args[i]}")` + } else { + args[i] = `listNode.deserialize("${args[i]}")` + } + } else if (/ListNode/.test(paramType)) { + console.warn('deserialize param meeting problem,args:', args[i]) + } + } + return { + hasTree, + hasList, + } +} +export function getResultType(resultType: string): string { + if (isTreeNode(resultType)) { + return 'TreeNode' + } else if (isListNode(resultType)) { + return 'ListNode' + } else if (/TreeNode|ListNode/.test(resultType)) { + console.warn('deserialize result meeting problem,resultType:', resultType) + } + return '' +} +export interface TestResult { + args: string + expect: string + result: string +} +export function setLinePrefix(str: string, prefix: string) { + return str + .split('\n') + .map((line) => prefix + line) + .join('\n') +} +export async function downloadNpm(name: string, moduleDir: string) { + const url = 'https://registry.npmjs.org/' + name + + const randomName = Math.random().toString(32).slice(2) + const targetDir = path.join(moduleDir, name) + const tempDir = path.join(moduleDir, '.temp', randomName) + const res = await axios.request({ + url, + }) + const data = res.data + const latestVersion = data['dist-tags']['latest'] + const fileUrl = data['versions'][latestVersion]['dist']['tarball'] + + const res2 = await axios.get(fileUrl, { responseType: 'stream' }) + const stream = res2.data + + await compressing.tgz.uncompress(stream, tempDir) + await fse.copy(path.join(tempDir, 'package'), path.join(targetDir)) + + rimraf(tempDir, (err) => { + console.log(err) + }) +} +export function uniqueArrByKey, Key extends keyof Obj>(arr: Obj[], key: Key) { + if (arr.length <= 1) { + return + } + arr.sort((x, y) => x[key].localeCompare(y[key])) + let i = 0 + + for (let j = 1; j < arr.length; j++) { + if (arr[j][key] !== arr[j - 1][key]) { + arr[++i] = arr[j] + } + } + arr.length = i + 1 +} +export function unionArr(arr1: T[], arr2: T[]) { + const set = new Set(arr1) + arr2.forEach((v) => set.add(v)) + return [...set] +} +export function handleMsg(testResultList: TestResult[]) { + const success = testResultList.every((v) => (v.expect && v.expect.trim()) === (v.result && v.result.trim())) + let msg = '' + if (success) { + msg = `✓ ${testResultList.length} tests complete` + } else { + msg = + testResultList + .map((v) => { + if (v.expect === v.result) { + return `✓ @test(${v.args})\n` + } else { + return `× @test(${v.args}) result: ${v.result} ,expect: ${v.expect}\n` + } + }) + .join('') + '\n' + } + return msg +} + +function handleParam(index: number, paramType: string, esbuild = false): string { + const prefix = esbuild ? 'a.' : '' + const handleConfig = [ + { + type: 'ListNode', + handleFn: prefix + 'listNode.deserialize', + }, + { + type: 'TreeNode', + handleFn: prefix + 'treeNode.deserialize', + }, + { + type: 'ListNode[]', + handleFn: prefix + 'listNode.deserializeArr', + }, + { + type: 'TreeNode[]', + handleFn: prefix + 'treeNode.deserializeArr', + }, + ] + const jsonType = [ + 'integer', + 'string', + 'integer[]', + 'string[]', + 'integer[][]', + 'string[][]', + 'list', + 'list', + 'list>', + 'list>', + 'character[][]', + 'boolean', + 'double', + 'character', + 'character[]', + 'long', + 'long[]', + 'long[][]' + ] + if (jsonType.includes(paramType)) { + return `const arg${index} =JSON.parse(unitArgs[${index}])` + } else { + for (const { type, handleFn } of handleConfig) { + if (type === paramType) { + return `const arg${index} =${handleFn}(unitArgs[${index}])` + } + } + } + + throw new Error(`paramType ${paramType} not support`) +} + +function handleReturn( + paramCount: number, + funcName: string, + returnType: string, + firstParamType: string, + esbuild = false +): string { + const isVoid = returnType === 'void' + if (isVoid) { + returnType = firstParamType + } + const prefix = esbuild ? 'a.' : '' + const handleConfig = [ + { + type: 'ListNode', + handleFn: prefix + 'listNode.serialize', + }, + { + type: 'TreeNode', + handleFn: prefix + 'treeNode.serialize', + }, + { + type: 'ListNode[]', + handleFn: prefix + 'listNode.serializeArr', + }, + { + type: 'TreeNode[]', + handleFn: prefix + 'treeNode.serializeArr', + }, + { + type: 'double', + handleFn: `${isVoid ? ';' : ''}(v=>v.toFixed(5))`, + }, + ] + const jsonType = [ + 'integer', + 'string', + 'integer[]', + 'string[]', + 'integer[][]', + 'string[][]', + 'list', + 'list', + 'list>', + 'list>', + 'character[][]', + 'boolean', + 'character', + 'character[]', + 'long', + 'long[]', + 'long[][]' + ] + + const argStr = Array(paramCount) + .fill(0) + .map((v, i) => `arg${i}`) + .join(',') + if (jsonType.includes(returnType)) { + if (!isVoid) { + const funcExpression = tag` + const result=${funcName}(${argStr}) + JSON.stringify(result) + ` + return funcExpression + } else { + const funcExpression = tag` + ${funcName}(${argStr}) + JSON.stringify(arg0) + ` + return funcExpression + } + } else { + for (const { type, handleFn } of handleConfig) { + if (type === returnType) { + if (!isVoid) { + const funcExpression = tag` + const result=${funcName}(${argStr}) + resultabc =${handleFn}(result) + ` + return funcExpression + } else { + const funcExpression = tag` + ${funcName}(${argStr}) + ${handleFn}(arg0) + ` + return funcExpression + } + } + } + } + + throw new Error(`returnType ${returnType} not support`) +} +function handleArgsType(meta: LanguageMetaData, originCode: string, args: string[], isEsbuild = false) { + const params = meta.params || [] + const rt = meta.return.type + const funcName = meta.name + const argExpressions: string[] = [] + const paramCount = params.length + for (let i = 0; i < paramCount; i++) { + const { type } = params[i] + argExpressions[i] = handleParam(i, type, isEsbuild) + } + const argExpression = argExpressions.join('\n') + + const rtExpression = handleReturn(paramCount, funcName, rt, params[0].type, isEsbuild) + const formatArg = JSON.stringify(args) + return ( + originCode + + '\n' + + tag` + const unitArgs=${formatArg} + ${argExpression} + ${rtExpression} + ` + ) +} + +function generateId(): string { + return Math.random().toString(32).slice(2) +} + +function uniqueArr(arr: T[]): T[] { + const set = new Set(arr) + return [...set] +} +export { + detectEnableExt, + getJsTestCaseList as getTestCaseList, + getTsTestCaseList, + parseTestCase, + parseCode as getFuncNames, + writeFileAsync, + readFileAsync, + execFileAsync, + paramMetaRegExp, + returnRegExp, + handleArgsType, + generateId, + uniqueArr +} diff --git a/src/common/website.ts b/src/common/website.ts new file mode 100644 index 0000000000000000000000000000000000000000..a500c51d8cbe3fd3ac96dd283d8548d30ec58e24 --- /dev/null +++ b/src/common/website.ts @@ -0,0 +1,15 @@ +import { Lang } from '../model/common' +import { config, DomainCN, DomainEN } from '../config' +export enum Website { + Leetcode = 'https://leetcode.com', + LeetcodeCn = 'https://leetcode.cn', +} +export const WebsiteMap = { + [Lang.cn]: Website.LeetcodeCn, + [Lang.en]: Website.Leetcode, +} +function baseTag(strs: TemplateStringsArray, ...arr: string[]): string { + const baseUrl = WebsiteMap[config.lang] + return baseUrl + '/' + arr.reduce((prev, cur, i) => prev + cur + strs[i + 1], strs[0]) +} +export const getSolution = (titleSlug: string): string => baseTag`problems/${titleSlug}/solution/` diff --git a/src/config.ts b/src/config.ts new file mode 100644 index 0000000000000000000000000000000000000000..709255ad18080ee87b7656dd193aad584ae06c9b --- /dev/null +++ b/src/config.ts @@ -0,0 +1,405 @@ +import { existsSync, mkdirSync } from 'fs' +import os = require('os') +import path = require('path') +import { window, workspace, ConfigurationChangeEvent, OutputChannel } from 'vscode' +import { Lang, AskForImportState } from './model/common' +import { cache } from './cache' +import { QuestionsProvider } from './provider/questionsProvider' +import { CodeLang, DataBase } from './common/langConfig' +import * as cp from 'child_process' +import * as fs from 'fs' +import { promisify } from 'util' +import { downloadNpm, unionArr, uniqueArrByKey, isVersionGte } from './common/util' +import { MemoFolder } from './model/memo' +const execFileAsync = promisify(cp.execFile) +const customConfig = workspace.getConfiguration('algorithm') +const defaultCodeLang = CodeLang.JavaScript +const defaultNodeBinPath = 'node' +const defaultLang = Lang.en +const defaultBaseDir = path.join(os.homedir(), '.alg') +const defaultJavacPath = 'javac' +const defaultJavaPath = 'java' +const algmVersion = '0.1.9' +const ESBUILD = 'esbuild' +const defaultDisplayLock = false +const defaultDataBase = DataBase.MySQL +export const DomainCN = 'https://leetcode.cn' +export const DomainEN = 'https://leetcode.com' +export const log = window.createOutputChannel('algorithm') +export const InstallState = { + installEsbuild: false, + installAlgm: false, +} +interface BaseDir { + algDir: string + cacheDir: string + questionDir: string +} + +interface AlgorithmEnv { + hasInstallEsbuild: boolean + askForImportState: AskForImportState + memo: MemoFolder[] +} + +// the esbuild install in the extension dir and the extension dir change with the version change +interface EnvFile { + askForImportState: AskForImportState + installEsbuildArr: string[] + memo?: MemoFolder[] +} +export interface Config extends BaseDir { + baseDir: string + lang: Lang + cookiePath: string + log: OutputChannel + questionPath: string + tagPath: string + favoritsPath: string + dbDir: string + nodeBinPath: string + codeLang: CodeLang + database: DataBase + // algorithmPath: string + debugOptionsFilePath: string + autoImportStr: string + autoImportAlgm: boolean + cacheBaseDir: string + existAlgmModule: boolean + //the node_module dir + moduleDir: string + // the node_module/algm dir + algmModuleDir: string + env: AlgorithmEnv + hasAskForImport: boolean + javacPath: string + javaPath: string + questionsProvider?: QuestionsProvider + displayLock: boolean +} +type UpdateConfigKey = keyof Pick + +function ensureMemoUnique(folders: MemoFolder[]) { + if (folders.length <= 1) { + return + } + uniqueArrByKey(folders, 'name') + folders.forEach((folder) => uniqueArrByKey(folder.children, 'name')) +} +function getEnv(cacheBaseDir: string): AlgorithmEnv { + const envPath = path.join(cacheBaseDir, 'env.json') + const defaultEnv: AlgorithmEnv = { + hasInstallEsbuild: false, + askForImportState: AskForImportState.Later, + memo: [], + } + try { + // eslint-disable-next-line @typescript-eslint/no-var-requires + const env: EnvFile = require(envPath) + + const dir = __dirname + const installEsbuild = env.installEsbuildArr.find((v) => v === dir) + const askForImportState = env.askForImportState + const memo = env.memo || [] + ensureMemoUnique(memo) + const hasInstallEsbuild = !!installEsbuild + return { + ...defaultEnv, + hasInstallEsbuild, + askForImportState, + memo, + } + } catch (err) { + return defaultEnv + } +} +function initConfig(): Config { + const codeLang: CodeLang = customConfig.get('codeLang') || defaultCodeLang + const autoImportStr: string = customConfig.get('autoImportStr') || '' + const lang: Lang = customConfig.get('lang') || defaultLang + const baseDir: string = customConfig.get('baseDir') || defaultBaseDir + const algDir: string = path.join(baseDir, lang) + const cacheBaseDir: string = path.join(os.homedir(), '.algcache') + const cacheDir: string = path.join(os.homedir(), '.algcache', lang) + const questionDir = path.join(baseDir, lang, codeLang) + const database: DataBase = customConfig.get('database') || defaultDataBase + const cookiePath: string = path.join(cacheDir, 'cookie.json') + const questionPath: string = path.join(cacheDir, 'question.json') + const tagPath: string = path.join(cacheDir, 'tag.json') + const favoritsPath: string = path.join(cacheDir, 'favorites.json') + const dbDir: string = path.join(cacheDir, 'db') + const nodeBinPath: string = workspace.getConfiguration('algorithm').get('nodePath') || defaultNodeBinPath + const javacPath: string = customConfig.get('javacPath') || defaultJavacPath + const javaPath: string = customConfig.get('javaPath') || defaultJavaPath + // const algorithmPath = path.join(__dirname, '../node_modules/algm') + // const algorithmPath = path.join(cacheDir, 'node_modules/algm') + const debugOptionsFilePath = path.join(baseDir, '.vscode/debugParams.json') + const autoImportAlgm: boolean = customConfig.get('autoImportAlgm') || false + const displayLock: boolean = customConfig.get('displayLock') || false + const moduleDir: string = path.join(baseDir, 'node_modules') + const algmModuleDir: string = path.join(moduleDir, 'algm') + const existAlgmModule = fs.existsSync(algmModuleDir) + const env = getEnv(cacheBaseDir) + const hasAskForImport = false + return { + baseDir, + lang, + algDir, + cacheBaseDir, + cacheDir, + cookiePath, + log, + questionPath, + tagPath, + dbDir, + nodeBinPath, + // algorithmPath, + questionDir, + codeLang, + debugOptionsFilePath, + autoImportStr, + autoImportAlgm, + moduleDir, + algmModuleDir, + existAlgmModule, + env, + hasAskForImport, + javaPath, + javacPath, + database, + displayLock, + favoritsPath + } +} +export const config = initConfig() + +function initDir() { + const dirKeys: (keyof BaseDir)[] = ['cacheDir'] + dirKeys.forEach((key) => { + const dir = config[key] + if (!existsSync(dir)) { + mkdirSync(dir, { recursive: true }) + } + }) +} + +function checkNodePath() { + const { nodeBinPath } = config + cp.execFile(nodeBinPath, ['-v'], (err) => { + if (err) { + window.showInformationMessage('please set the node.js executable path') + } + }) +} + +function checkAlgmVersion() { + const targetDir = config.algmModuleDir + try { + // eslint-disable-next-line @typescript-eslint/no-var-requires + const a = require(path.join(targetDir, 'package.json')) + return isVersionGte(a.version, algmVersion) + } catch (err) { + return false + } +} +async function checkAlgm() { + if (config.autoImportAlgm) { + const moduleDir = config.moduleDir + const targetDir = config.algmModuleDir + const name = 'algm' + + if (existsSync(targetDir) && checkAlgmVersion()) { + return + } + if (!InstallState.installAlgm) { + InstallState.installAlgm = true + log.appendLine('installing algm...') + log.show() + try { + await downloadNpm(name, moduleDir) + log.appendLine('install algm success') + } catch (err) { + log.appendLine(err) + log.appendLine('install algm fail') + } + InstallState.installAlgm = false + } + } +} +function init() { + checkNodePath() + initDir() + checkAlgm() +} + +export function updateEnv(key: T, value: AlgorithmEnv[T]) { + config.env[key] = value + const envPath = path.join(config.cacheBaseDir, 'env.json') + const dir = __dirname + const hasInstallEsbuild = config.env.hasInstallEsbuild + const installEsbuildArr: string[] = [] + if (hasInstallEsbuild) { + installEsbuildArr.push(dir) + } + const envFile: EnvFile = { + askForImportState: config.env.askForImportState, + installEsbuildArr: installEsbuildArr, + memo: config.env.memo, + } + try { + const data = fs.readFileSync(envPath, { encoding: 'utf8' }) + const originEnvFile: EnvFile = JSON.parse(data) + envFile.askForImportState = originEnvFile.askForImportState || envFile.askForImportState + const originInstallEsbuildArr = originEnvFile.installEsbuildArr + if (Array.isArray(originInstallEsbuildArr)) { + envFile.installEsbuildArr = unionArr(installEsbuildArr, originInstallEsbuildArr) + } + } catch (err) { + log.appendLine(err) + } + fs.writeFileSync(envPath, JSON.stringify(envFile)) +} + +export function updateConfig(section: T, value: Config[T], isSync = false) { + if (config[section] !== value) { + workspace.getConfiguration('algorithm').update(section, value, true) + } + if (isSync) { + config[section] = value + } +} +function updateLang() { + const baseDir = config.baseDir + config.lang = workspace.getConfiguration('algorithm').get('lang') || defaultLang + config.algDir = path.join(baseDir, config.lang) + config.questionDir = path.join(baseDir, config.lang, config.codeLang) + config.cacheDir = path.join(os.homedir(), '.algcache', config.lang) + config.cookiePath = path.join(config.cacheDir, 'cookie.json') + config.questionPath = path.join(config.cacheDir, 'question.json') + config.tagPath = path.join(config.cacheDir, 'tag.json') + config.dbDir = path.join(config.cacheDir, 'db') +} +function updateCodeLang() { + const baseDir = config.baseDir + config.codeLang = workspace.getConfiguration('algorithm').get('codeLang') || defaultCodeLang + config.questionDir = path.join(baseDir, config.lang, config.codeLang) +} +function updateDataBaseLang() { + config.database = workspace.getConfiguration('algorithm').get('database') || defaultDataBase +} +function updateNodePath() { + config.nodeBinPath = workspace.getConfiguration('algorithm').get('nodePath') || defaultNodeBinPath +} +function updateJavacPath() { + config.javacPath = workspace.getConfiguration('algorithm').get('javacPath') || defaultJavacPath +} +function updateJavaPath() { + config.javaPath = workspace.getConfiguration('algorithm').get('javaPath') || defaultJavaPath +} +function updateAutoImportStr() { + config.autoImportStr = workspace.getConfiguration('algorithm').get('autoImportStr') || '' +} +function updateBaseDir() { + const baseDir: string = workspace.getConfiguration('algorithm').get('baseDir') || defaultBaseDir + config.baseDir = baseDir + config.algDir = path.join(baseDir, config.lang) + config.questionDir = path.join(baseDir, config.lang, config.codeLang) + config.debugOptionsFilePath = path.join(baseDir, '.vscode/debugParams.json') + config.moduleDir = path.join(baseDir, 'node_modules') + config.algmModuleDir = path.join(config.moduleDir, 'algm') + config.existAlgmModule = fs.existsSync(config.algmModuleDir) +} + +function updateDisplayLock() { + config.displayLock = workspace.getConfiguration('algorithm').get('displayLock') || defaultDisplayLock +} + +async function installEsbuild() { + const name = ESBUILD + const moduleDir = path.join(__dirname, '..', 'node_modules') + const targetDir = path.join(moduleDir, name) + log.appendLine('installing esbuild from npm...') + log.show() + InstallState.installEsbuild = true + try { + if (!fs.existsSync(targetDir)) { + await downloadNpm('esbuild', moduleDir) + } + + const installFile = path.join(targetDir, 'install.js') + if (fs.existsSync(installFile)) { + const nodeBinPath = config.nodeBinPath + const { stderr } = await execFileAsync(nodeBinPath, [installFile]) + if (stderr) { + log.appendLine(stderr) + // log.appendLine('install esbuild fail') + } else { + updateEnv('hasInstallEsbuild', true) + log.appendLine('install esbuild success') + } + } + } catch (err) { + log.appendLine(err) + log.appendLine('install esbuild fail') + } + InstallState.installEsbuild = false +} + +export function checkEsbuildDir() { + if (config.env.hasInstallEsbuild) { + return true + } + installEsbuild() + return false +} + +function updateAutoImportAlgm() { + config.autoImportAlgm = workspace.getConfiguration('algorithm').get('autoImportAlgm') || false + checkAlgm() +} + +export function onChangeConfig(questionsProvider: QuestionsProvider, e: ConfigurationChangeEvent) { + if (e.affectsConfiguration('algorithm.nodePath')) { + updateNodePath() + } + if (e.affectsConfiguration('algorithm.javacPath')) { + updateJavacPath() + } + if (e.affectsConfiguration('algorithm.javaPath')) { + updateJavaPath() + } + if (e.affectsConfiguration('algorithm.lang')) { + updateLang() + initDir() + cache.removeCache() + questionsProvider.refresh() + } + if (e.affectsConfiguration('algorithm.codeLang')) { + updateCodeLang() + initDir() + } + if (e.affectsConfiguration('algorithm.database')) { + updateDataBaseLang() + } + if (e.affectsConfiguration('algorithm.autoImportStr')) { + updateAutoImportStr() + } + if (e.affectsConfiguration('algorithm.baseDir')) { + updateBaseDir() + /** + * do not init baseDir, as user change the baseDir, + * and then do something activating the extension, + * finally change the baseDir again. + * All these baseDirs may be initialized even if no question file open. + * Check the dir when question file open instead. + */ + } + if (e.affectsConfiguration('algorithm.autoImportAlgm')) { + updateAutoImportAlgm() + } + + if (e.affectsConfiguration('algorithm.displayLock')) { + updateDisplayLock() + } +} +init() diff --git a/src/db.ts b/src/db.ts new file mode 100644 index 0000000000000000000000000000000000000000..943d57252a99d71645f7953d5f2a6e69665f5562 --- /dev/null +++ b/src/db.ts @@ -0,0 +1,22 @@ +import Db from './fileStorage/db' +import { config } from './config' +import { Lang } from './model/common' + +const filename = 'question' +const dbMap: Partial> = {} +export async function getDb(): Promise { + const lang = config.lang + const db = dbMap[lang] + if (db) { + return db + } else { + const dbDir = config.dbDir + const db = new Db({ + dbDir, + filename: filename, + }) + await db.init() + dbMap[lang] = db + return db + } +} diff --git a/src/debug/launch.ts b/src/debug/launch.ts new file mode 100644 index 0000000000000000000000000000000000000000..74ab765ff7943bfec1a3babaedc39f8a1f781cb4 --- /dev/null +++ b/src/debug/launch.ts @@ -0,0 +1,125 @@ +/* eslint-disable indent */ +import { Breakpoint, debug, SourceBreakpoint } from 'vscode' +import { config } from '../config' +import * as vscode from 'vscode' +import { WorkspaceFolder, DebugConfiguration, ProviderResult, CancellationToken } from 'vscode' +import * as path from 'path' +import { getDebugConfig } from '../util' +import { writeFileSync } from '../common/util' +// import { Map } from '../common/map' +interface Map { + has( + this: MapWith, + key: CheckedString + ): this is MapWith + + has(this: Map, key: CheckedString): this is MapWith +} + +interface MapWith extends Map { + get(k: DefiniteKey): V + get(k: K): V | undefined +} +export function registerDebug() { + let breaks: Breakpoint[] = [] + // eslint-disable-next-line @typescript-eslint/no-unused-vars + class ConfigurationProvider implements vscode.DebugConfigurationProvider { + provideDebugConfigurations( + _folder: WorkspaceFolder | undefined, + _token?: CancellationToken + ): ProviderResult { + const debugConfiguration = getDebugConfig() + return [debugConfiguration] + } + /** + * Massage a debug configuration just before a debug session is being launched, + * e.g. add all missing attributes to the debug configuration. + */ + resolveDebugConfigurationWithSubstitutedVariables( + _folder: WorkspaceFolder | undefined, + debugConfig: DebugConfiguration, + _token?: CancellationToken + ): ProviderResult { + const { nodeBinPath } = config + debugConfig.runtimeExecutable = nodeBinPath + return debugConfig + } + } + class TaskProvider implements vscode.TaskProvider { + static TaskType = 'algorithm' + provideTasks() { + const { debugOptionsFilePath, nodeBinPath } = config + const debugTaskFilePath = path.resolve(__dirname, '../debugTask', 'index.js') + const taskName = 'build' + const tasks = [ + new vscode.Task( + { + type: TaskProvider.TaskType, + }, + vscode.TaskScope.Workspace, + taskName, + TaskProvider.TaskType, + new vscode.ProcessExecution(nodeBinPath, [debugTaskFilePath, '${file}', debugOptionsFilePath]) + ), + ] + const param = serializeBreaks(breaks as SourceBreakpoint[]) + writeFileSync(debugOptionsFilePath, param, { encoding: 'utf8' }) + return tasks + } + resolveTask(task: vscode.Task, _token?: CancellationToken | undefined): ProviderResult { + return task + } + } + + debug.onDidChangeBreakpoints((e) => { + breaks = breaks.concat(e.added) + const removePoints = e.removed + const editPoints = e.changed + breaks = breaks.filter((b) => !removePoints.find((v) => v.id === b.id)) + breaks = breaks.map((v) => editPoints.find((eb) => eb.id === v.id) || v) + }) + vscode.tasks.registerTaskProvider('algorithm', new TaskProvider()) + + // Automatically set configuration more better + // debug.registerDebugConfigurationProvider('node', new ConfigurationProvider()) +} + +interface CustomBreakpoint { + path: string + lines: number[] +} +function serializeBreaks(breaks: SourceBreakpoint[]): string { + const pathMap = new Map() + breaks.forEach((b) => { + const p = b.location.uri.fsPath + const line = b.location.range.start.line + if (!pathMap.has(p)) { + pathMap.set(p, [line]) + } else { + pathMap.get(p)!.push(line) + } + }) + const r: CustomBreakpoint[] = [] + for (const key of pathMap.keys()) { + r.push({ path: key, lines: pathMap.get(key)! }) + } + return JSON.stringify(r) +} +export function tranfromToCustomBreakpoint(breaks: SourceBreakpoint[]) { + const pathMap = new Map() + breaks.forEach((b) => { + const p = b.location.uri.fsPath + const line = b.location.range.start.line + + if (!pathMap.has(p)) { + pathMap.set(p, [line]) + } else { + pathMap.get(p)!.push(line) + } + }) + const r: CustomBreakpoint[] = [] + for (const key of pathMap.keys()) { + r.push({ path: key, lines: pathMap.get(key)! }) + } + return r +} diff --git a/src/debugTask/index.ts b/src/debugTask/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..24988bb44857e8b2e7256b1f12d980fd6f4f493b --- /dev/null +++ b/src/debugTask/index.ts @@ -0,0 +1,90 @@ +import { writeFileSync, promises } from 'fs' +import { outBoundArrayPlugin } from '../babelPlugin' +import rollup = require('rollup') +import resolve from '@rollup/plugin-node-resolve' +import rollupBabelPlugin from '@rollup/plugin-babel' +import * as path from 'path' +import { CodeLang, getFileLang } from '../common/langConfig' +import { DebugOptions } from '../common/lang' +import { handleArgsType } from '../common/util' + +export async function main(options: DebugOptions, args: string[]) { + const mainFilePath = options.filePath + const dir = path.resolve(mainFilePath, '..', '..', '..') + + const outputDir = path.join(dir, 'out') + const codeLang = getFileLang(mainFilePath) + if (![CodeLang.JavaScript, CodeLang.TypeScript].includes(codeLang)) { + console.log('only support JavaScript and TypeScript') + return + } + await promises.mkdir(outputDir, { recursive: true }) + const codePath = path.join(outputDir, 'code.js') + const codeMapPath = path.join(outputDir, 'code.js.map') + + const mainFileCode = options.originCode + + const meta = options.metaData + const funName = meta.name + + if (codeLang === CodeLang.TypeScript) { + const finalCode = mainFileCode + '\n' + handleArgsType(meta, '', args, true) + return buildTsCode(finalCode, mainFilePath, path.join(dir, 'out')) + } + + const bundle = await rollup.rollup({ + input: mainFilePath, + treeshake: false, + plugins: [ + resolve(), + rollupBabelPlugin({ + babelHelpers: 'bundled', + comments: false, + plugins: [outBoundArrayPlugin], + }), + ], + }) + const { output } = await bundle.generate({ + sourcemap: true, + sourcemapPathTransform: (r, s) => { + return path.join(path.parse(s).dir, r) + }, + }) + let code = output[0].code + const map = output[0].map + if (funName) { + code += handleArgsType(meta, '', args) + '\n' + } + + code = code + '//# sourceMappingURL=code.js.map' + if (map?.file) { + map.file = 'code.js' + } + + writeFileSync(codePath, code) + writeFileSync(codeMapPath, JSON.stringify(map)) +} + +export async function buildTsCode(text: string, filePath: string, dir: string) { + // eslint-disable-next-line @typescript-eslint/no-var-requires + return require('esbuild') + .build({ + stdin: { + contents: text, + loader: 'ts', + resolveDir: dir, + sourcefile: filePath, + }, + platform: 'node', + mainFields: ['module', 'main'], + bundle: true, + format: 'esm', + treeShaking: true, + outfile: 'code.js', + absWorkingDir: dir, + sourcemap: 'inline', + }) + .catch((err) => { + console.log(err) + }) +} diff --git a/src/execTestCode.ts b/src/execTestCode.ts new file mode 100644 index 0000000000000000000000000000000000000000..21de875937b12ab589ca574759ec404d95e720c1 --- /dev/null +++ b/src/execTestCode.ts @@ -0,0 +1,35 @@ +import cp = require('child_process') + +import path = require('path') +import { config } from './config' +import { window } from 'vscode' +import { TestOptions } from './common/lang' +const notFoundReg = /node: not found/ +export function execTestChildProcess(options: TestOptions): Promise { + return new Promise((resolve) => { + const { nodeBinPath } = config + const cmd = cp.spawn(nodeBinPath, [path.join(__dirname, './child_process/execTestCode.js')]) + let msg = '' + cmd.stdout.on('data', (data) => { + console.log('data', data) + msg += data + }) + cmd.stdin.setDefaultEncoding('utf8') + cmd.stdin.write(JSON.stringify(options)) + cmd.stdin.end() + // cmd.send(JSON.stringify(options)) + cmd.stderr.on('data', (message) => { + console.log('err', message.toString()) + if (notFoundReg.test(message)) { + window.showErrorMessage(message + ',please set the path of the nodejs') + } else { + window.showErrorMessage(message) + } + }) + cmd.on('close', () => { + resolve(msg) + console.log('child process close') + console.log('msg', msg) + }) + }) +} diff --git a/src/extension.ts b/src/extension.ts index f39c78e58af9e61f83f634e52d1bc6e017515ae2..db2e8df3dd6e0840f48676a49304ae82cae4fad2 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,26 +1,90 @@ -// The module 'vscode' contains the VS Code extensibility API -// Import the module and reference it with the alias vscode in your code below -import * as vscode from 'vscode'; - -// this method is called when your extension is activated -// your extension is activated the very first time the command is executed +import * as vscode from 'vscode' +import { languages, commands } from 'vscode' +import { CodelensProvider } from './provider/codelensProvider' +import { + testCodeCommand, + buildCodeCommand, + submitCommand, + refreshCommand, + switchEndpointCommand, + signInCommand, + switchCodeLangCommand, + debugCodeCommand, + getDescriptionCommand, + searchCommand, + memoFilePreviewCommand, + addFolderCommand, + addMemoFileCommand, + removeMemoFileCommand, + switchDataBaseCommand, + viewSubmitHistoryCommand, + newAnswerCommand, +} from './commands' +import { QuestionsProvider } from './provider/questionsProvider' +import { createQuestionPanelCommand } from './webview/questionPreview' +import { config, onChangeConfig } from './config' +import { registerForSnippetProviders } from './provider/snippetProvider' +import { registerDebug } from './debug/launch' +import { registerCompletionItemProvider } from './provider/completionProvider' +import { MemoProvider } from './provider/memoProvider' +import { childProcessProxy } from './process' export function activate(context: vscode.ExtensionContext) { - - // Use the console to output diagnostic information (console.log) and errors (console.error) - // This line of code will only be executed once when your extension is activated - console.log('Congratulations, your extension "leetcode-design" is now active!'); - - // The command has been defined in the package.json file - // Now provide the implementation of the command with registerCommand - // The commandId parameter must match the command field in package.json - let disposable = vscode.commands.registerCommand('leetcode-design.helloWorld', () => { - // The code you place here will be executed every time your command is executed - // Display a message box to the user - vscode.window.showInformationMessage('这是插件执行命令!'); - }); + const subscriptions = context.subscriptions + registerCompletionItemProvider(context) + registerForSnippetProviders(context) + registerDebug() + const codelensProvider = new CodelensProvider() + languages.registerCodeLensProvider('*', codelensProvider) + const questionsProvider = new QuestionsProvider(vscode.workspace.workspaceFolders, context.extensionPath) + config.questionsProvider = questionsProvider + const memoProvider = new MemoProvider() + subscriptions.push(commands.registerCommand('algorithm.testCode', testCodeCommand)) + subscriptions.push(commands.registerCommand('algorithm.debugCode', debugCodeCommand)) + subscriptions.push(commands.registerCommand('algorithm.buildCode', buildCodeCommand.bind(null, context))) + subscriptions.push(commands.registerCommand('algorithm.submit', submitCommand.bind(null, questionsProvider))) + subscriptions.push( + commands.registerCommand('algorithm.getDescription', getDescriptionCommand.bind(null, context.extensionPath)) + ) + subscriptions.push( + commands.registerCommand( + 'algorithm.questionPreview', + createQuestionPanelCommand.bind(null, context.extensionPath) + ) + ) + subscriptions.push( + commands.registerCommand('algorithm.refreshQuestions', refreshCommand.bind(null, questionsProvider)) + ) + subscriptions.push( + commands.registerCommand('algorithm.switchEndpoint', switchEndpointCommand.bind(null, questionsProvider)) + ) + subscriptions.push(commands.registerCommand('algorithm.signIn', signInCommand.bind(null, questionsProvider))) + subscriptions.push( + commands.registerCommand('algorithm.switchCodeLang', switchCodeLangCommand.bind(null, questionsProvider)) + ) + subscriptions.push(commands.registerCommand('algorithm.search', searchCommand)) + subscriptions.push(commands.registerCommand('algorithm.memoFilePreview', memoFilePreviewCommand)) + subscriptions.push(commands.registerCommand('algorithm.addFolder', addFolderCommand.bind(null, memoProvider))) + subscriptions.push(commands.registerCommand('algorithm.addMemoFile', addMemoFileCommand.bind(null, memoProvider))) + subscriptions.push( + commands.registerCommand('algorithm.removeMemoFile', removeMemoFileCommand.bind(null, memoProvider)) + ) + subscriptions.push(commands.registerCommand('algorithm.switchDataBase', switchDataBaseCommand)) + subscriptions.push( + commands.registerCommand('algorithm.viewSubmitHistory', viewSubmitHistoryCommand.bind(null, context)) + ) + subscriptions.push(commands.registerCommand('algorithm.newAnswer', newAnswerCommand)) - context.subscriptions.push(disposable); + vscode.window.createTreeView('questions', { + treeDataProvider: questionsProvider, + showCollapseAll: true, + }) + vscode.window.createTreeView('memo', { + treeDataProvider: memoProvider, + showCollapseAll: true, + }) + subscriptions.push(vscode.workspace.onDidChangeConfiguration(onChangeConfig.bind(null, questionsProvider))) } -// this method is called when your extension is deactivated -export function deactivate() {} +export function deactivate() { + childProcessProxy.clear() +} \ No newline at end of file diff --git a/src/fileStorage/README.md b/src/fileStorage/README.md new file mode 100644 index 0000000000000000000000000000000000000000..410911752c26e20649be39a87a55fb3dc9cf8eda --- /dev/null +++ b/src/fileStorage/README.md @@ -0,0 +1,22 @@ +# 存储文件格式 + +## header + +| field | length | +| ------------ | ------ | +| magic number | 32 | +| version | 32 | +| checksum | 32 | +| count | 32 | + +### section header + +| field | length | +| --------- | ------ | +| checksum | 32 | +| id | 32 | +| fid | 32 | +| offset | 32 | +| size | 16 | +| hash | 128 | +| timestamp | 64 | diff --git a/src/fileStorage/crc32_table.ts b/src/fileStorage/crc32_table.ts new file mode 100644 index 0000000000000000000000000000000000000000..5704a0d5caf5dc993a2bc79280f47a0229d0b6d4 --- /dev/null +++ b/src/fileStorage/crc32_table.ts @@ -0,0 +1,36 @@ +/** + * copy from https://docs.microsoft.com/en-us/openspecs/office_protocols/ms-abs/06966aa2-70da-4bf9-8448-3355f277cd77?redirectedfrom=MSDN + */ + +const crc32_table: number[] = [ + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, + 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, + 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, + 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, + 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, + 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, + 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, + 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, + 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, + 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, + 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, + 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, +] +export default crc32_table diff --git a/src/fileStorage/db.ts b/src/fileStorage/db.ts new file mode 100644 index 0000000000000000000000000000000000000000..bcc5e9d9287d4a0d116dc936c5656b40fc09bbbf --- /dev/null +++ b/src/fileStorage/db.ts @@ -0,0 +1,276 @@ +import path = require('path') +import fs = require('fs') +import util = require('util') +import { crc32, md5 } from './util' +import { existDir, existFile, writeFileAsync } from '../common/util' +const openAsync = util.promisify(fs.open) +const readAsync = util.promisify(fs.read) +const writeAsync = util.promisify(fs.write) +const readFileAsync = util.promisify(fs.readFile) + +const META = 'Meta' +const MAGIC = 0x125e591 +const VERSION = 1 +const HeaderConfig: Field[] = [ + { + field: 'magic', + type: 'int', + len: 32, + }, + { + field: 'version', + type: 'int', + len: 32, + }, + { + field: 'checksum', + type: 'int', + len: 32, + }, + { + field: 'count', + type: 'int', + len: 32, + }, +] +const SectionHeaderConfig: Field[] = [ + { + field: 'checksum', + type: 'int', + len: 32, + }, + { + field: 'id', + type: 'int', + len: 32, + }, + { + field: 'fid', + type: 'int', + len: 32, + }, + { + field: 'offset', + type: 'int', + len: 32, + }, + { + field: 'size', + type: 'int', + len: 16, + }, + { + field: 'hash', + type: 'hex', + len: 128, + }, + { + field: 'timestamp', + type: 'int', + len: 64, + }, +] +interface DbOptions { + dbDir: string + filename: string +} +export default class Db { + private dbDir: string + private filename: string + private headerPath: string + private filePath: string + public fds: number[] = [-1, -1] + public buffer: Buffer = Buffer.alloc(0) + public header: Header | null = null + public sectionHeaders: SectionHeader[] = [] + // public headerFd: number + constructor(options: DbOptions) { + this.dbDir = options.dbDir + this.filename = options.filename + this.headerPath = path.join(this.dbDir, this.filename + META) + this.filePath = path.join(this.dbDir, this.filename) + } + async init(): Promise { + await existDir(this.dbDir) + await existFile(this.headerPath) + await existFile(this.filePath) + const headerFd = await openAsync(this.headerPath, 'r+') + const dataFd = await openAsync(this.filePath, 'r+') + this.fds = [headerFd, dataFd] + + const buffer = await readFileAsync(this.headerPath) + this.buffer = buffer + await this._init() + } + async _init(): Promise { + const buffer = this.buffer + let header: Header + const sectionHeaders: SectionHeader[] = [] + if (!buffer.length) { + const count = 0 + header = { + magic: MAGIC, + version: VERSION, + checksum: crc32(Buffer.alloc(4)), + count, + } + await writeFileAsync(this.headerPath, convertToBuffer(header, HeaderConfig)) + } else { + const headerLen = getLen(HeaderConfig) + const headerBuf = buffer.slice(0, headerLen) + header = convertToObj
(headerBuf, HeaderConfig) + + // header = { + // magic: buffer.slice(0, 4).readInt32BE(), + // version: buffer.slice(4, 8).readInt32BE(), + // checksum: buffer.slice(8, 12).readInt32BE(), + // count: buffer.slice(12, 16).readInt32BE() + // } + const sectionHeadersBuf = buffer.slice(headerLen) + const len = getLen(SectionHeaderConfig) + for (let i = 0; i < sectionHeadersBuf.length / len; i++) { + const buf = sectionHeadersBuf.slice(i * len, (i + 1) * len) + + sectionHeaders.push(convertToObj(buf, SectionHeaderConfig)) + } + } + this.header = header + this.sectionHeaders = sectionHeaders + } + async read(id: number): Promise { + const sectionHeader = this.sectionHeaders.find((v) => v.id === id) + if (sectionHeader) { + const buf = Buffer.alloc(sectionHeader.size) + await readAsync(this.fds[1], buf, 0, buf.length, sectionHeader.offset) + return buf.toString('utf8') + } + return '' + } + async add(question: string, id: number, fid: number): Promise { + if (this.sectionHeaders.find((v) => v.id === id)) { + return + } + const buffer = Buffer.from(question) + const count = (this.header as Header).count + const last = count > 0 ? this.sectionHeaders[count - 1] : { offset: 0, size: 0 } + const offset = last.offset + last.size + const size = buffer.length + const hash = md5(buffer) + const partialSecHeader = { + id, + fid, + offset, + size, + hash, + timestamp: Date.now(), + } + const config = SectionHeaderConfig.slice(1) + const partialSecHeaderBuf = convertToBuffer(partialSecHeader, config) + const checksum = crc32(partialSecHeaderBuf) + const sectionHeader = { + checksum, + ...partialSecHeader, + } + this.sectionHeaders[count] = sectionHeader + + const secHeaderBuf = convertToBuffer(sectionHeader, SectionHeaderConfig) + + ;(this.header as Header).count++ + ;(this.header as Header).checksum = crc32(convertToBuffer(this.sectionHeaders, SectionHeaderConfig)) + const headerBuf = convertToBuffer(this.header, HeaderConfig) + const headerLen = getLen(HeaderConfig) + const secHeaderLen = getLen(SectionHeaderConfig) + const secOffset = headerLen + count * secHeaderLen + await Promise.all([ + writeAsync(this.fds[0], secHeaderBuf, 0, secHeaderBuf.length, secOffset), + writeAsync(this.fds[0], headerBuf, 0, headerBuf.length, 0), + writeAsync(this.fds[1], buffer, 0, buffer.length, offset), + ]) + } +} +interface Header { + magic: number + version: number + checksum: number + count: number +} +interface SectionHeader { + checksum: number + id: number + fid: number + offset: number + size: number + hash: string + timestamp: number +} +type FieldType = 'int' | 'hex' +export interface Field { + field: string + type: FieldType + len: number +} + +export function convertToObj(buffer: Buffer, config: Field[]): T { + let i = 0 + const obj: Partial = {} + for (const field of config) { + obj[field.field] = read(buffer, i, field) + i += field.len / 8 + } + return obj as T +} +export function convertToBuffer(obj: T[] | T, config: Field[]): Buffer { + if (Array.isArray(obj)) { + return Buffer.concat(obj.map((v) => convertToBuffer(v, config))) + } + let i = 0 + const len = getLen(config) + const buf = Buffer.alloc(len) + + for (const field of config) { + write(obj[field.field], buf, i, field) + i += field.len / 8 + } + return buf +} + +function getLen(config: Field[]) { + return config.reduce((prev, cur) => prev + cur.len / 8, 0) +} + +function read(buffer: Buffer, offset: number, field: Field) { + const mapFun = { + int: (buffer: Buffer) => { + const byteLen = field.len / 8 + if (byteLen === 8) { + try { + const a = Number(buffer.readBigUInt64BE(offset)) + return a + } catch (err) { + console.log(buffer) + } + } else { + return buffer.readUIntBE(offset, field.len / 8) + } + }, + + hex: (buffer: Buffer) => buffer.slice(offset, offset + field.len / 8).toString('hex'), + } + const fun = mapFun[field.type] + return fun(buffer) +} +function write(value: number | string, buffer: Buffer, offset: number, field: Field) { + const mapFunc = { + int: () => { + const byteLen = field.len / 8 + if (byteLen === 8) { + buffer.writeBigInt64BE(BigInt(value as number), offset) + } else { + buffer.writeUIntBE(value as number, offset, field.len / 8) + } + }, + hex: () => Buffer.from(value as string, 'hex').copy(buffer, offset), + } + const fun = mapFunc[field.type] + return fun() +} diff --git a/src/fileStorage/util.ts b/src/fileStorage/util.ts new file mode 100644 index 0000000000000000000000000000000000000000..d0feae20a45b530e7f02ccdf1a4351cad9388113 --- /dev/null +++ b/src/fileStorage/util.ts @@ -0,0 +1,24 @@ +import crypto = require('crypto') +import crc32_table from './crc32_table' +export function md5(data: crypto.BinaryLike): string { + const hash = crypto.createHash('md5') + return hash.update(data).digest('hex') +} + +/** + * Reference:https://docs.microsoft.com/en-us/openspecs/office_protocols/ms-abs/06966aa2-70da-4bf9-8448-3355f277cd77?redirectedfrom=MSDN + * @param buffer + */ +export function crc32(buffer: Buffer): number { + let crc = 0xffffffff + let i = 0 + while (i < buffer.length) { + crc = crc32_table[(crc & 0xff) ^ buffer[i]] ^ ((crc >= 0 ? crc : 2 ** 32 + crc) / 256) + i++ + } + crc = crc ^ 0xffffffff + return crc >= 0 ? crc : 2 ** 32 + crc +} +export function verify(data: Buffer, checksum: number) { + return crc32(data) === checksum +} diff --git a/src/history/answer.ts b/src/history/answer.ts new file mode 100644 index 0000000000000000000000000000000000000000..57f416ea14508e1a2abda82b42e48abbb0bc8efb --- /dev/null +++ b/src/history/answer.ts @@ -0,0 +1,112 @@ +import { generateId, getDesc, getFuncNames, QuestionMeta, readFileAsync } from '../common/util' +import { submitStorage } from './storage' +import * as path from 'path' +import { config } from '../config' +import { fetchQuestion, getName } from '../webview/questionPreview' +import { preprocessCode } from '../util' +import { CodeLang, isAlgorithm, langMap } from '../common/langConfig' +import { Service } from '../lang/common' +import { writeFile } from '../common/util' +import { readJson, writeJson, ensureFile } from 'fs-extra' +import { UpdateCommentOption } from '../model/common' +interface Answer { + id: string + code: string + desc: string + timestamp: string + lang?: string + titleSlug?: string + questionId?: string +} + +export class AnswerStorage { + static answerStorage = new AnswerStorage() + getFilePath(questionId: string) { + const cacheDir = path.join(config.cacheDir, 'answer') + return path.join(cacheDir, questionId + '.json') + } + static saveSubmit(filePath: string, text: string, result: any) { + const desc = getDesc(text, filePath) || '' + + submitStorage.save({ + filePath: filePath, + text, + result, + desc, + }) + } + async read(questionId: string): Promise { + const filePath = this.getFilePath(questionId) + try { + const arr = await readJson(filePath) + return arr + } catch (err) { + console.log(err) + return [] + } + } + async save(data: string, questionMeta: QuestionMeta) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const id = questionMeta.id! + const historyfilePath = this.getFilePath(id) + const arr = await this.read(id) + const newAnswer: Answer = { + code: data, + id: generateId(), + desc: questionMeta.desc || '', + timestamp: Math.floor(Date.now() / 1000).toString(), + lang: questionMeta.lang, + questionId: id, + titleSlug: questionMeta.titleSlug, + } + arr.push(newAnswer) + await ensureFile(historyfilePath) + await writeJson(historyfilePath, arr) + } + async updateComment({ id, questionId, comment }: UpdateCommentOption) { + const arr = await this.read(questionId) + const historyfilePath = this.getFilePath(questionId) + const item = arr.find((v) => v.id === id) + if (item) { + item.desc = comment + } + await writeJson(historyfilePath, arr) + } + async newAnswer(filePath: string) { + const data = await readFileAsync(filePath, { encoding: 'utf8' }) + const { questionMeta } = getFuncNames(data, filePath) + const id = questionMeta.id + if (!id) { + return + } + await this.save(data, questionMeta) + + const { weekname, lang: langSlug } = questionMeta + const param = { + titleSlug: questionMeta.titleSlug, + weekname: questionMeta.weekname, + questionId: questionMeta.id, + } + const question = await fetchQuestion(param) + if (!question) { + return + } + const { codeSnippets, questionFrontendId, title, translatedTitle } = question + const codeSnippet = codeSnippets.find((codeSnippet) => codeSnippet.langSlug === langSlug) + if (codeSnippet) { + const langSlug = codeSnippet.langSlug + const langConfig = langMap[langSlug] + const { name } = getName(questionFrontendId, title, translatedTitle, codeSnippet) + let code = preprocessCode(question, weekname, codeSnippet, name) + if (langConfig.lang === CodeLang.Java) { + code = code.replace('class Solution', 'public class Solution') + } + if (isAlgorithm(langConfig.lang)) { + await Service.handlePreImport(filePath) + } + + await writeFile(filePath, code) + } + } +} +export const answerStorage = AnswerStorage.answerStorage diff --git a/src/history/index.ts b/src/history/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..9f1c59f313065be85a7fe13b9d3fc1ef0c0bf742 --- /dev/null +++ b/src/history/index.ts @@ -0,0 +1,166 @@ +import { answerStorage } from './answer' +import { submitStorage } from './storage' +import { config } from '../config' +import { HistoryType, Lang, UpdateCommentOption } from '../model/common' +import { api } from '../api/index' + +export async function getHistory(questionId: string, fn: (code: string, lang: string) => string) { + const originAnswers = await answerStorage.read(questionId) + const formatAnswers = originAnswers + .map((v) => { + return { + code: fn(v.code, v.lang || ''), + obj: { + desc: v.desc, + timestamp: formatTimestamp(v.timestamp), + id: v.id, + lang: v.lang, + }, + } + }) + .reverse() + const answerData = { + header: [ + { + label: 'description', + key: 'desc', + }, + { + label: 'lang', + key: 'lang', + }, + { + label: 'timestamp', + key: 'timestamp', + }, + ], + arr: formatAnswers, + } + const originSubmitStorage = await submitStorage.read(questionId) + const formatSubmits = originSubmitStorage + .map((v) => { + return { + code: fn(v.code, v.submission.lang), + obj: { + ...v.submission, + memory: v.submission.memory, + comment: v.submission.submissionComment, + statusDisplay: v.submission.statusDisplay, + }, + } + }) + .reverse() + + const submitStorageData = { + header: [ + { + label: 'statusDisplay', + key: 'statusDisplay', + }, + { + label: 'lang', + key: 'lang', + }, + { + label: 'memory', + key: 'memory', + }, + { + label: 'runtime', + key: 'runtime', + }, + { + label: 'comment', + key: 'comment', + }, + ], + arr: formatSubmits, + } + + return { + id: questionId, + answerData: answerData, + localSubmit: submitStorageData, + // remoteSubmit: remoteStorageData + } +} +export async function getRemoteSubmits(questionId: string) { + const question = await api.fetchQuestionDetailById(questionId) + const res = await api.fetchSubmissions({ titleSlug: question.titleSlug }) + const submissions = res.submissionList.submissions || [] + const formatRemoteSubmits = submissions.map((v) => { + return { + code: '', + obj: { + ...v, + memory: v.memory, + timestamp: formatTimestamp(v.timestamp), + comment: v?.submissionComment?.comment, + id: v.id, + }, + } + }) + const remoteStorageData = { + header: [ + { + label: 'statusDisplay', + key: 'statusDisplay', + }, + { + label: 'lang', + key: 'lang', + }, + { + label: 'memory', + key: 'memory', + }, + { + label: 'runtime', + key: 'runtime', + }, + { + label: 'comment', + key: 'comment', + }, + ], + arr: formatRemoteSubmits, + } + return remoteStorageData +} +export function formatTimestamp(time: string | number) { + if (typeof time === 'string') { + time = parseInt(time) + } + const num = time * 1000 + const date = new Date(num) + const year = date.getFullYear() + const month = (date.getMonth() + 1).toString().padStart(2, '0') + const day = date.getDate().toString().padStart(2, '0') + const hours = date.getHours().toString().padStart(2, '0') + const minutes = date.getMinutes().toString().padStart(2, '0') + if (config.lang === Lang.cn) { + return `${year}/${month}/${day} ${hours}:${minutes}` + } else { + return `${year}/${month}/${day} ${hours}:${minutes}` + } +} +export function formatMemory(memory: number) { + return Math.floor(memory / (1024 * 1024)) + 'M' +} + +// export function updateComment(type: HistoryType.Answer | HistoryType.LocalSubmit, options: UpdateCommentOption): Promise +// export function updateComment(type: HistoryType.RemoteSubmit, options: UpdateRemoteCommentOption): Promise + +export async function updateComment(type: HistoryType, options: UpdateCommentOption): Promise { + switch (type) { + case HistoryType.Answer: { + return answerStorage.updateComment(options) + } + case HistoryType.LocalSubmit: { + return submitStorage.updateComment(options) + } + case HistoryType.RemoteSubmit: { + return submitStorage.updateRemoteComment(options) + } + } +} diff --git a/src/history/storage.ts b/src/history/storage.ts new file mode 100644 index 0000000000000000000000000000000000000000..8eecdfb694b11bc5091b87962cbe4d18e5a798c3 --- /dev/null +++ b/src/history/storage.ts @@ -0,0 +1,126 @@ +import * as path from 'path' +import { config } from '../config' +import { pathExists, readJson, writeJson, ensureFile } from 'fs-extra' +import { CheckResponse, Lang, UpdateCommentOption, UpdateRemoteCommentOption } from '../model/common' +import { apiCn } from '../api' +import { formatMemory, formatTimestamp } from '.' +interface Param { + filePath: string + text: string + result: CheckResponse + desc?: string +} +interface LocalSubmit { + id: string + code: string + submission: Submission + result: CheckResponse +} +interface Submission { + id: string + statusDisplay: string + lang: string + runtime: string + timestamp: string + url: string + isPending: string + memory: string + submissionComment: string +} +class SubmitStorage { + static submitStorage = new SubmitStorage() + arr: Param[] = [] + isWork = false + getFilePath(question_id: string) { + const cacheDir = path.join(config.cacheDir, 'submit') + return path.join(cacheDir, question_id + '.json') + } + async read(question_id: string): Promise { + const filePath = this.getFilePath(question_id) + try { + const arr = await readJson(filePath) + return arr + } catch (err) { + return [] + } + } + async save(options: Param) { + if (this.isWork) { + this.arr.push(options) + } else { + this.isWork = true + await this.innerSave(options) + } + } + saveSubmit(options: Param) { + if (options.desc) { + this.updateRemoteComment({ + id: options.result.submission_id, + comment: options.desc, + }) + } + + this.save(options) + } + updateRemoteComment({ id, comment }: UpdateRemoteCommentOption) { + if (config.lang === Lang.cn && comment) { + return apiCn.api.updateComment({ + submissionId: id, + comment: comment, + }) + } + } + async updateComment({ id, questionId, comment }: UpdateCommentOption): Promise { + const arr = await this.read(questionId) + const item = arr.find((v) => v.id === id) + if (item) { + item.submission.submissionComment = comment + } + const filePath = this.getFilePath(questionId) + return writeJson(filePath, arr) + } + private async innerSave(options: Param): Promise { + try { + const id = options.result.question_id as string + const r = options.result + const filePath = this.getFilePath(id) + const obj: LocalSubmit = { + id: r.submission_id, + code: options.text, + submission: { + id: r.submission_id, + isPending: 'Not Pending', + submissionComment: options.desc || '', + lang: r.lang, + memory: formatMemory(r.memory), + runtime: r.status_runtime, + statusDisplay: r.status_msg, + timestamp: formatTimestamp(r.task_finish_time), + url: '/submissions/detail/' + r.submission_id + '/', + }, + result: options.result, + } + let arr: LocalSubmit[] = [] + const exist = await pathExists(filePath) + if (exist) { + arr = await readJson(filePath) + arr.push(obj) + } else { + arr.push(obj) + } + await ensureFile(filePath) + await writeJson(filePath, arr) + } catch (err) { + console.log(err) + } + if (this.arr.length) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const opt = this.arr.shift()! + await this.innerSave(opt) + } else { + this.isWork = false + } + } +} + +export const submitStorage = SubmitStorage.submitStorage diff --git a/src/lang/base.ts b/src/lang/base.ts new file mode 100644 index 0000000000000000000000000000000000000000..4db45f3fbc8e22202d5c5c144b086ffc0dccfdca --- /dev/null +++ b/src/lang/base.ts @@ -0,0 +1,238 @@ +import { readFileAsync, TestCase, TestCaseParam, CaseList } from '../common/util' +import { getFuncNames, parseTestCase, TestResult, handleMsg } from '../common/util' +import { log } from '../config' +import { api } from '../api/index' +import { resolve } from 'path' +import { OutputChannel } from 'vscode' +import * as vscode from 'vscode' +import { tranfromToCustomBreakpoint } from '../debug/launch' +import { getFileComment } from '../common/langConfig' +import { parseCommentTest } from '../common/util' +import { defaultTimeout, LanguageMetaData, MetaData } from '../common/lang' +import { childProcessProxy } from '../process' +import * as cp from 'child_process' + +export abstract class BaseLang { + public log: OutputChannel + public originCode?: string + public commentToken: '#' | '//' + public abstract funcRegExp: RegExp + public abstract testRegExp: RegExp + public abstract runInNewContext(args: string[], originCode: string, funcName: string): Promise + // eslint-disable-next-line @typescript-eslint/no-explicit-any + public abstract getDebugConfig(breaks?: vscode.SourceBreakpoint[]): any + public abstract beforeDebug(breaks: vscode.SourceBreakpoint[]): Promise + public abstract handlePreImport(): void + public abstract shouldRemoveInBuild(line: string): boolean + constructor(public filePath: string, public text?: string) { + this.log = log + if (!filePath) { + throw new Error('filePath must not empty') + } + if (text) { + this.originCode = text + } + this.commentToken = getFileComment(filePath) + } + async getOriginCode() { + if (this.originCode) { + return this.originCode + } + const originCode = await readFileAsync(this.filePath, { + encoding: 'utf8', + }) + this.originCode = originCode + return this.originCode + } + public async getQuestionMeta(): Promise { + const originCode = await this.getOriginCode() + const { questionMeta } = getFuncNames(originCode, this.filePath) + const id = questionMeta.id + if (!id) { + this.log.appendLine('id is null') + return + } + const question = await api.fetchQuestionDetailById(id) + if (!question) { + this.log.appendLine('question not found') + return + } + const metaData: MetaData = JSON.parse(question.metaData) + return metaData + } + async resolveArgsFromBreaks(breaks: vscode.SourceBreakpoint[]): Promise { + const filePath = this.filePath + const customBreakpoints = tranfromToCustomBreakpoint(breaks) + const customBreakPoint = customBreakpoints.find((c) => c.path === filePath) + if (!customBreakPoint) { + throw new Error('breakpoint not found, please set breakpoint first') + } + const originCode = await this.getOriginCode() + const questionMeta = (await this.getQuestionMeta()) as LanguageMetaData | undefined + if (!questionMeta) { + throw new Error('questionMeta not found ') + } + const codeLines = originCode.split('\n') + + const lines = customBreakPoint.lines + const line = lines.find((num) => this.testRegExp.test(codeLines[num])) + if (!Number.isInteger(line)) { + throw new Error('please select the test case') + } + const { args } = parseCommentTest(codeLines[line as number]) + return args + } + handleResult(stdout: string, caseList) { + const testResultList: TestResult[] = caseList.map((v) => { + return { + args: v.args, + expect: v.result, + } + }) + const regexp = /resultabc(\d+):(.+?)resultend/g + let r + while ((r = regexp.exec(stdout))) { + const index = r[1] + const result = r[2] + testResultList[index].result = result + } + return testResultList + } + async waitExecTest(p: cp.PromiseWithChild<{ + stdout: string; + stderr: string; + }>, caseList: CaseList) { + const child = p.child + childProcessProxy.add(child) + try { + const { stdout } = await p + const testResultList = this.handleResult(stdout, caseList) + childProcessProxy.remove(child) + return handleMsg(testResultList) + } catch (err) { + if (err.killed) { + log.appendLine(`timeout ${defaultTimeout}ms`) + } + childProcessProxy.remove(child) + log.appendLine(err) + } + } + async runMultiple(caseList: CaseList, originCode: string, funcName: string): Promise { + const testResultList: TestResult[] = [] + + for (const { args, result: expect } of caseList) { + try { + const result = await this.runInNewContext(args, originCode, funcName) + testResultList.push({ + args: args.join(','), + expect: expect, + result, + }) + } catch (err) { + const msg = `× @test(${args.join(',')})\n` + resolve(msg + err.stderr) + return + } + } + return handleMsg(testResultList) + } + public async execTest(testCase: TestCase) { + const filePath = this.filePath + const caseList = parseTestCase(testCase) + const originCode = await readFileAsync(filePath, { encoding: 'utf8' }) + const { questionMeta } = getFuncNames(originCode, filePath) + const id = questionMeta.id + if (!id) { + log.appendLine('id is null') + return + } + const question = await api.fetchQuestionDetailById(id) + if (!question) { + log.appendLine('question not found') + return + } + const metaData: LanguageMetaData = JSON.parse(question.metaData) + const funcName = metaData.name + if (!caseList.length) { + return + } + return this.runMultiple(caseList, originCode, funcName) + } + + public getTestCaseList(text: string) { + const testRegExp = + this.commentToken === '#' + ? /#\s*@test\(((?:"(?:\\.|[^"])*"|[^)])*)\)/ + : /\/\/\s*@test\(((?:"(?:\\.|[^"])*"|[^)])*)\)/ + const funcRegExp = this.funcRegExp + const testCase: TestCase = [] + const lines = text.split(/\n/) + + for (let i = 0; i < lines.length; i++) { + const line = lines[i] + if (testRegExp.test(line)) { + testCase.push(line) + } else if (funcRegExp.test(line)) { + const testCaseList: TestCaseParam[] = [ + { + line: i, + testCase, + funcName: '', + paramsTypes: [], + resultType: '', + }, + ] + return testCaseList + } + } + return [] + } + + async debugCodeCommand(folder: vscode.WorkspaceFolder, breaks: vscode.SourceBreakpoint[]) { + try { + await this.beforeDebug(breaks) + } catch (err) { + log.appendLine(err.message) + log.show() + return + } + + const debugConfiguration = await this.getDebugConfig(breaks) + + vscode.debug.startDebugging(folder, debugConfiguration) + } + public async buildCode() { + const originCode = await this.getOriginCode() + const { questionMeta } = getFuncNames(originCode, this.filePath) + const commentToken = getFileComment(this.filePath) + + const code = originCode + .split('\n') + .filter((line) => !isComment(line, commentToken) && !this.shouldRemoveInBuild(line)) + .join('\n') + return { + code, + questionMeta, + } + } + public addComment(text: string, comment: string, _funcName: string) { + const lines = text.split('\n') + const n = lines.length + for (let i = n - 1; i >= 0; i--) { + if (this.testRegExp.test(lines[i])) { + const newLine = this.commentToken + comment + return [...lines.slice(0, i + 1), newLine, ...lines.slice(i + 1)].join('\n') + } + } + for (let i = 0; i < n; i++) { + if (this.funcRegExp.test(lines[i])) { + const newLine = this.commentToken + comment + return [...lines.slice(0, i + 1), newLine, ...lines.slice(i + 1)].join('\n') + } + } + } +} + +function isComment(line: string, commentToken: '#' | '//') { + return line.trimLeft().startsWith(commentToken) +} diff --git a/src/lang/bash.ts b/src/lang/bash.ts new file mode 100644 index 0000000000000000000000000000000000000000..9cdd5415a827c7ffb99a1521042e11c5e21b5eef --- /dev/null +++ b/src/lang/bash.ts @@ -0,0 +1,45 @@ +import { log } from '../config' +import { OutputChannel } from 'vscode' +import { readFileAsync } from '../common/util' +import { getFuncNames } from '../common/util' + +export class BashParse { + public log: OutputChannel + public originCode?: string + public commentToken = '#' + constructor(public filePath: string, public text?: string) { + this.log = log + if (!filePath) { + throw new Error('filePath must not empty') + } + if (text) { + this.originCode = text + } + } + async getOriginCode() { + if (this.originCode) { + return this.originCode + } + const originCode = await readFileAsync(this.filePath, { + encoding: 'utf8', + }) + this.originCode = originCode + return this.originCode + } + public async buildCode() { + const originCode = await this.getOriginCode() + const { questionMeta } = getFuncNames(originCode, this.filePath) + + const code = originCode + .split('\n') + .filter((line) => !this.isComment(line)) + .join('\n') + return { + code, + questionMeta, + } + } + isComment(line: string): boolean { + return line.trim().startsWith('#') + } +} diff --git a/src/lang/common.ts b/src/lang/common.ts new file mode 100644 index 0000000000000000000000000000000000000000..426bc31457beec8907bbfdcd48da0a8b81441790 --- /dev/null +++ b/src/lang/common.ts @@ -0,0 +1,67 @@ +import { CodeLang, getFileLang, ExtraType } from '../common/langConfig' +import { BaseLang } from './base' +import { PythonParse } from './python' +import { GoParse } from './golang' +import { JavaParse } from './java' +import { CppParse } from './cpp' +import { TestCase } from '../common/util' +import * as vscode from 'vscode' +import * as path from 'path' +import { enableLang } from '../common/langConfig' +import { JavascriptParse } from './javascript' +import { TypescriptParse } from './typescript' +const langMap = { + [CodeLang.Python3]: PythonParse, + [CodeLang.Go]: GoParse, + [CodeLang.Java]: JavaParse, + [CodeLang['C++']]: CppParse, + [CodeLang.JavaScript]: JavascriptParse, + [CodeLang.TypeScript]: TypescriptParse, +} +export class Service { + public codeLang: CodeLang + private ctx: BaseLang + constructor(public filePath: string, public text?: string) { + this.codeLang = getFileLang(filePath) + + const Parse = langMap[this.codeLang] + if (!Parse) { + const fileParse = path.parse(filePath) + throw new Error('Currently, not support ' + fileParse.ext) + } + this.ctx = new Parse(filePath, text) + } + static getPreImport(codeLang: CodeLang, name: string, extraTypeSet: Set): string { + const Parse = langMap[codeLang] + if (!Parse) { + return '' + } + return Parse.getPreImport(name, extraTypeSet) + } + static handlePreImport(filePath: string) { + const codeLang = getFileLang(filePath) + if (['JavaScript', 'TypeScript'].includes(codeLang)) { + return + } + const service = new Service(filePath) + return service.ctx.handlePreImport() + } + public isSupport() { + return enableLang.includes(this.codeLang) + } + public execTest(testCase: TestCase) { + return this.ctx.execTest(testCase) + } + public debugCodeCommand(folder: vscode.WorkspaceFolder, breaks: vscode.SourceBreakpoint[]) { + return this.ctx.debugCodeCommand(folder, breaks) + } + public buildCode() { + return this.ctx.buildCode() + } + public getTestCaseList(text: string) { + return this.ctx.getTestCaseList(text) + } + public addComment(text, comment, funcName) { + return this.ctx.addComment(text, comment, funcName) + } +} diff --git a/src/lang/cpp.ts b/src/lang/cpp.ts new file mode 100644 index 0000000000000000000000000000000000000000..6effdb80839172e612684121f6cbe6ecd2a95af6 --- /dev/null +++ b/src/lang/cpp.ts @@ -0,0 +1,421 @@ +import * as cp from 'child_process' +import { pathExists, ensureFile, copy } from 'fs-extra' +import { CaseList, writeFileAsync } from '../common/util' +import { tag } from 'pretty-tag' +import { promisify } from 'util' +import * as vscode from 'vscode' +import * as path from 'path' +import { BaseLang } from './base' +import { defaultTimeout, LanguageMetaData } from '../common/lang' +const execFileAsync = promisify(cp.execFile) +const GCC = 'g++' +let hasCopy = false +const langTypeMap: Record = { + integer: 'int', + string: 'string', + boolean: 'bool', + 'integer[]': 'vector', + 'string[]': 'vector', + 'integer[][]': 'vector>', + double: 'double', + ListNode: 'ListNode *', + TreeNode: 'TreeNode *', + 'ListNode[]': 'vector', + 'TreeNode[]': 'vector', + 'character[][]': 'vector>', + 'string[][]': 'vector>', + 'list': 'vector', + 'list': 'vector', + 'list>': 'vector>', + 'list>': 'vector>', + 'list': 'vector', + 'list': 'vector', + 'character': 'char', + 'character[]': 'vector', + 'long': 'int', + 'long[]': 'vector', + 'long[][]': 'vector>' +} + +export class CppParse extends BaseLang { + // static preImport: string = 'package main' + static getPreImport() { + return tag` + #include + #include + #include + #include "algm/algm.h" + using namespace std; + ` + } + funcRegExp = /^(\s*class Solution)/ + testRegExp = /\/\/\s*@test\(((?:"(?:\\.|[^"])*"|[^)])*)\)/ + private cwd: string + private mainFilePath: string + constructor(public filePath: string, public text?: string) { + super(filePath, text) + this.cwd = path.join(filePath, '..', '..') + this.mainFilePath = path.join('main', 'main.cpp') + } + handleParam(index: number, paramType: string): string { + const langType = langTypeMap[paramType] + if (!langType) { + throw new Error('not support param type:' + paramType) + } + const handleConfig = [ + { + type: 'integer', + handleFn: 'parseInteger', + }, + { + type: 'string', + handleFn: 'parseString', + }, + { + type: 'integer[]', + handleFn: 'parseIntegerArr', + }, + { + type: 'string[]', + handleFn: 'parseStringArr', + }, + { + type: 'integer[][]', + handleFn: 'parseIntegerArrArr', + }, + { + type: 'double', + handleFn: 'parseFloat', + }, + { + type: 'ListNode', + handleFn: 'parseListNode', + }, + { + type: 'TreeNode', + handleFn: 'parseTreeNode', + }, + { + type: 'ListNode[]', + handleFn: 'parseListNodeArr', + }, + { + type: 'TreeNode[]', + handleFn: 'parseTreeNodeArr', + }, + + { + type: 'string[][]', + handleFn: 'parseStringArrArr', + }, + { + type: 'list', + handleFn: 'parseStringArr', + }, + { + type: 'list>', + handleFn: 'parseStringArrArr', + }, + { + type: 'list', + handleFn: 'parseIntegerArr', + }, + { + type: 'list>', + handleFn: 'parseIntegerArrArr', + }, + { + type: 'character', + handleFn: 'parseChar' + }, { + type: 'character[]', + handleFn: 'parseCharArr' + }, + { + type: 'character[][]', + handleFn: 'parseCharArrArr', + }, + ] + for (const { type, handleFn } of handleConfig) { + if (type === paramType) { + return `${langType} arg${index} = ${handleFn}(args[${index}]);` + } + } + throw new Error(`paramType ${paramType} not support`) + } + handleReturn(paramCount: number, funcName: string, returnType: string, firstParamType: string): string { + const isVoid = returnType === 'void' + if (isVoid) { + returnType = firstParamType + } + const langType = langTypeMap[returnType] + if (!langType) { + throw new Error('not support return type:' + returnType) + } + const handleConfig = [ + { + type: 'integer', + handleFn: 'serializeInteger', + }, + { + type: 'string', + handleFn: 'serializeString', + }, + { + type: 'double', + handleFn: 'serializeFloat', + }, + { + type: 'boolean', + handleFn: 'serializeBool', + }, + { + type: 'ListNode', + handleFn: 'serializeListNode', + }, + { + type: 'TreeNode', + handleFn: 'serializeTreeNode', + }, + { + type: 'integer[]', + handleFn: 'serializeIntegerArr', + }, + { + type: 'list', + handleFn: 'serializeIntegerArr', + }, + { + type: 'string[]', + handleFn: 'serializeStringArr', + }, + { + type: 'list', + handleFn: 'serializeStringArr', + }, + { + type: 'ListNode[]', + handleFn: 'serializeListNodeArr', + }, + { + type: 'TreeNode[]', + handleFn: 'serializeTreeNodeArr', + }, + { + type: 'integer[][]', + handleFn: 'serializeIntegerArrArr', + }, + { + type: 'list>', + handleFn: 'serializeIntegerArrArr', + }, + { + type: 'string[][]', + handleFn: 'serializeStringArrArr', + }, + { + type: 'list>', + handleFn: 'serializeStringArrArr', + }, + { + type: 'character', + handleFn: 'serializeChar', + }, { + type: 'character[]', + handleFn: 'serializeCharArr' + }, { + type: 'character[][]', + handleFn: 'serializeCharArrArr' + }, { + type: 'long', + handleFn: 'serializeInteger' + }, { + type: 'long[]', + handleFn: 'serializeIntegerArr' + }, { + type: 'long[][]', + handleFn: 'serializeIntegerArrArr', + } + ] + const argStr = Array(paramCount) + .fill(0) + .map((_, i) => `arg${i}`) + .join(',') + + for (const { type, handleFn } of handleConfig) { + if (type === returnType) { + if (!isVoid) { + const funcExpression = tag` + ${langType} result=s->${funcName}(${argStr}); + string resultabc =${handleFn}(result); + ` + return funcExpression + } else { + const funcExpression = tag` + s->${funcName}(${argStr}); + string resultabc =${handleFn}(arg0); + ` + return funcExpression + } + } + } + throw new Error(`returnType ${returnType} not support`) + } + + async handleArgsType(argsStr: string) { + const meta = (await this.getQuestionMeta()) as LanguageMetaData | undefined + if (!meta) { + throw new Error('question meta not found') + } + const params = meta.params || [] + const rt = meta.return.type + const funcName = meta.name + const argExpressions: string[] = [] + const paramCount = params.length + for (let i = 0; i < paramCount; i++) { + const { type } = params[i] + argExpressions[i] = this.handleParam(i, type) + } + + const name = path.parse(this.filePath).name + const argExpression = argExpressions.join('\n') + const rtExpression = this.handleReturn(paramCount, funcName, rt, params[0].type) + + return tag` + #include "question/${name}.cpp" + #include "regex" + #include "algm/parse.h" + int main(int argc, char *argv[]) + { + string str = "${argsStr}"; + vector> arr = parseStringArrArr(str); + for (int i = 0; i < arr.size(); i++) + { + vector args = arr[i]; + Solution *s = new Solution(); + ${argExpression} + ${rtExpression} + cout << "resultabc"+to_string(i)+":" << resultabc <<"resultend"<< endl; + } + return 0; + } + ` + } + + private async ensureCommonModuleFile() { + // const dir = config. + const algmDir = path.resolve(this.filePath, '..', '..', 'algm') + // const files = await readdirAsync(algmDir) + const sourceDir = path.resolve(__dirname, '..', '..', 'template', 'cpp') + const names = ['algm.h', 'ListNode.h', 'TreeNode.h', 'parse.h'] + + await Promise.all( + names.map(async (name) => { + const src = path.join(sourceDir, name) + const dst = path.join(algmDir, name) + const isExist = await pathExists(dst) + if (!hasCopy || !isExist) { + try { + await copy(src, dst, { overwrite: true }) + } catch (err) { + console.log(err) + } + + } + }) + ) + hasCopy = true + } + private getExecProgram() { + const cwd = this.cwd + return path.join(cwd, 'main', 'main') + } + async runMultiple(caseList: CaseList, _originCode: string, _funcName: string) { + const argsArr = caseList.map((v) => v.args) + const argsStr = JSON.stringify(argsArr) + await this.buildMainFile(argsStr) + const cwd = this.cwd + + const execProgram = this.getExecProgram() + const p = execFileAsync(execProgram, { + cwd: cwd, + timeout: defaultTimeout + }) + return this.waitExecTest(p, caseList) + } + async runInNewContext(_args: string[], _originCode: string, _funcName: string) { + return '' + } + async handlePreImport() { + await this.ensureCommonModuleFile() + return + } + + // do some thing before debug,eg. get testcase + async beforeDebug(breaks: vscode.SourceBreakpoint[]) { + const args = await this.resolveArgsFromBreaks(breaks) + const str = JSON.stringify([args]) + await this.buildMainFile(str) + } + async buildMainFile(argsStr: string) { + argsStr = argsStr.replace(/\\|"/g, (s) => `\\${s}`) + await this.writeTestCase(argsStr) + const cwd = this.cwd + const mainFilePath = this.mainFilePath + await execFileAsync(GCC, ['-I', '.', '-g', mainFilePath, '"-std=c++17"', '-o', 'main/main'], { cwd: cwd, shell: true }) + } + private getTestFilePath() { + const cwd = this.cwd + const testFilePath = path.join(cwd, 'main', 'main.cpp') + return testFilePath + } + async writeTestCase(argsStr: string) { + await this.ensureCommonModuleFile() + const finalCode = await this.handleArgsType(argsStr) + const testFilePath = this.getTestFilePath() + await ensureFile(testFilePath) + await writeFileAsync(testFilePath, finalCode) + } + async getDebugConfig(_breaks: vscode.SourceBreakpoint[]) { + const cwd = this.cwd + const execProgram = this.getExecProgram() + // for m1 + if (process.platform === 'darwin' && process.arch === 'arm64') { + return { + "name": "clang++ - Build and debug active file", + "type": "lldb", + "request": "launch", + "program": execProgram, + "args": [], + "stopAtEntry": true, + "cwd": cwd, + "environment": [], + "externalConsole": false, + "MIMode": "lldb", + } + } + return { + name: 'g++ - Build and debug active file', + type: 'cppdbg', + request: 'launch', + program: execProgram, + args: [], + stopAtEntry: false, + cwd: cwd, + environment: [], + externalConsole: false, + MIMode: 'gdb', + setupCommands: [ + { + description: 'Enable pretty-printing for gdb', + text: '-enable-pretty-printing', + ignoreFailures: true, + }, + ], + } + + } + shouldRemoveInBuild(line: string): boolean { + return line.trim().startsWith('#include "algm/algm.h"') + } +} diff --git a/src/lang/database.ts b/src/lang/database.ts new file mode 100644 index 0000000000000000000000000000000000000000..1b220de19e51226dc89718091b144353bb95f8a9 --- /dev/null +++ b/src/lang/database.ts @@ -0,0 +1,45 @@ +import { log } from '../config' +import { OutputChannel } from 'vscode' +import { readFileAsync } from '../common/util' +import { getFuncNames } from '../common/util' + +export class DataBaseParse { + public log: OutputChannel + public originCode?: string + public commentToken = '#' + constructor(public filePath: string, public text?: string) { + this.log = log + if (!filePath) { + throw new Error('filePath must not empty') + } + if (text) { + this.originCode = text + } + } + async getOriginCode() { + if (this.originCode) { + return this.originCode + } + const originCode = await readFileAsync(this.filePath, { + encoding: 'utf8', + }) + this.originCode = originCode + return this.originCode + } + public async buildCode() { + const originCode = await this.getOriginCode() + const { questionMeta } = getFuncNames(originCode, this.filePath) + + const code = originCode + .split('\n') + .filter((line) => !this.isComment(line)) + .join('\n') + return { + code, + questionMeta, + } + } + isComment(line: string): boolean { + return line.trim().startsWith('#') + } +} diff --git a/src/lang/golang.ts b/src/lang/golang.ts new file mode 100644 index 0000000000000000000000000000000000000000..7e5996895292816048d5dedc408e7f7a089c501c --- /dev/null +++ b/src/lang/golang.ts @@ -0,0 +1,358 @@ +import * as cp from 'child_process' +import { pathExists, ensureFile, copy, ensureDir } from 'fs-extra' +import { CaseList, writeFileAsync } from '../common/util' +import { tag } from 'pretty-tag' +import { promisify } from 'util' +import * as vscode from 'vscode' +import * as path from 'path' +import { BaseLang } from './base' +import { platform } from 'os' +import { defaultTimeout, LanguageMetaData } from '../common/lang' + +const execFileAsync = promisify(cp.execFile) + +export class GoParse extends BaseLang { + static getPreImport() { + return 'package main' + } + funcRegExp = /^(\s*func)/ + testRegExp = /\/\/\s*@test\(((?:"(?:\\.|[^"])*"|[^)])*)\)/ + private cwd: string + constructor(public filePath: string, public text?: string) { + super(filePath, text) + this.cwd = path.dirname(filePath) + } + + handleParam(index: number, paramType: string): string { + const handleConfig = [ + { + type: 'integer', + handleFn: 'parseInteger', + }, + { + type: 'string', + handleFn: 'parseString', + }, { + type: 'character', + handleFn: 'parseChar', + }, + { + type: 'integer[]', + handleFn: 'parseIntegerArr', + }, + { + type: 'character[]', + handleFn: 'parseCharArr' + }, + { + type: 'character[][]', + handleFn: 'parseCharArrArr' + }, + { + type: 'string[]', + handleFn: 'parseStringArr', + }, + { + type: 'integer[][]', + handleFn: 'parseIntegerArrArr', + }, + { + type: 'double', + handleFn: 'parseFloat', + }, + { + type: 'ListNode', + handleFn: 'deserializeListNode', + }, + { + type: 'TreeNode', + handleFn: 'deserializeTreeNode', + }, + { + type: 'ListNode[]', + handleFn: 'deserializeListNodeArr', + }, + { + type: 'TreeNode[]', + handleFn: 'deserializeTreeNodeArr', + }, + { + type: 'string[][]', + handleFn: 'parseStringArrArr', + }, + { + type: 'long', + handleFn: 'parseInteger' + }, { + type: 'long[]', + handleFn: 'parseIntegerArr' + }, { + type: 'long[][]', + handleFn: 'parseIntegerArrArr' + } + ] + for (const { type, handleFn } of handleConfig) { + if (type === paramType) { + return `arg${index} := ${handleFn}(unitArgs[${index}]);` + } + } + throw new Error(`paramType ${paramType} not support`) + } + handleReturn(paramCount: number, funcName: string, returnType: string, firstParamType: string): string { + const isVoid = returnType === 'void' + if (isVoid) { + returnType = firstParamType + } + + const handleConfig = [ + { + type: 'integer', + handleFn: 'serializeInterface', + }, + { + type: 'string', + handleFn: 'serializeInterface', + }, + { + type: 'character', + handleFn: 'serializeChar', + }, + { + type: 'double', + handleFn: 'serializeFloat', + }, + { + type: 'boolean', + handleFn: 'serializeInterface', + }, + { + type: 'ListNode', + handleFn: 'serializeListNode', + }, + { + type: 'TreeNode', + handleFn: 'serializeTreeNode', + }, + { + type: 'integer[]', + handleFn: 'serializeInterface', + }, + { + type: 'list', + handleFn: 'serializeInterface', + }, + { + type: 'string[]', + handleFn: 'serializeInterface', + }, + { + type: 'list', + handleFn: 'serializeInterface', + }, + { + type: 'ListNode[]', + handleFn: 'serializeListNodeArr', + }, + { + type: 'TreeNode[]', + handleFn: 'serializeTreeNodeArr', + }, + { + type: 'integer[][]', + handleFn: 'serializeInterface', + }, + { + type: 'list>', + handleFn: 'serializeInterface', + }, + { + type: 'character[][]', + handleFn: 'serializeCharArrArr', + }, + { + type: 'string[][]', + handleFn: 'serializeInterface', + }, + { + type: 'list>', + handleFn: 'serializeInterface', + }, { + type: 'character[]', + handleFn: 'serializeCharArr' + }, { + type: 'long', + handleFn: 'serializeInterface', + }, + { + type: 'long[]', + handleFn: 'serializeInterface', + }, + { + type: 'long[][]', + handleFn: 'serializeInterface', + }, + ] + const argStr = Array(paramCount) + .fill(0) + .map((_v, i) => `arg${i}`) + .join(',') + + for (const { type, handleFn } of handleConfig) { + if (type === returnType) { + if (!isVoid) { + const funcExpression = tag` + result := ${funcName}(${argStr}); + resultabc :=${handleFn}(result); + ` + return funcExpression + } else { + const funcExpression = tag` + ${funcName}(${argStr}) + resultabc := ${handleFn}(arg0); + ` + return funcExpression + } + } + } + throw new Error(`returnType ${returnType} not support`) + } + async handleArgsType(argsStr: string) { + const meta = (await this.getQuestionMeta()) as LanguageMetaData | undefined + if (!meta) { + throw new Error('question meta not found') + } + const params = meta.params || [] + const rt = meta.return.type + const funcName = meta.name + const argExpressions: string[] = [] + const paramCount = params.length + for (let i = 0; i < paramCount; i++) { + const { type } = params[i] + argExpressions[i] = this.handleParam(i, type) + } + + const argExpression = argExpressions.join('\n') + const rtExpression = this.handleReturn(paramCount, funcName, rt, params[0].type) + + return tag` + package main + import "fmt" + func main(){ + str := "${argsStr}" + arr := parseStringArrArr(str) + for i:=0;i v.args) + const argsStr = JSON.stringify(argsArr) + await this.buildMainFile(argsStr) + const mainFile = this.getExecProgram() + const cwd = this.cwd + + const p = execFileAsync(mainFile, { + cwd: cwd, + timeout: defaultTimeout + }) + return this.waitExecTest(p, caseList) + } + private async ensureModFile() { + const cwd = this.cwd + const modName = 'lc' + path.parse(cwd).name + const modPath = path.join(cwd, 'go.mod') + const isExist = await pathExists(modPath) + const goPath = 'go' + + if (!isExist) { + await ensureDir(cwd) + try { + await execFileAsync(goPath, ['mod', 'init', modName], { + cwd: cwd, + shell: true, + }) + } catch (err) { + console.log(err) + } + } + } + async ensureCommonModuleFile() { + const algmDir = this.cwd + const sourceDir = path.resolve(__dirname, '..', '..', 'template', 'golang') + const names = ['algm.go'] + + await Promise.all( + names.map(async (name) => { + const src = path.join(sourceDir, name) + const dst = path.join(algmDir, name) + const isExist = await pathExists(dst) + if (!isExist) { + return copy(src, dst) + } + }) + ) + } + async buildMainFile(argsStr: string) { + await this.writeTestCase(argsStr) + const goPath = 'go' + const cwd = this.cwd + let outFile = 'main' + if (platform() === 'win32') { + outFile = 'main.exe' + } + await execFileAsync(goPath, ['build', '-o', outFile, '.'], { + cwd: cwd, + shell: true, + }) + } + async runInNewContext(_args: string[], _originCode: string, _funcName: string) { + return '' + } + async handlePreImport() { + await this.ensureModFile() + await this.ensureCommonModuleFile() + return + } + // do some thing before debug,eg. get testcase + async beforeDebug(breaks: vscode.SourceBreakpoint[]) { + const args = await this.resolveArgsFromBreaks(breaks) + const str = JSON.stringify([args]) + await this.writeTestCase(str) + } + getTestFilePath() { + const cwd = this.cwd + return path.join(cwd, 'main.go') + } + async writeTestCase(argsStr: string) { + argsStr = argsStr.replace(/\\|"/g, (s) => `\\${s}`) + const finalCode = await this.handleArgsType(argsStr) + const testFilePath = this.getTestFilePath() + await ensureFile(testFilePath) + await writeFileAsync(testFilePath, finalCode) + } + + getDebugConfig() { + const dir = path.parse(this.filePath).dir + return { + name: 'Launch Package', + type: 'go', + request: 'launch', + mode: 'debug', + program: dir, + } + } + shouldRemoveInBuild(line: string): boolean { + const preImportStr = GoParse.getPreImport() + return line.trim().startsWith(preImportStr) + } +} diff --git a/src/lang/java.ts b/src/lang/java.ts new file mode 100644 index 0000000000000000000000000000000000000000..021a0a1af398d1f5b78c428ba92e5c27204fcb3e --- /dev/null +++ b/src/lang/java.ts @@ -0,0 +1,385 @@ +import * as cp from 'child_process' +import { pathExists, ensureFile, copy } from 'fs-extra' +import { CaseList, writeFileAsync } from '../common/util' +import { tag } from 'pretty-tag' +import { config } from '../config' +import { promisify } from 'util' +import * as vscode from 'vscode' +import * as path from 'path' +import { ExtraType } from '../common/langConfig' +import { BaseLang } from './base' +import { defaultTimeout, LanguageMetaData } from '../common/lang' +let hasCopy = false +const execFileAsync = promisify(cp.execFile) +const langTypeMap = { + integer: 'int', + string: 'String', + 'integer[]': 'int[]', + 'string[]': 'String[]', + 'integer[][]': 'int[][]', + double: 'double', + ListNode: 'ListNode', + TreeNode: 'TreeNode', + 'ListNode[]': 'ListNode[]', + 'TreeNode[]': 'TreeNode[]', + 'character[][]': 'char[][]', + 'string[][]': 'String[][]', + 'list': 'List', + 'list': 'List', + 'list>': 'List>', + 'list>': 'List>', + 'list': 'ListNode[]', + 'list': 'TreeNode[]', + boolean: 'boolean', + character: 'char', + 'character[]': 'char[]' + +} + +export class JavaParse extends BaseLang { + // static preImport: string = 'package main' + static getPreImport(name: string, extraTypeSet: Set) { + let importStr = '' + if (extraTypeSet.size) { + importStr = 'import algm.*;' + } + return tag` + package ${name}; + ${importStr} + ` + } + funcRegExp = /^(\s*(public)? class Solution)/ + testRegExp = /\/\/\s*@test\(((?:"(?:\\.|[^"])*"|[^)])*)\)/ + private cwd: string + constructor(public filePath: string, public text?: string) { + super(filePath, text) + this.cwd = path.join(filePath, '..', '..') + } + + handleParam(index: number, paramType: string): string { + const langType = langTypeMap[paramType] + if (!langType) { + throw new Error('not support param type:' + paramType) + } + const handleConfig = [ + { + type: 'integer', + handleFn: 'parseInteger', + }, + { + type: 'string', + handleFn: 'parseString', + }, + { + type: 'integer[]', + handleFn: 'parseIntegerArr', + }, + { + type: 'string[]', + handleFn: 'parseStringArr', + }, + { + type: 'integer[][]', + handleFn: 'parseIntegerArrArr', + }, + { + type: 'double', + handleFn: 'parseFloat', + }, + { + type: 'ListNode', + handleFn: 'parseListNode', + }, + { + type: 'TreeNode', + handleFn: 'parseTreeNode', + }, + { + type: 'ListNode[]', + handleFn: 'parseListNodeArr', + }, + { + type: 'TreeNode[]', + handleFn: 'parseTreeNodeArr', + }, + + { + type: 'string[][]', + handleFn: 'parseStringArrArr', + }, + { + type: 'list', + handleFn: 'parseIntegerList', + }, + { + type: 'list>', + handleFn: 'parseIntegerListList', + }, + { + type: 'list', + handleFn: 'parseStringList', + }, + { + type: 'list>', + handleFn: 'parseStringListList', + }, + { + type: 'character', + handleFn: 'parseChar', + }, + { + type: 'character[]', + handleFn: 'parseCharArr' + }, + { + type: 'character[][]', + handleFn: 'parseCharArrArr' + }, + ] + for (const { type, handleFn } of handleConfig) { + if (type === paramType) { + return `${langType} arg${index} = Util.${handleFn}(unitArgs[${index}]);` + } + } + throw new Error(`paramType ${paramType} not support`) + } + handleReturn(paramCount: number, funcName: string, returnType: string, firstParamType: string): string { + const isVoid = returnType === 'void' + if (isVoid) { + returnType = firstParamType + } + const langType = langTypeMap[returnType] + if (!langType) { + throw new Error('not support return type:' + returnType) + } + const handleConfig = [ + { + type: 'integer', + handleFn: 'serializeInteger', + }, + { + type: 'string', + handleFn: 'serializeString', + }, + { + type: 'double', + handleFn: 'serializeFloat', + }, + { + type: 'boolean', + handleFn: 'serializeBool', + }, + { + type: 'ListNode', + handleFn: 'serializeListNode', + }, + { + type: 'TreeNode', + handleFn: 'serializeTreeNode', + }, + { + type: 'integer[]', + handleFn: 'serializeIntegerArr', + }, + { + type: 'list', + handleFn: 'serializeIntegerList', + }, + { + type: 'string[]', + handleFn: 'serializeStringArr', + }, + { + type: 'list', + handleFn: 'serializeStringArr', + }, + { + type: 'ListNode[]', + handleFn: 'serializeListNodeArr', + }, + { + type: 'TreeNode[]', + handleFn: 'serializeTreeNodeArr', + }, + { + type: 'integer[][]', + handleFn: 'serializeIntegerArrArr', + }, + { + type: 'list>', + handleFn: 'serializeIntegerListList', + }, + { + type: 'string[][]', + handleFn: 'serializeStringArrArr', + }, + { + type: 'list', + handleFn: 'serializeStringList', + }, + { + type: 'list>', + handleFn: 'serializeStringListList', + }, + { + type: 'character', + handleFn: 'serializeChar', + }, + { + type: 'character[]', + handleFn: 'serializeCharArr' + }, + { + type: 'character[][]', + handleFn: 'serializeCharArrArr', + }, + ] + const argStr = Array(paramCount) + .fill(0) + .map((_v, i) => `arg${i}`) + .join(',') + + for (const { type, handleFn } of handleConfig) { + if (type === returnType) { + if (!isVoid) { + const funcExpression = tag` + ${langType} result=s.${funcName}(${argStr}); + String resultabc =Util.${handleFn}(result); + ` + return funcExpression + } else { + const funcExpression = tag` + s.${funcName}(${argStr}); + String resultabc =Util.${handleFn}(arg0); + ` + return funcExpression + } + } + } + throw new Error(`returnType ${returnType} not support`) + } + + async handleArgsType(argsStr: string) { + const meta = (await this.getQuestionMeta()) as LanguageMetaData | undefined + if (!meta) { + throw new Error('question meta not found') + } + const params = meta.params || [] + const rt = meta.return.type + const funcName = meta.name + const argExpressions: string[] = [] + const paramCount = params.length + for (let i = 0; i < paramCount; i++) { + const { type } = params[i] + argExpressions[i] = this.handleParam(i, type) + } + const dir = path.parse(path.parse(this.filePath).dir).name + + const argExpression = argExpressions.join('\n') + const rtExpression = this.handleReturn(paramCount, funcName, rt, params[0].type) + + return tag` + package test; + import ${dir}.*; + import algm.*; + import java.util.List; + public class Test { + public static void main(String[] args){ + String str="${argsStr}"; + String[][] arr = Util.parseStringArrArr(str); + + for(int i=0;i { + const src = path.join(sourceDir, name) + const dst = path.join(algmDir, name) + const isExist = await pathExists(dst) + if (!hasCopy || !isExist) { + return copy(src, dst) + } + }) + ) + hasCopy = true + } + async runMultiple(caseList: CaseList, _originCode: string, _funcName: string) { + const argsArr = caseList.map((v) => v.args) + const argsStr = JSON.stringify(argsArr) + await this.buildMainFile(argsStr) + const javaPath = config.javaPath + const cwd = this.cwd + const p = execFileAsync(javaPath, [`test/Test`], { + cwd: cwd, + timeout: defaultTimeout + }) + return this.waitExecTest(p, caseList) + } + async runInNewContext(_args: string[], _originCode: string, _funcName: string) { + return '' + } + async handlePreImport() { + await this.ensureCommonModuleFile() + return + } + // do some thing before debug,eg. get testcase + async beforeDebug(breaks: vscode.SourceBreakpoint[]) { + const args = await this.resolveArgsFromBreaks(breaks) + const str = JSON.stringify([args]) + await this.writeTestCase(str) + } + private getTestFilePath() { + const cwd = this.cwd + const testFilePath = path.join(cwd, 'test', 'Test.java') + return testFilePath + } + async writeTestCase(argsStr: string) { + argsStr = argsStr.replace(/\\|"/g, (s) => `\\${s}`) + await this.ensureCommonModuleFile() + const finalCode = await this.handleArgsType(argsStr) + const testFilePath = this.getTestFilePath() + await ensureFile(testFilePath) + await writeFileAsync(testFilePath, finalCode) + } + async buildMainFile(argsStr: string) { + await this.writeTestCase(argsStr) + const javacPath = config.javacPath + const cwd = this.cwd + await execFileAsync(javacPath, [`test/Test.java`], { + cwd: cwd, + shell: true, + }) + } + async getDebugConfig(_breaks: vscode.SourceBreakpoint[]) { + const testFilePath = this.getTestFilePath() + const cwd = this.cwd + return { + type: 'java', + name: 'Launch Current File', + request: 'launch', + mainClass: testFilePath, + cwd: cwd, + args: '', + } + } + shouldRemoveInBuild(line: string): boolean { + line = line.trim() + return line.startsWith('package') || line.startsWith('import algm') + } +} diff --git a/src/lang/javascript.ts b/src/lang/javascript.ts new file mode 100644 index 0000000000000000000000000000000000000000..6fedd8f999edf7738a87da527ecdb9c2010e51bc --- /dev/null +++ b/src/lang/javascript.ts @@ -0,0 +1,135 @@ +import { CaseList, getFuncNames, readFileAsync } from '../common/util' +import { config } from '../config' +import * as vscode from 'vscode' +import { BaseLang } from './base' +import { execTestChildProcess } from '../execTestCode' +import { TestOptions, LanguageMetaData, DebugOptions } from '../common/lang' +import { main } from '../debugTask/index' +import path = require('path') +import { outBoundArrayPlugin } from '../babelPlugin' +import babel = require('@babel/core') +import rollup = require('rollup') +import resolve from '@rollup/plugin-node-resolve' +import rollupBabelPlugin from '@rollup/plugin-babel' +import { window } from 'vscode' +import { addComment } from '../common/transformCode' +const virtual = require('@rollup/plugin-virtual') +export class JavascriptParse extends BaseLang { + static getPreImport() { + return '' + } + funcRegExp = /^(?:(\s*function)|(.*=\s*function))/ + testRegExp = /\/\/\s*@test\(((?:"(?:\\.|[^"])*"|[^)])*)\)/ + + async runMultiple(caseList: CaseList, originCode: string, _funcName: string) { + const metaData = (await this.getQuestionMeta()) as LanguageMetaData | undefined + if (!metaData) { + throw new Error('question meta not found') + } + const options: TestOptions = { + caseList, + originCode, + filePath: this.filePath, + metaData: metaData, + } + return await execTestChildProcess(options) + } + + shouldRemoveInBuild(_line: string): boolean { + return false + } + + async runInNewContext(_args: string[], _originCode: string, _funcName: string) { + return '' + } + async handlePreImport() { + return + } + async buildCode() { + try { + const filePath = this.filePath + const text = this.text! + const dir = path.parse(filePath).dir + const { funcNames, questionMeta } = getFuncNames(text, filePath) + const funcRunStr = 'console.log(' + funcNames.map((f) => f + '()').join('+') + ')' + // The rollup will not transform code in virtual entry + const entry: babel.BabelFileResult | null = await babel.transformAsync(text, { + comments: false, + compact: false, + plugins: [outBoundArrayPlugin], + }) + const entryCode = entry?.code + `\n${funcRunStr}` + const bundle = await rollup.rollup({ + input: 'entry', + + treeshake: true, + plugins: [ + // It use virtual entry because treeshake will remove unuse code. + virtual({ + entry: entryCode, + }), + resolve({ rootDir: dir }), + rollupBabelPlugin({ + babelHelpers: 'bundled', + comments: false, + shouldPrintComment: () => false, + }), + ], + }) + const { output } = await bundle.generate({}) + let code = output[0].code + code = code.replace(funcRunStr, '').replace(/;\s*$/, '') + return { + code, + questionMeta, + } + } catch (err) { + console.log('err:', err) + window.showInformationMessage(`parse params err: ${err}`) + return { + code: '', + questionMeta: {}, + } + } + } + // do some thing before debug,eg. get testcase + async beforeDebug(breaks: vscode.SourceBreakpoint[]) { + const args = await this.resolveArgsFromBreaks(breaks) + const metaData = (await this.getQuestionMeta()) as LanguageMetaData | undefined + if (!metaData) { + throw new Error('question meta not found') + } + const originCode = await readFileAsync(this.filePath, { + encoding: 'utf8', + }) + const options: DebugOptions = { + originCode, + filePath: this.filePath, + metaData: metaData, + } + await this.writeTestCase(options, args) + } + async writeTestCase(options: DebugOptions, args: string[]) { + return main(options, args) + } + getDebugConfig() { + const { nodeBinPath } = config + + return { + type: 'node', + request: 'launch', + name: 'debug question', + skipFiles: ['/**'], + program: '${workspaceFolder}/out/code.js', + outFiles: ['${workspaceFolder}/out/*.js'], + runtimeVersion: 'default', + runtimeExecutable: nodeBinPath, + sourceMaps: true, + args: ['${file}'], + // "preLaunchTask": "algorithm: build" + } + } + public addComment(text: string, comment: string, funcName: string) { + return addComment(text, comment, funcName) + } +} diff --git a/src/lang/python.ts b/src/lang/python.ts new file mode 100644 index 0000000000000000000000000000000000000000..ebcd3926fab6c4b57e3b607c3a76c23ad80e3e71 --- /dev/null +++ b/src/lang/python.ts @@ -0,0 +1,390 @@ +import * as cp from 'child_process' +import { pathExists, ensureFile } from 'fs-extra' +import { CaseList, writeFileAsync } from '../common/util' +import { tag } from 'pretty-tag' +import { config } from '../config' +import { promisify } from 'util' +import * as vscode from 'vscode' +import * as path from 'path' +import { BaseLang } from './base' +import { platform } from 'os' +import { LanguageMetaData, defaultTimeout } from '../common/lang' +const execFileAsync = promisify(cp.execFile) + +export class PythonParse extends BaseLang { + static getPreImport() { + const lang = config.lang + const codeLang = config.codeLang + + return `from ${lang}.${codeLang}.mod.preImport import *` + } + private cwd: string + funcRegExp = /^(\s*class Solution)/ + testRegExp = /#\s*@test\(((?:"(?:\\.|[^"])*"|[^)])*)\)/ + handleTypeCode = tag` + class TreeNode: + def __init__(self, val=0, left=None, right=None): + self.val = val + self.left = left + self.right = right + class ListNode: + def __init__(self, val=0, next=None): + self.val = val + self.next = next + def serializeListNode(head:ListNode): + if(head==None): + return [] + node=head + arr=[] + while(node!=None): + arr.append(str(node.val)) + node=node.next + return '['+','.join(arr)+']' + def parseListNode(arr)->ListNode: + header=ListNode() + node=header + for num in arr: + node.next=ListNode(num) + node=node.next + return header.next + + def serializeTreeNode(root:TreeNode): + if(root==None): + return [] + arr=[] + queue=[root] + while(len(queue)>0): + node=queue.pop(0) + if node!=None: + arr.append(str(node.val)) + queue.append(node.left) + queue.append(node.right) + else: + arr.append("null") + i=len(arr)-1 + while(arr[i]=="null"): + i=i-1 + arr.pop() + return '['+','.join(arr)+']' + def parseTreeNode(arr)->TreeNode: + if(len(arr)==0): + return None + val=arr.pop(0) + root=TreeNode(val) + queue=[root] + while(queue): + node=queue.pop(0) + if len(arr)==0: + return root + leftVal=arr.pop(0) + if leftVal!=None: + left=TreeNode(leftVal) + node.left=left + queue.append(left) + if len(arr)==0: + return root + rightVal=arr.pop(0) + if rightVal!=None: + right=TreeNode(rightVal) + node.right=right + queue.append(right) + return root + def parseTreeNodeArr(arr): + out=[] + for item in arr: + treeNode=parseTreeNode(item) + out.append(treeNode) + return out + def serializeTreeNodeArr(arr): + treeNodeStrArr=[] + for item in arr: + treeNodeStrArr.append(serializeTreeNode(item)) + return '['+','.join(treeNodeStrArr)+']' + def parseListNodeArr(arr): + out=[] + for item in arr: + listNode=parseListNode(item) + out.append(listNode) + return out + def serializeListNodeArr(arr): + listNodeStrArr=[] + for item in arr: + listNodeStrArr.append(serializeListNode(item)) + return '['+','.join(listNodeStrArr)+']' + def serializeFloat(param): + r=str(param) + arr=r.split(".") + if len(arr)==1: + return r+".00000" + else: + decimalStr=arr[1]+"00000" + return arr[0]+"."+decimalStr[0:5] + ` + + constructor(public filePath: string, public text?: string) { + super(filePath, text) + this.cwd = path.join(config.algDir, 'Python3') + } + + handleParam(index: number, paramType: string): string { + const handleConfig = [ + { + type: 'ListNode', + handleFn: 'parseListNode', + }, + { + type: 'TreeNode', + handleFn: 'parseTreeNode', + }, + { + type: 'ListNode[]', + handleFn: 'parseListNodeArr', + }, + { + type: 'TreeNode[]', + handleFn: 'parseTreeNodeArr', + }, + ] + const jsonType = [ + 'integer', + 'string', + 'integer[]', + 'string[]', + 'integer[][]', + 'string[][]', + 'list', + 'list', + 'list>', + 'list>', + 'character[][]', + 'boolean', + 'double', + 'character', + 'character[]', + 'long', + 'long[]', + 'long[][]' + ] + if (jsonType.includes(paramType)) { + return `arg${index} = unitArgs[${index}]` + } else { + for (const { type, handleFn } of handleConfig) { + if (type === paramType) { + return `arg${index} =${handleFn}(unitArgs[${index}])` + } + } + } + + throw new Error(`paramType ${paramType} not support`) + } + handleReturn(paramCount: number, funcName: string, returnType: string, firstParamType: string): string { + const isVoid = returnType === 'void' + if (isVoid) { + returnType = firstParamType + } + + const handleConfig = [ + { + type: 'ListNode', + handleFn: 'serializeListNode', + }, + { + type: 'TreeNode', + handleFn: 'serializeTreeNode', + }, + { + type: 'ListNode[]', + handleFn: 'serializeListNodeArr', + }, + { + type: 'TreeNode[]', + handleFn: 'serializeTreeNodeArr', + }, + { + type: 'double', + handleFn: 'serializeFloat', + }, + ] + const jsonType = [ + 'integer', + 'string', + 'integer[]', + 'string[]', + 'integer[][]', + 'string[][]', + 'list', + 'list', + 'list>', + 'list>', + 'character[][]', + 'boolean', + 'character', + 'character[]', + 'long', + 'long[]', + 'long[][]' + ] + + const argStr = Array(paramCount) + .fill(0) + .map((_v, i) => `arg${i}`) + .join(',') + if (jsonType.includes(returnType)) { + if (!isVoid) { + const funcExpression = tag` + result=s.${funcName}(${argStr}) + resultabc =json.dumps(result,separators=(',', ':')) + ` + return funcExpression + } else { + const funcExpression = tag` + s.${funcName}(${argStr}) + resultabc =json.dumps(arg0,separators=(',', ':')) + ` + return funcExpression + } + } else { + for (const { type, handleFn } of handleConfig) { + if (type === returnType) { + if (!isVoid) { + const funcExpression = tag` + result=s.${funcName}(${argStr}) + resultabc =${handleFn}(result) + ` + return funcExpression + } else { + const funcExpression = tag` + s.${funcName}(${argStr}) + resultabc =${handleFn}(arg0) + ` + return funcExpression + } + } + } + } + + throw new Error(`returnType ${returnType} not support`) + } + + async handleArgsType(argsStr: string) { + const meta = (await this.getQuestionMeta()) as LanguageMetaData | undefined + + if (!meta) { + throw new Error('question meta not found') + } + const params = meta.params || [] + const rt = meta.return.type + const funcName = meta.name + const argExpressions: string[] = [] + const paramCount = params.length + for (let i = 0; i < paramCount; i++) { + const { type } = params[i] + argExpressions[i] = this.handleParam(i, type) + } + const filePathParse = path.parse(this.filePath) + + const name = filePathParse.name + const argExpression = argExpressions.join('\n') + const rtExpression = this.handleReturn(paramCount, funcName, rt, params[0].type) + const cwd = this.cwd.replace(/\\/g, '\\\\') + const baseDir = config.baseDir.replace(/\\/g, '\\\\') + return tag` + import sys + import json + sys.path.append("${cwd}") + sys.path.append("${baseDir}") + a = __import__('${name}') + ${this.handleTypeCode} + + + arr=json.loads("${argsStr}") + for i in range(len(arr)): + unitArgs=arr[i] + s=a.Solution() + ${argExpression} + ${rtExpression} + print("resultabc"+str(i)+":"+resultabc+"resultend") + ` + } + async runMultiple(caseList: CaseList, _originCode: string, _funcName: string) { + const argsArr = caseList.map((v) => v.args.map((str) => JSON.parse(str))) + const argsStr = JSON.stringify(argsArr) + await this.buildMainFile(argsStr) + let pythonPath = 'python3' + if (platform() === 'win32') { + pythonPath = 'python' + } + const testFilePath = this.getTestFilePath() + const cwd = this.cwd + + const p = execFileAsync(pythonPath, [testFilePath], { + cwd: cwd, + timeout: defaultTimeout + }) + return this.waitExecTest(p, caseList) + } + async buildMainFile(argsStr: string) { + await this.writeTestCase(argsStr) + } + shouldRemoveInBuild(line: string): boolean { + const preImportStr = PythonParse.getPreImport() + return line.trimLeft().startsWith(preImportStr) + } + + async runInNewContext(_args: string[], _originCode: string, _funcName: string) { + return '' + } + async handlePreImport() { + const dir = config.questionDir + const preImportFile = path.join(dir, 'mod', 'preImport.py') + const exist = await pathExists(preImportFile) + if (exist) { + return + } else { + await ensureFile(preImportFile) + } + const data = tag` + from typing import List + class ListNode: + def __init__(self, val=0, next=None): + self.val = val + self.next = next + class TreeNode: + def __init__(self, val=0, left=None, right=None): + self.val = val + self.left = left + self.right = right + ` + if (!exist) { + await writeFileAsync(preImportFile, data, { encoding: 'utf8' }) + } + } + private getTestFilePath() { + const cwd = this.cwd + const testFilePath = path.join(cwd, 'out', 'out.py') + return testFilePath + } + // do some thing before debug,eg. get testcase + async beforeDebug(breaks: vscode.SourceBreakpoint[]) { + const args = await this.resolveArgsFromBreaks(breaks) + const str = JSON.stringify([args.map((v) => JSON.parse(v))]) + await this.writeTestCase(str) + } + async writeTestCase(argsStr: string) { + argsStr = argsStr.replace(/\\|"/g, (s) => `\\${s}`) + const finalCode = await this.handleArgsType(argsStr) + const testFilePath = this.getTestFilePath() + await ensureFile(testFilePath) + await writeFileAsync(testFilePath, finalCode) + } + getDebugConfig() { + const outputFile = path.join(this.cwd, 'out', 'out.py') + return { + name: 'Python: Current File (Integrated Terminal)', + type: 'python', + request: 'launch', + program: outputFile, + console: 'integratedTerminal', + } + } +} diff --git a/src/lang/typescript.ts b/src/lang/typescript.ts new file mode 100644 index 0000000000000000000000000000000000000000..d665d4736db5302c6605e7d45dcd9400864c3860 --- /dev/null +++ b/src/lang/typescript.ts @@ -0,0 +1,146 @@ +import { CaseList, getFuncNames, readFileAsync } from '../common/util' +import { config } from '../config' +import * as vscode from 'vscode' +import { BaseLang } from './base' +import { execTestChildProcess } from '../execTestCode' +import { TestOptions, LanguageMetaData, DebugOptions } from '../common/lang' +import { main } from '../debugTask/index' +import * as path from 'path' +import babel = require('@babel/core') +import presetTs = require('@babel/preset-typescript') +import { outBoundArrayPlugin } from '../babelPlugin' +import rollup = require('rollup') +import resolve from '@rollup/plugin-node-resolve' +import rollupBabelPlugin from '@rollup/plugin-babel' +import { window } from 'vscode' +import { addComment } from '../common/transformCode' +const virtual = require('@rollup/plugin-virtual') +export class TypescriptParse extends BaseLang { + static getPreImport() { + return '' + } + funcRegExp = /^(?:(\s*function)|(.*=\s*function))/ + testRegExp = /\/\/\s*@test\(((?:"(?:\\.|[^"])*"|[^)])*)\)/ + + async runMultiple(caseList: CaseList, originCode: string, _funcName: string) { + const metaData = (await this.getQuestionMeta()) as LanguageMetaData | undefined + if (!metaData) { + throw new Error('question meta not found') + } + const options: TestOptions = { + caseList, + originCode, + filePath: this.filePath, + metaData: metaData, + } + return await execTestChildProcess(options) + } + async buildCode() { + try { + const filePath = this.filePath + let text = this.text! + text = text + .split('\n') + .filter((line) => !this.shouldRemoveInBuild(line)) + .join('\n') + + const dir = path.parse(filePath).dir + const { funcNames, questionMeta } = getFuncNames(text, filePath) + const funcRunStr = 'console.log(' + funcNames.map((f) => f + '()').join('+') + ')' + // The rollup will not transform code in virtual entry + const entry: babel.BabelFileResult | null = await babel.transformAsync(text, { + filename: filePath, + comments: false, + compact: false, + presets: [presetTs], + plugins: [outBoundArrayPlugin], + }) + const entryCode = entry?.code + `\n${funcRunStr}` + const bundle = await rollup.rollup({ + input: 'entry', + + treeshake: true, + plugins: [ + // It use virtual entry because treeshake will remove unuse code. + virtual({ + entry: entryCode, + }), + + resolve({ rootDir: dir, modulesOnly: true }), + + rollupBabelPlugin({ + babelHelpers: 'bundled', + comments: false, + shouldPrintComment: () => false, + }), + ], + }) + const { output } = await bundle.generate({}) + let code = output[0].code + code = code.replace(funcRunStr, '').replace(/;\s*$/, '') + return { + code, + questionMeta, + } + } catch (err) { + console.log('err:', err) + window.showInformationMessage(`parse params err: ${err}`) + return { + code: '', + questionMeta: {}, + } + } + } + shouldRemoveInBuild(line: string): boolean { + return /import\s*{\s*(ListNode|TreeNode)\s*}\s*from\s*'algm'/.test(line.trimLeft()) + } + + async runInNewContext(_args: string[], _originCode: string, _funcName: string) { + return '' + } + async handlePreImport() { + return + } + + // do some thing before debug,eg. get testcase + async beforeDebug(breaks: vscode.SourceBreakpoint[]) { + const args = await this.resolveArgsFromBreaks(breaks) + const metaData = (await this.getQuestionMeta()) as LanguageMetaData | undefined + if (!metaData) { + throw new Error('question meta not found') + } + const originCode = await readFileAsync(this.filePath, { + encoding: 'utf8', + }) + const options: DebugOptions = { + originCode, + filePath: this.filePath, + metaData: metaData, + } + await this.writeTestCase(options, args) + } + async writeTestCase(options: DebugOptions, args: string[]) { + return main(options, args) + } + + getDebugConfig() { + const { nodeBinPath } = config + + return { + type: 'node', + request: 'launch', + name: 'debug question', + skipFiles: ['/**'], + program: '${workspaceFolder}/out/code.js', + outFiles: ['${workspaceFolder}/out/*.js'], + runtimeVersion: 'default', + runtimeExecutable: nodeBinPath, + sourceMaps: true, + args: ['${file}'], + // "preLaunchTask": "algorithm: build" + } + } + public addComment(text: string, comment: string, funcName: string) { + return addComment(text, comment, funcName) + } +} diff --git a/src/login/index.ts b/src/login/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..efe40d0299ff37ab67ebb08ef48b17ed666b4ac5 --- /dev/null +++ b/src/login/index.ts @@ -0,0 +1,230 @@ +import _request = require('request') +import { promisify } from 'util' +import { window } from 'vscode' +import { config, DomainCN, DomainEN } from '../config' +import { User } from './input' +import { writeFileAsync } from '../common/util' +import { signInCommand } from '../commands' + +function parseCookie(cookie: string) { + const keyValueStrArr = cookie.split(';') + const map = {} + keyValueStrArr.forEach((kvStr) => { + let [key, value] = kvStr.split('=') + key = key.trim() + value = value.trim() + map[key] = value + }) + return map +} + +async function saveCookie(cookie: string) { + const cookiePath = config.cookiePath + const map = parseCookie(cookie) + const headers = { cookie } + if (map['csrftoken']) { + headers['x-csrftoken'] = map['csrftoken'] + } + await writeFileAsync(cookiePath, JSON.stringify(headers)) +} +// set-cookie +async function saveResCookie(cookies: string[] = []) { + const map = {} + for (let i = 0; i < cookies.length; i++) { + const cookie = cookies[i] + const arr = cookie.split(';') + const kv = arr[0] + let [key, value] = kv.split('=') + key = key.trim() + if (key) { + map[key] = value + } + } + const cookieStr = Object.keys(map) + .map((key) => `${key}=${map[key]}`) + .join('; ') + const headers = { cookie: cookieStr } + if (map['csrftoken']) { + headers['x-csrftoken'] = map['csrftoken'] + } + const cookiePath = config.cookiePath + await writeFileAsync(cookiePath, JSON.stringify(headers)) +} +function parseFormData(html: string) { + const formRegExp = // + const r = formRegExp.exec(html.replace(/\n/g, '')) + if (!r) { + return Promise.reject({ + message: 'the page of login github not found', + code: 3, + }) + } + const formStr = r[0] + const inputRegExp = /]*name="(.*?)"(?:[^>](?!alue))*(?:value="(.*?)")?[^>]*>/g + let inputRegExpRes: RegExpExecArray | null = null + let d = {} + const defaultObj = { + 'webauthn-support': 'supported', + 'webauthn-iuvpaa-support': 'unsupported', + } + while ((inputRegExpRes = inputRegExp.exec(formStr))) { + const name = inputRegExpRes[1] + const value = inputRegExpRes[2] + if (name) { + d[name] = value || '' + } + } + d = Object.assign(d, defaultObj) + return d +} +type RequestAsync = ( + arg1: (_request.UriOptions & _request.CoreOptions) | (_request.UrlOptions & _request.CoreOptions) +) => Promise<_request.Response> +async function githubAuth(html: string, request: RequestAsync, user) { + let data = parseFormData(html) + data = Object.assign(data, { + login: user.name, + password: user.password, + }) + // github login and then redirect back + const res = await request({ + url: 'https://github.com/session', + form: data, + method: 'POST', + followAllRedirects: true, + headers: { + 'content-type': 'application/x-www-form-urlencoded', + }, + }) + let body = res.body + if (/Incorrect username or password/.test(body)) { + return Promise.reject({ + message: 'Incorrect username or password', + code: 3, + }) + } + // enable two-factor + const twoFactorRegExp = /Two-factor authentication/ + if (twoFactorRegExp.test(body)) { + body = await githubTwoFactorAuth(body, request) + } + return body +} +async function githubTwoFactorAuth(html: string, request: RequestAsync) { + const authenticityTokenTwoFactor = html.match(/name="authenticity_token" value="(.*?)"/) + if (authenticityTokenTwoFactor === null) { + return Promise.reject({ + message: 'get GitHub two-factor page fail', + code: 3, + }) + } + const code = await window.showInputBox({ + prompt: 'input the Authentication code', + }) + if (!code) { + return Promise.reject({ + message: 'cancel login', + code: 2, + }) + } + const data = { + otp: code, + authenticity_token: authenticityTokenTwoFactor[1], + } + const res = await request({ + url: 'https://github.com/sessions/two-factor', + form: data, + method: 'POST', + followAllRedirects: true, + headers: { + 'content-type': 'application/x-www-form-urlencoded', + }, + }) + return res.body +} +async function githubRedirectBack(body: string, request: RequestAsync) { + const redirectRegExp = / Thenable +interface QuickPickParameters { + title: string + step: number + totalSteps: number + items: T[] + activeItem?: T + placeholder: string + buttons?: QuickInputButton[] + shouldResume: () => Thenable +} +interface InputBoxParameters { + title: string + step: number + totalSteps: number + value: string + prompt: string + password?: boolean + validate: (value: string) => Promise + buttons?: QuickInputButton[] + shouldResume: () => Thenable +} +class MultiStepInput { + static async run(start: InputStep) { + const input = new MultiStepInput() + return input.stepThrough(start) + } + + private current?: QuickInput + private steps: InputStep[] = [] + + private async stepThrough(start: InputStep) { + let step: InputStep | void = start + while (step) { + this.steps.push(step) + if (this.current) { + this.current.enabled = false + this.current.busy = true + } + try { + step = await step(this) + } catch (err) { + if (err === InputFlowAction.back) { + this.steps.pop() + step = this.steps.pop() + } else if (err === InputFlowAction.resume) { + step = this.steps.pop() + } else if (err === InputFlowAction.cancel) { + step = undefined + } else { + throw err + } + } + } + if (this.current) { + this.current.dispose() + } + } + + async showQuickPick>({ + title, + step, + totalSteps, + items, + activeItem, + placeholder, + buttons, + shouldResume, + }: P) { + const disposables: Disposable[] = [] + try { + return await new Promise((resolve, reject) => { + const input = window.createQuickPick() + input.title = title + input.step = step + input.totalSteps = totalSteps + input.placeholder = placeholder + input.items = items + if (activeItem) { + input.activeItems = [activeItem] + } + input.buttons = [...(this.steps.length > 1 ? [QuickInputButtons.Back] : []), ...(buttons || [])] + disposables.push( + input.onDidTriggerButton((item) => { + if (item === QuickInputButtons.Back) { + reject(InputFlowAction.back) + } else { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + resolve(item as any) + } + }), + input.onDidChangeSelection((items) => resolve(items[0])), + input.onDidHide(() => { + ; (async () => { + reject( + shouldResume && (await shouldResume()) ? InputFlowAction.resume : InputFlowAction.cancel + ) + })().catch(reject) + }) + ) + if (this.current) { + this.current.dispose() + } + this.current = input + this.current.show() + }) + } finally { + disposables.forEach((d) => d.dispose()) + } + } + + async showInputBox

({ + title, + step, + totalSteps, + password = false, + value, + prompt, + validate, + buttons, + shouldResume, + }: P) { + const disposables: Disposable[] = [] + try { + return await new Promise((resolve, reject) => { + const input = window.createInputBox() + input.title = title + input.step = step + input.totalSteps = totalSteps + input.value = value || '' + input.prompt = prompt + input.password = password + input.buttons = [...(this.steps.length > 1 ? [QuickInputButtons.Back] : []), ...(buttons || [])] + let validating = validate('') + disposables.push( + input.onDidTriggerButton((item) => { + if (item === QuickInputButtons.Back) { + reject(InputFlowAction.back) + } else { + resolve(item as never) + } + }), + input.onDidAccept(async () => { + const value = input.value + input.enabled = false + input.busy = true + if (!(await validate(value))) { + resolve(value) + } + input.enabled = true + input.busy = false + }), + input.onDidChangeValue(async (text) => { + const current = validate(text) + validating = current + const validationMessage = await current + if (current === validating) { + input.validationMessage = validationMessage + } + }), + input.onDidHide(() => { + ; (async () => { + reject( + shouldResume && (await shouldResume()) ? InputFlowAction.resume : InputFlowAction.cancel + ) + })().catch(reject) + }) + ) + if (this.current) { + this.current.dispose() + } + this.current = input + this.current.show() + }) + } finally { + disposables.forEach((d) => d.dispose()) + } + } +} +export interface User { + name: string + password: string +} +async function inputName(input: MultiStepInput, user: Partial, title: string): Promise { + user.name = await input.showInputBox({ + step: 1, + totalSteps: 2, + validate: async () => '', + prompt: 'please input username or email', + title, + value: '', + shouldResume: () => Promise.resolve(false), + }) + return (input) => inputPass(input, user, title) +} +async function inputPass(input: MultiStepInput, user: Partial, title: string) { + user.password = await input.showInputBox({ + step: 2, + totalSteps: 2, + password: true, + validate: async () => '', + prompt: 'please input password', + title, + value: '', + shouldResume: () => Promise.resolve(false), + }) +} +function validUser(user: Partial): user is User { + return !!(user.name && user.password) +} +function validCookie(cookie: string) { + return cookie.includes('LEETCODE_SESSION') && cookie.includes('csrftoken') +} +async function refresh(questionsProvider: QuestionsProvider) { + cache.removeCache() + const refreshPromise = refreshQuestions() + await execWithProgress(refreshPromise, 'refresh questions') + questionsProvider.refresh() +} +export async function selectLogin(questionsProvider: QuestionsProvider) { + const githubItem = { + label: 'Third-Party:GitHub', + detail: 'Use GitHub account to login', + } + const cookieItem = { + label: 'Leetcode Cookie', + detail: 'Use Leetcode cookie copied from browser to login', + } + const accountItem = { + label: 'Leetcode Account', + detail: 'use Leetcode account to login', + } + const items = [githubItem, cookieItem] + if (config.lang === 'cn') { + items.unshift(accountItem) + } + const result = await window.showQuickPick(items) + if (result === githubItem) { + const user = await githubInput() + if (!validUser(user)) { + return + } + await execWithProgress(githubLogin(user), 'wait login') + window.showInformationMessage('login success') + } else if (result === cookieItem) { + const cookie = await cookieInput() + if (!cookie) { + return + } + if (!validCookie(cookie)) { + window.showErrorMessage('cookie is invalid') + return + } + await cookieLogin(cookie) + config.log.appendLine('save cookie success') + // window.showInformationMessage('save cookie success') + await refresh(questionsProvider) + return + } else if (result === accountItem) { + const user = await accountInput() + if (!validUser(user)) { + return + } + await accountLogin(user) + config.log.appendLine('login success') + // window.showInformationMessage('login success') + await refresh(questionsProvider) + } +} +export async function githubInput(): Promise> { + const user: Partial = {} + await MultiStepInput.run((input) => inputName(input, user, 'login github')) + return user +} +export async function cookieInput(): Promise { + const cookie = await window.showInputBox({ + prompt: 'copy the cookie from browser', + }) + return cookie +} +export async function accountInput() { + const user: Partial = {} + await MultiStepInput.run((input) => inputName(input, user, 'account login')) + return user +} + +// copy from https://github.com/microsoft/vscode-extension-samples/blob/master/quickinput-sample/src/multiStepInput.ts diff --git a/src/memo/index.ts b/src/memo/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..83058ccf8fb0b0a8d2d6c2dac419150e9b268da1 --- /dev/null +++ b/src/memo/index.ts @@ -0,0 +1,61 @@ +import { existDir, writeFileAsync } from '../common/util' +import { config, updateEnv } from '../config' +import * as path from 'path' +import { ResolverParam } from '../provider/resolver' +export function addFolder(name: string) { + if (config.env.memo.find((v) => v.name === name)) { + throw new Error('folder already exists') + } + config.env.memo.push({ + name, + children: [], + }) + updateEnv('memo', config.env.memo) +} +export function deleteFolder(name: string) { + const memo = config.env.memo + const index = memo.findIndex((item) => item.name === name) + memo.splice(index, 1) + updateEnv('memo', memo) +} +export async function addFolderFile(folderName: string, fileName: string) { + const memo = config.env.memo + const folder = memo.find((item) => item.name === folderName) + if (folder) { + folder.children.push({ + type: 'other', + name: fileName, + param: fileName, + }) + const memoDir = path.join(config.cacheBaseDir, 'memo') + const filePath = path.join(memoDir, fileName) + await existDir(memoDir) + await writeFileAsync(filePath, Buffer.alloc(0)) + } +} +export function addQuestion(folderName: string, name: string, param: Partial) { + const memo = config.env.memo + const folder = memo.find((item) => item.name === folderName) + if (folder) { + if (folder.children.find((v) => v.name === name)) { + throw new Error('file already exists') + } + folder.children.push({ + type: 'question', + name, + param, + }) + updateEnv('memo', memo) + } +} +// eslint-disable-next-line @typescript-eslint/no-unused-vars +async function deleteFile(folderName: string, fileName: string) { + const memo = config.env.memo + const folder = memo.find((item) => item.name === folderName) + if (folder) { + const index = folder.children.findIndex((c) => c.name === fileName) + if (index !== -1) { + folder.children.splice(index, 1) + } + } +} diff --git a/src/model/command.ts b/src/model/command.ts new file mode 100644 index 0000000000000000000000000000000000000000..e0d6e245f64f0d4c7bf5bafe414eb36d2c0d4c19 --- /dev/null +++ b/src/model/command.ts @@ -0,0 +1,26 @@ +import * as vscode from 'vscode' +import { TestCaseParam } from '../common/util' +import { QuestionsProvider } from '../provider/questionsProvider' + +export interface CodeLensesOptions { + text: string + filePath: string + langSlug: string +} +export interface TestCodeLensesOptions { + filePath: string + testCaseParam: TestCaseParam +} +export type BuildCodeLensesOptions = CodeLensesOptions +export type SubmitCodeLensesOptions = CodeLensesOptions +export type GetDescriptionCodeLensesOptions = CodeLensesOptions +export type ViewSubmitHistoryCodeLensesOptions = CodeLensesOptions +type FilePath = string +export type DebugLensesOptions = FilePath +type ExtensionPath = string +export type BuildCodeArguments = [vscode.ExtensionContext, BuildCodeLensesOptions] +export type TestCodeArguments = [TestCodeLensesOptions] +export type DebugCodeArguments = [DebugLensesOptions] +export type SubmitCodeArguments = [QuestionsProvider, SubmitCodeLensesOptions] +export type GetDescriptionArguments = [ExtensionPath, GetDescriptionCodeLensesOptions] +export type ViewSubmitHistoryArguments = [vscode.ExtensionContext, CodeLensesOptions] diff --git a/src/model/common.ts b/src/model/common.ts new file mode 100644 index 0000000000000000000000000000000000000000..8e31cfd411b62a27e92d32d3eb34a7e261902c59 --- /dev/null +++ b/src/model/common.ts @@ -0,0 +1,304 @@ +export interface GraphqlVariables { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + [key: string]: any +} +export interface GraphRes { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + errors: any + data: T +} +export enum Lang { + en = 'en', + cn = 'cn', +} +export interface Tag { + slug: string + name: string + questions: number[] + translatedName: string +} +export interface Favorites { + id: string + name: string + questions: number[] + type: string +} +export interface CodeSnippet { + lang: string + langSlug: string + code: string +} +// export type CodeLang = 'C++' | 'Java' | 'Python' | 'Python3' | 'C' | 'C#' | 'JavaScript' | 'Ruby' | 'Swift' | 'Go' | 'Scala' | 'Kotlin' | 'Rust' | 'PHP' | 'TypeScript' +// export const CodeLangs = ['C++', 'Java', 'Python', 'Python3', 'C', 'C#', 'JavaScript', 'Ruby', 'Swift', 'Go', 'Scala', 'Kotlin', 'Rust', 'PHP', 'TypeScript'] +export interface ConciseQuestion { + fid: string + level: number + id: number + title: string + slug: string + acs: number + submitted: number + paid_only: boolean + status: string + name: string +} +export interface CheckResponse { + status_code: number + lang: string + run_success: boolean + status_runtime: string + memory: number + question_id: string + elapsed_time: number + compare_result: string + code_output: string + std_output: string + last_testcase: string + task_finish_time: number + task_name: string + finished: boolean + status_msg: string + state: State + fast_submit: boolean + total_correct: number + total_testcases: number + submission_id: string + runtime_percentile: number + status_memory: string + memory_percentile: number + pretty_lang: string + input_formatted?: string + expected_output?: string +} +type State = 'PENDING' | 'STARTED' | 'SUCCESS' +export interface MapIdConciseQuestion { + [id: number]: ConciseQuestion +} +export interface Problems { + user_name: string + num_solved: number + num_total: number + ac_easy: number + ac_medium: number + ac_hard: number + stat_status_pairs: StatStatusPairs[] + frequency_high: number + frequency_mid: number + category_slug: string +} +interface StatStatusPairs { + stat: Stat + status: unknown + difficulty: Difficulty + paid_only: boolean + is_favor: boolean + frequency: number + progress: number +} +interface Difficulty { + level: number +} +interface Stat { + question_id: number + question__title: string + question__title_slug: string + question__hide: boolean + total_acs: number + total_submitted: number + total_column_articles: number + frontend_question_id: string + is_new_question: boolean +} +export enum ErrorStatus { + Unlogin = 403, + InvalidCookie = 499, +} + +export enum AskForImportState { + Yes = 'Yes', + No = 'No', + Later = 'Later', +} + +export enum PendingStatus { + NotPending = 'Not Pending', + Pending = 'Pending', +} +export enum FlagType { + BLUE = 'BLUE', + ORANGE = 'ORANGE', + GREEN = 'GREEN', + PURPLE = 'PURPLE', + RED = 'RED', +} +export interface SubmissionComment { + comment: string + flagType: FlagType +} +export interface Submission { + id: string + isPending: PendingStatus + submissionComment?: SubmissionComment + lang: string + memory: string + runtime: string + statusDisplay: string + timestamp: string + url: string +} + +export interface LocalSubmission { + code: string + submission: Submission +} + +export type LocalSubmissionArr = LocalSubmission[] + +export enum HistoryType { + Answer = 'answer', + LocalSubmit = 'localSubmit', + RemoteSubmit = 'remoteSubmit', +} + +export interface UpdateCommentOption { + id: string + comment: string + questionId: string +} +export type UpdateRemoteCommentOption = Omit + +type Requred = { + [key in R]-?: T[key] +} & + { + [key in keyof T]: T[key] + } +export function checkParams(obj: T, attrs: R[]): asserts obj is Requred { + const verify = attrs.every((attr) => !!obj[attr]) + if (!verify) { + const attr = attrs.find((attr) => !obj[attr])! + throw new Error(`options error, ${String(attr)} is ${obj[attr]}`) + } +} + +export interface ContestDetail { + contest: Contest + questions: ContestQuestion[] + user_num: number + has_chosen_contact: boolean + company: Company + registered: boolean + containsPremium: boolean +} +interface Company { + name: string + description: string + logo: string + slug?: string +} +interface ContestQuestion { + id: number + question_id: number + credit: number + title: string + english_title: string + title_slug: string + category_slug: string +} +interface Contest { + id: number + title: string + title_slug: string + description: string + duration: number + start_time: number + is_virtual: boolean + origin_start_time: number + is_private: boolean + related_contest_title?: unknown + discuss_topic_id?: number +} + +export interface CnContestPageData { + questionId: string + questionIdHash: string + questionTitleSlug: string + questionTitle: string + questionSourceTitle: string + questionExampleTestcases: string + categoryTitle: string + contestTitleSlug: string + loginUrl: string + isSignedIn: boolean + sessionId: string + reverseUrl: ReverseUrl + enableRunCode: boolean + enableSubmit: boolean + submitUrl: string + interpretUrl: string + judgeType: string + nextChallengePairs?: unknown + codeDefinition: CodeDefinition[] + enableTestMode: boolean + metaData: MetaData + sampleTestCase: string + judgerAvailable: boolean + envInfo: EnvInfo + questionContent: string + questionSourceContent: string + editorType: string +} +interface EnvInfo { + cpp: string[] + java: string[] + python: string[] + c: string[] + csharp: string[] + javascript: string[] + ruby: string[] + swift: string[] + golang: string[] + python3: string[] + scala: string[] + kotlin: string[] + rust: string[] + php: string[] + typescript: string[] + racket: string[] +} +interface MetaData { + name: string + params: Param[] + return: Return +} +interface Return { + type: string +} +interface Param { + name: string + type: string +} +export interface CodeDefinition { + value: string + text: string + defaultCode: string +} +interface ReverseUrl { + latest_submission: string + account_login: string + maintenance: string + profile: string +} + +export interface CommonQuestion { + translatedContent: string + translatedTitle: string + questionFrontendId: string + metaData: string + content: string + title: string + titleSlug: string + codeSnippets: CodeSnippet[] + questionId: string + questionSourceContent?: string +} diff --git a/src/model/memo.ts b/src/model/memo.ts new file mode 100644 index 0000000000000000000000000000000000000000..9a8d034aecf4317d862c678a918da9212fc9f93a --- /dev/null +++ b/src/model/memo.ts @@ -0,0 +1,17 @@ +import { ResolverParam } from '../provider/resolver' + +interface MemoQuestionFile { + type: 'question' + name: string + param: Partial +} +interface MemoOtherFile { + type: 'other' + name: string + param: string +} +export type MemoFile = MemoQuestionFile | MemoOtherFile +export interface MemoFolder { + name: string + children: MemoFile[] +} diff --git a/src/model/question.cn.ts b/src/model/question.cn.ts new file mode 100644 index 0000000000000000000000000000000000000000..5ba0a0a83915a8c36f7fed3eb7b9d01b55cd4775 --- /dev/null +++ b/src/model/question.cn.ts @@ -0,0 +1,282 @@ +import { CodeSnippet, FlagType, GraphqlVariables, SubmissionComment } from './common' + +export interface ConciseQuestion { + fid: string + level: number + id: number + title: string + slug: string + acs: number + submitted: number + paid_only: boolean + status: string + name: string +} +export interface MapIdConciseQuestion { + [id: number]: ConciseQuestion +} + +export interface TodayRecordData { + todayRecord: TodayRecord[] +} +export interface TodayRecord { + question: Pick + lastSubmission: LastSubmission + date: string + userStatus: UserStatus + __typename: string +} +interface LastSubmission { + id: string + __typename: string +} +type UserStatus = 'FINISH' | 'NOT_START' + +export interface QuestionTranslationData { + translations: Translation[] +} +export interface Translation { + questionId: string + title: string +} + +export interface GraphqlResponse { + data: T +} +export interface DailyQuestionRecordData { + dailyQuestionRecords: [DailyQuestionRecord] +} +export interface DailyQuestionRecord { + date: string + + question: Pick + userStatus: string + __typename: string +} + +export interface GraphqlRequestData { + operationName: string | null + query: string + variables: GraphqlVariables +} + +export interface QuestionData { + question: Question +} +export interface Question { + questionSourceContent?: string + questionId: string + questionFrontendId: string + boundTopicId: number + title: string + titleSlug: string + content: string + translatedTitle: string + translatedContent: string + isPaidOnly: boolean + difficulty: string + likes: number + dislikes: number + isLiked: unknown + similarQuestions: string + contributors: [] + langToValidPlayground: string + topicTags: TopicTags[] + companyTagStats: unknown + codeSnippets: CodeSnippet[] + stats: string + hints: string[] + solution: Solution + status: Status + sampleTestCase: string + metaData: string + judgerAvailable: boolean + judgeType: string + mysqlSchemas: string[] + enableRunCode: boolean + envInfo: string + book: unknown + isSubscribed: boolean + isDailyQuestion: boolean + dailyRecordStatus: string + editorType: string + ugcQuestionId: unknown + style: string + + // questionTitleSlug: string +} +interface Solution { + canSeeDetail: boolean + id: string +} +type Status = 'ac' | 'notac' | null + +interface TopicTags { + name: string + slug: string + translatedName: string + questions: number[] //question id + __typename: string +} + +export interface ContestData { + allContests: Pick[] +} +interface Contest { + containsPremium: boolean + title: string + cardImg: string + titleSlug: string + description: string + startTime: number + duration: number + originStartTime: number + isVirtual: boolean + company: Company + __typename: string +} +interface Company { + watermark: string + __typename: string +} + +export interface TagData { + topics: TopicTags[] +} +// interface Topics { +// slug: string +// name: string +// questions: number[] +// translatedName: string +// } + +export interface favoritesData { + name: string + type: string + id: string + questions: number[] +} + +export interface SubmitOptions { + titleSlug: string + typed_code: string + question_id: string + lang?: string +} +export interface SubmitContestOptions extends SubmitOptions { + weekname: string +} +export interface SubmitResponse { + submission_id: number +} +export interface CheckResponse { + status_code: number + lang: string + run_success: boolean + status_runtime: string + memory: number + question_id: string + elapsed_time: number + compare_result: string + code_output: string + std_output: string + last_testcase: string + task_finish_time: number + task_name: string + finished: boolean + status_msg: string + state: State + fast_submit: boolean + total_correct: number + total_testcases: number + submission_id: string + runtime_percentile: number + status_memory: string + memory_percentile: number + pretty_lang: string +} + +export interface CheckContestResponse { + state: State +} +type State = 'PENDING' | 'STARTED' | 'SUCCESS' + +export interface CheckOptions { + submission_id: number + titleSlug: string +} +export interface CheckContestOptions extends CheckOptions { + weekname: string +} + +export interface SubmissionsResponse { + submissionList: SubmissionList +} +export interface SubmissionsOptions { + lastKey?: string + limit?: number + offset?: number + titleSlug: string +} +interface SubmissionList { + lastKey: string + hasNext: boolean + submissions: Submissions[] +} +interface Submissions { + id: string + statusDisplay: string + lang: string + runtime: string + timestamp: string + url: string + isPending: string + memory: string + submissionComment?: SubmissionComment +} +export interface UpdateCommentOptions { + comment: string + flagType?: FlagType + submissionId: string +} +export interface UpdateCommentResponse { + submissionCreateOrUpdateSubmissionComment: SubmissionCreateOrUpdateSubmissionComment +} + +interface SubmissionCreateOrUpdateSubmissionComment { + ok: boolean +} + +export interface SubmissionDetailOptions { + id: string +} +export interface SubmissionDetailResponse { + submissionDetail?: SubmissionDetail +} +interface SubmissionDetail { + id: string + code: string + runtime: string + memory: string + rawMemory: string + statusDisplay: string + timestamp: number + lang: string + passedTestCaseCnt: number + totalTestCaseCnt: number + sourceUrl: string + question: Question + outputDetail: OutputDetail + __typename: string + submissionComment: SubmissionComment +} + +interface OutputDetail { + codeOutput: string + expectedOutput: string + input: string + compileError: string + runtimeError: string + lastTestcase: string + __typename: string +} diff --git a/src/model/question.ts b/src/model/question.ts new file mode 100644 index 0000000000000000000000000000000000000000..bab97abd6a11fc2d6c14638e09a61b151836224b --- /dev/null +++ b/src/model/question.ts @@ -0,0 +1,313 @@ +import { CodeSnippet, GraphqlVariables, SubmissionComment } from './common' + +export interface Chapter { + descriptionText: string + id: string + slug: string + title: string +} +export interface ChaptersRes { + chapters: Chapter[] +} +interface ChapterQuestion { + chapterId: number + id: string + isEligibleForCompletion: boolean + paidOnly: boolean + prerequisites: unknown[] + title: string + type: number +} +interface ChapterDetail { + description: string + id: string + slug: string + title: string + items: ChapterQuestion[] +} +export interface ChapterRes { + chapter: ChapterDetail +} +interface GetOrCreateExploreSession { + progress: string +} + +interface DailyProgress { + is_complete: boolean +} +interface DailyQuestionMap { + [key: string]: DailyProgress +} +export interface DailyWeekMap { + [key: string]: DailyQuestionMap +} +export interface ChaptersProgressRes { + getOrCreateExploreSession: GetOrCreateExploreSession +} +interface ChapterItem { + question: Pick +} +export interface ChapterItemRes { + item: ChapterItem +} + +export interface ConciseQuestion { + fid: string + level: number + id: number + title: string + slug: string + acs: number + submitted: number + paid_only: boolean + status: string + name: string +} +export interface MapIdConciseQuestion { + [id: number]: ConciseQuestion +} + +export interface TodayRecordData { + todayRecord: TodayRecord[] +} +interface TodayRecord { + question: Pick + lastSubmission: LastSubmission + date: string + userStatus: UserStatus + __typename: string +} +interface LastSubmission { + id: string + __typename: string +} +type UserStatus = 'FINISH' | 'NOT_START' + +export interface QuestionTranslationData { + translations: Translation[] +} +interface Translation { + questionId: string + title: string +} + +export interface GraphqlResponse { + data: T +} +export interface DailyQuestionRecordData { + dailyQuestionRecords: [DailyQuestionRecord] +} +export interface DailyQuestionRecord { + date: string + + question: Pick + userStatus: string + __typename: string +} + +export interface GraphqlRequestData { + operationName: string | null + query: string + variables: GraphqlVariables +} + +export interface QuestionData { + question: Question +} +export interface Question { + questionId: string + questionFrontendId: string + boundTopicId: number + title: string + titleSlug: string + content: string + translatedTitle: string + translatedContent: string + isPaidOnly: boolean + difficulty: string + likes: number + dislikes: number + isLiked: unknown + similarQuestions: string + contributors: [] + langToValidPlayground: string + topicTags: TopicTags[] + companyTagStats: unknown + codeSnippets: CodeSnippet[] + stats: string + hints: string[] + solution: Solution + status: Status + sampleTestCase: string + metaData: string + judgerAvailable: boolean + judgeType: string + mysqlSchemas: string[] + enableRunCode: boolean + envInfo: string + book: unknown + isSubscribed: boolean + isDailyQuestion: boolean + dailyRecordStatus: string + editorType: string + ugcQuestionId: unknown + style: string + __typename: string + + // questionTitleSlug: string +} +interface Solution { + canSeeDetail: boolean + id: string +} +type Status = 'ac' | 'notac' | null + +interface TopicTags { + name: string + slug: string + translatedName: string + questions: number[] //question id + __typename: string +} + +export interface ContestData { + allContests: Pick[] +} +interface Contest { + containsPremium: boolean + title: string + cardImg: string + titleSlug: string + description: string + startTime: number + duration: number + originStartTime: number + isVirtual: boolean + company: Company + __typename: string +} +interface Company { + watermark: string + __typename: string +} + +export interface TagData { + topics: TopicTags[] +} +// interface Topics { +// slug: string +// name: string +// questions: number[] +// translatedName: string +// } + +export interface SubmitOptions { + titleSlug: string + typed_code: string + question_id: string + lang?: string +} +export interface SubmitContestOptions extends SubmitOptions { + weekname: string +} +export interface SubmitResponse { + submission_id: number +} +export interface CheckResponse { + status_code: number + lang: string + run_success: boolean + status_runtime: string + memory: number + question_id: string + elapsed_time: number + compare_result: string + code_output: string + std_output: string + last_testcase: string + task_finish_time: number + task_name: string + finished: boolean + status_msg: string + state: State + fast_submit: boolean + total_correct: number + total_testcases: number + submission_id: string + runtime_percentile: number + status_memory: string + memory_percentile: number + pretty_lang: string +} + +export interface CheckContestResponse { + state: State +} +type State = 'PENDING' | 'STARTED' | 'SUCCESS' + +export interface CheckOptions { + submission_id: number + titleSlug: string +} +export interface CheckContestOptions extends CheckOptions { + weekname: string +} + +export interface SubmissionsResponse { + submissionList: SubmissionList +} +export interface SubmissionsOptions { + lastKey?: string + limit?: number + offset?: number + titleSlug: string +} +interface SubmissionList { + lastKey: string + hasNext: boolean + submissions: Submissions[] +} +export interface Submissions { + id: string + statusDisplay: string + lang: string + runtime: string + timestamp: string + url: string + isPending: string + memory: string + submissionComment?: SubmissionComment +} +export interface SubmissionDetailOptions { + id: string +} + +export interface SubmissionDetailPageData { + submissionData: SubmissionData + questionId: string + sessionId: string + getLangDisplay: string + submissionCode: string + editCodeUrl: string + checkUrl: string + runtimeDistributionFormatted: string + memoryDistributionFormatted: string + langs: unknown[] + runtime: string + memory: string + enableMemoryDistribution: string + nonSufficientMsg: string +} +interface SubmissionData { + status_code: number + runtime: string + memory: string + total_correct: string + total_testcases: string + compare_result: string + input_formatted: string + input: string + expected_output: string + code_output: string + last_testcase: string +} diff --git a/src/process.ts b/src/process.ts new file mode 100644 index 0000000000000000000000000000000000000000..d722623a6487be992aa1d0e1eff679ef6c189179 --- /dev/null +++ b/src/process.ts @@ -0,0 +1,35 @@ +import * as cp from 'child_process' + + +export const processArr: cp.ChildProcess[] = [] +export function clearProcessArr() { + processArr.forEach(p => { + p.kill() + }) +} + +class ChildProcessProxy { + processIdSet: Set = new Set() + clear() { + this.processIdSet.forEach(pid => { + process.kill(pid) + }) + } + add(p: cp.ChildProcess) { + const pid = p.pid + this.processIdSet.add(pid) + p.once('exit', () => { + this.processIdSet.delete(pid) + }) + } + remove(p: cp.ChildProcess | null) { + if (!p) { + return + } + if (this.processIdSet.has(p.pid)) { + p.kill() + } + } +} + +export const childProcessProxy = new ChildProcessProxy() \ No newline at end of file diff --git a/src/provider/codelensProvider.ts b/src/provider/codelensProvider.ts new file mode 100644 index 0000000000000000000000000000000000000000..33fa1c1a16b32e7cb0c1e444d4128002189bd4d3 --- /dev/null +++ b/src/provider/codelensProvider.ts @@ -0,0 +1,146 @@ +import * as vscode from 'vscode' +import { detectEnableExt, TestCaseParam } from '../common/util' +import { getFileLang, getFileLangSlug, isAlgorithm, isSupportFile } from '../common/langConfig' +import { Service } from '../lang/common' +import { + CodeLensesOptions, + DebugLensesOptions, + GetDescriptionCodeLensesOptions, + SubmitCodeLensesOptions, + TestCodeLensesOptions, + ViewSubmitHistoryCodeLensesOptions, +} from '../model/command' +export class CodelensProvider implements vscode.CodeLensProvider { + private codeLenses: vscode.CodeLens[] = [] + private regex: RegExp + private _onDidChangeCodeLenses: vscode.EventEmitter = new vscode.EventEmitter() + public readonly onDidChangeCodeLenses: vscode.Event = this._onDidChangeCodeLenses.event + + constructor() { + this.regex = /(@test)/g + + vscode.workspace.onDidChangeConfiguration((_) => { + this._onDidChangeCodeLenses.fire() + }) + } + private getBuildCodeLenses(options: CodeLensesOptions): vscode.CodeLens { + const codeLens = new vscode.CodeLens(new vscode.Range(0, 0, 0, 7)) + + codeLens.command = { + title: 'build', + tooltip: 'build', + command: 'algorithm.buildCode', + arguments: [options], + } + return codeLens + } + private getSubmitCodeLenses(options: SubmitCodeLensesOptions): vscode.CodeLens { + const codeLens = new vscode.CodeLens(new vscode.Range(0, 0, 0, 7)) + + codeLens.command = { + title: 'submit', + tooltip: 'submit', + command: 'algorithm.submit', + arguments: [options], + } + return codeLens + } + private getDescriptionCodeLenses(options: GetDescriptionCodeLensesOptions) { + const codeLens = new vscode.CodeLens(new vscode.Range(0, 0, 0, 7)) + codeLens.command = { + title: 'description', + tooltip: 'description', + command: 'algorithm.getDescription', + arguments: [options], + } + return codeLens + } + private getHistoryCodeLenses(options: ViewSubmitHistoryCodeLensesOptions) { + const codeLens = new vscode.CodeLens(new vscode.Range(0, 0, 0, 7)) + codeLens.command = { + title: 'history', + tooltip: 'history', + command: 'algorithm.viewSubmitHistory', + arguments: [options], + } + return codeLens + } + private getTestCodeLenses(options: TestCodeLensesOptions) { + const { + testCaseParam: { line }, + } = options + const codeLens = new vscode.CodeLens(new vscode.Range(line, 0, line, 7)) + codeLens.command = { + title: 'test', + tooltip: 'test', + command: 'algorithm.testCode', + arguments: [options], + } + return codeLens + } + private getDebugCodeLenses(testCaseParam: TestCaseParam, filePath: DebugLensesOptions) { + const { line } = testCaseParam + const codeLens = new vscode.CodeLens(new vscode.Range(line, 0, line, 7)) + codeLens.command = { + title: 'debug', + tooltip: 'debug', + command: 'algorithm.debugCode', + arguments: [filePath], + } + return codeLens + } + + public provideCodeLenses(document: vscode.TextDocument): vscode.CodeLens[] | Thenable { + this.codeLenses = [] + const text = document.getText() + const filePath = document.fileName + const isSupport = isSupportFile(filePath) + if (!isSupport) { + return [] + } + const enableExt = detectEnableExt(text, filePath) + + if (enableExt) { + const codeLang = getFileLang(filePath) + const langSlug = getFileLangSlug(filePath) + const codeLensesOptions: CodeLensesOptions = { + text, + filePath, + langSlug, + } + const submitCodeLenses = this.getSubmitCodeLenses({ + ...codeLensesOptions, + }) + const buildCodeLenses = this.getBuildCodeLenses({ + ...codeLensesOptions, + }) + const desCodeLenses = this.getDescriptionCodeLenses({ + ...codeLensesOptions, + }) + const historyCodeLenses = this.getHistoryCodeLenses({ + ...codeLensesOptions, + }) + this.codeLenses.push(submitCodeLenses) + this.codeLenses.push(buildCodeLenses) + this.codeLenses.push(desCodeLenses) + this.codeLenses.push(historyCodeLenses) + if (isAlgorithm(codeLang)) { + const lang = new Service(filePath, text) + const testCaseList = lang.getTestCaseList(text) + testCaseList.forEach((testCaseParam) => { + const testCodeOptions: TestCodeLensesOptions = { + filePath: document.uri.fsPath, + testCaseParam, + } + const testCodeLenses = this.getTestCodeLenses(testCodeOptions) + const debugCodeLenses = this.getDebugCodeLenses(testCaseParam, document.uri.fsPath) + this.codeLenses.push(testCodeLenses) + this.codeLenses.push(debugCodeLenses) + }) + } + + return this.codeLenses + } + return [] + } +} diff --git a/src/provider/completionProvider.ts b/src/provider/completionProvider.ts new file mode 100644 index 0000000000000000000000000000000000000000..adef50779757d0ec5f66b97971fb5af201e6b973 --- /dev/null +++ b/src/provider/completionProvider.ts @@ -0,0 +1,29 @@ +import { config } from '../config' +import * as vscode from 'vscode' + +const defaultCompletionItems = [ + { + languages: ['javascript', 'typescript'], + prefix: 'algorithm', + body: "// @algorithm\r\nimport * as a from '" + config.algmModuleDir + "'\r\n\r\n", + }, +] +export function registerCompletionItemProvider(context: vscode.ExtensionContext) { + defaultCompletionItems.forEach(({ languages, prefix, body }) => { + context.subscriptions.push( + vscode.languages.registerCompletionItemProvider( + languages, + { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + provideCompletionItems(document: vscode.TextDocument, position: vscode.Position) { + const snippetCompletion = new vscode.CompletionItem(prefix) + snippetCompletion.insertText = new vscode.SnippetString(body) + + return [snippetCompletion] + }, + }, + '.' // triggered whenever a '.' is being typed + ) + ) + }) +} diff --git a/src/provider/memoProvider.ts b/src/provider/memoProvider.ts new file mode 100644 index 0000000000000000000000000000000000000000..f088b30668267cd4de1dcfe4553375f4f5e4e60c --- /dev/null +++ b/src/provider/memoProvider.ts @@ -0,0 +1,170 @@ +import * as vscode from 'vscode' +import { config, updateEnv } from '../config' +import { sortFiles } from '../util' +const MemoFilePreviewCommand = 'algorithm.memoFilePreview' +const MemoFileContext = 'memoFile' +enum MemoLevel { + Folder, + File, + Invalid, +} +enum RemoveMemoMsg { + Folder = 'Are you sure you want to delete the folder?', + File = 'Are you sure you want to delete the file?', +} + +export class MemoTree extends vscode.TreeItem { + constructor( + public label: string, + public id: string, + public paths: string[], + public collapsibleState: vscode.TreeItemCollapsibleState = vscode.TreeItemCollapsibleState.Collapsed, + public command?: vscode.Command + ) { + super(label, vscode.TreeItemCollapsibleState.Collapsed) + } + contextValue = 'memo' +} + +export class MemoProvider implements vscode.TreeDataProvider { + private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter< + MemoTree | undefined + >() + readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event + refresh(): void { + this._onDidChangeTreeData.fire(undefined) + } + getTreeItem(element: MemoTree): vscode.TreeItem { + return element + } + getChildren(element?: MemoTree): Thenable { + if (element) { + const folderName = element.label + const files = this.getFolderFiles(folderName) + return Promise.resolve( + files.map((f) => { + const tree = new MemoTree(f.label, f.id, f.paths, vscode.TreeItemCollapsibleState.None, { + title: 'memoFilePreview', + command: MemoFilePreviewCommand, + arguments: [f.param], + }) + tree.contextValue = MemoFileContext + return tree + }) + ) + } else { + const folders = this.getFolders() + return Promise.resolve( + folders.map((f) => { + const tree = new MemoTree(f.label, f.id, f.paths) + tree.contextValue = MemoFileContext + return tree + }) + ) + } + } + getFolders() { + return config.env.memo.map((v) => { + return { + label: v.name, + id: 'folder' + v.name, + paths: [v.name], + } + }) + } + getFolderFiles(name: string) { + const folder = config.env.memo.find((v) => v.name === name) + if (folder) { + const files = folder.children + sortFiles(files) + return files.map((v) => { + return { + label: v.name, + id: name + v.name, + paths: [name, v.name], + param: v, + } + }) + } else { + return [] + } + } + static getElementLevel(element: MemoTree) { + const paths = element.paths + if (paths.length === 1) { + return MemoLevel.Folder + } else if (paths.length === 2) { + return MemoLevel.File + } + return MemoLevel.Invalid + } + static async remove(element: MemoTree): Promise { + const isRemove = await MemoProvider.checkRemove(element) + if (!isRemove) { + return false + } + const removeConfigs = [ + { + level: MemoLevel.Folder, + fn: MemoProvider.removeFolder, + }, + { + level: MemoLevel.File, + fn: MemoProvider.removeFile, + }, + ] + const level = MemoProvider.getElementLevel(element) + const config = removeConfigs.find((c) => c.level === level) + if (config) { + config.fn(element.paths) + return true + } + return false + } + + static async checkRemove(element: MemoTree): Promise { + const msgConfigs = [ + { + level: MemoLevel.Folder, + msg: RemoveMemoMsg.Folder, + }, + { + level: MemoLevel.File, + msg: RemoveMemoMsg.File, + }, + ] + const Remove = 'remove' + const level = MemoProvider.getElementLevel(element) + const config = msgConfigs.find((c) => c.level === level) + if (config) { + const msg = config.msg + const r = await vscode.window.showWarningMessage(msg, { modal: true }, Remove) + return r === Remove + } + return false + } + static removeFolder(paths: string[]) { + const memo = config.env.memo + const folderName = paths[0] + const index = memo.findIndex((m) => m.name === folderName) + if (index !== -1) { + memo.splice(index, 1) + return updateEnv('memo', memo) + } + + config.log.appendLine('folder not exist') + } + static removeFile(paths: string[]) { + const memo = config.env.memo + const [folderName, fileName] = paths + const folder = memo.find((m) => m.name === folderName) + if (folder) { + const index = folder.children.findIndex((f) => f.name === fileName) + if (index !== -1) { + folder.children.splice(index, 1) + return updateEnv('memo', memo) + } + } + config.log.appendLine('file not exist') + } +} diff --git a/src/provider/questionsProvider.ts b/src/provider/questionsProvider.ts new file mode 100644 index 0000000000000000000000000000000000000000..8170ed603baf90e4010c099f5d91559c680994db --- /dev/null +++ b/src/provider/questionsProvider.ts @@ -0,0 +1,117 @@ +import * as vscode from 'vscode' +import { QuestionPreview } from '../webview/questionPreview' +import { config } from '../config' +import { resolverEn, ResolverFn, ResolverParam, ResolverType } from './resolver' +import { resolverCn } from './resolver.cn' +import * as path from 'path' +export class QuestionTree extends vscode.TreeItem { + constructor( + public readonly label: string, + public readonly id: string, + public readonly collapsibleState: vscode.TreeItemCollapsibleState, + public readonly type: string, + public readonly key?: string, + public readonly param?: Partial, + public readonly command?: vscode.Command + ) { + super(label, collapsibleState) + } +} +export class QuestionsProvider implements vscode.TreeDataProvider { + private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter< + QuestionTree | undefined + >() + readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event + constructor( + private workspaceRoot: ReadonlyArray | undefined, + private _extensionPath: string + ) {} + refresh(): void { + this._onDidChangeTreeData.fire(undefined) + } + + getTreeItem(element: QuestionTree): vscode.TreeItem { + return element + } + getChildren(element?: QuestionTree): Thenable { + let resolver: ResolverType + if (config.lang === 'en') { + resolver = resolverEn + } else { + resolver = resolverCn + } + if (element) { + const type = element.type + const key = element.key + const param = element.param || {} + let fn: ResolverFn + if (key) { + fn = resolver[type][key] + } else { + fn = resolver[type] as ResolverFn + } + return Promise.resolve(fn(param)) + .then((arr) => { + if (!arr.length) { + return [] + } + const isLastChild = arr[0].isLast + if (isLastChild) { + return arr.map((v) => { + const dep = new QuestionTree( + v.label, + v.id, + vscode.TreeItemCollapsibleState.None, + v.type, + v.key, + v.param, + { + title: 'QuestionPreview', + command: QuestionPreview, + arguments: [v.param], + } + ) + if (v.paidOnly) { + dep.iconPath = new vscode.ThemeIcon('lock') + } else { + // dep.iconPath = v.isAC ? new vscode.ThemeIcon('check') : '' + dep.iconPath = v.isAC ? path.join(__dirname, '..', '..', 'media', 'ac.svg') : '' + } + dep.contextValue = 'memo' + return dep + }) + } else { + return arr.map( + (v) => + new QuestionTree( + v.label, + v.id, + vscode.TreeItemCollapsibleState.Collapsed, + v.type, + v.key, + v.param || {} + ) + ) + } + }) + .catch((err) => { + console.log(err) + return [] + }) + } else { + return Promise.resolve(resolver.Query()).then((arr) => + arr.map( + (v) => + new QuestionTree( + v.label, + v.id, + vscode.TreeItemCollapsibleState.Collapsed, + v.type, + v.key, + v.param || {} + ) + ) + ) + } + } +} diff --git a/src/provider/resolver.cn.ts b/src/provider/resolver.cn.ts new file mode 100644 index 0000000000000000000000000000000000000000..9da6bc6e82c78b6964761e7c378c4623a658a620 --- /dev/null +++ b/src/provider/resolver.cn.ts @@ -0,0 +1,201 @@ +import { + api, + getTags, + getQuestionsByTag, + getQuestionsByDifficult, + fetchFavoriteLists, + getAllQuestions, + getCategories, + getQuestionsByCategory, + getFavorites +} from '../api/api.cn' +import { ResolverType } from './resolver' +import { normalizeQuestions } from '../common/util' + +export const resolverCn: ResolverType = { + Query() { + //'Company', 'Favorite', + const menuList = [ + {label: '全部', id: 'All'}, + {label: '题单', id: 'List'}, + {label: '标签', id: 'Tag'}, + {label: '难度', id: 'Difficulty'} + ] + return menuList.map((v) => ({ + key: v.id.toLowerCase(), + type: 'Catalogue', + label: v.label, + id: v.id, + })) + }, + Catalogue: { + async all() { + const questions = await getAllQuestions() + return normalizeQuestions(questions, 'all') + }, + difficulty() { + return ['Easy', 'Medium', 'Hard'].map((v) => ({ + key: v.toLowerCase(), + type: 'Difficulty', + label: v, + id: v, + })) + }, + category() { + const categories = getCategories() + return categories.map((v) => ({ + label: v.label, + type: 'Category', + key: v.category_slug, + id: 'Category' + v.category_slug, + })) + }, + async tag() { + const tags = await getTags() + return tags.map((tag) => ({ + key: 'tagkey', + type: 'Tag', + label: tag, + id: tag, + param: { + tag, + }, + })) + }, + + // company() { + + // }, + // favorite() { + + // }, + async contest() { + const contests = await api.fetchContests() + return contests.map((contest) => ({ + key: 'contestKey', + type: 'Contest', + label: contest.title, + id: contest.title, + param: { + titleSlug: contest.titleSlug, + }, + })) + }, + // async todayrecord() { + // const record = await api.fetchTodayRecord() + // return record.map((v) => ({ + // type: 'Question', + // label: v.question.questionFrontendId + '.' + v.question.translatedTitle, + // isAC: v.userStatus === 'FINISH', //NOT_START + // isLast: true, + // id: 'todayrecord' + v.question.questionFrontendId, + // param: { + // titleSlug: v.question.titleSlug, + // }, + // })) + // }, + async list() { + const list = await getFavorites() + return list.map((v) => ({ + key: 'getListdifficulty', + type: 'List', + label: v.name, + id: v.id, + param: { + itemId: v.id, + name: v.name + } + })) + // const questions = await getAllQuestions() + // return normalizeQuestions(questions, 'list') + }, + }, + Category: { + async algorithm() { + const key = 'algorithm' + const questions = await getQuestionsByCategory(key) + return normalizeQuestions(questions, key) + }, + async lcci() { + const key = 'lcci' + const questions = await getQuestionsByCategory(key) + return normalizeQuestions(questions, key) + }, + async lcof() { + const key = 'lcof' + const questions = await getQuestionsByCategory(key) + return normalizeQuestions(questions, key) + }, + }, + Tag: { + async tagkey({ tag }) { + if (!tag) { + return [] + } + const questions = await getQuestionsByTag(tag) + return normalizeQuestions(questions, 'tag' + tag) + }, + }, + Difficulty: { + async easy() { + const key = 'easy' + const questions = await getQuestionsByDifficult(key) + return normalizeQuestions(questions, key) + }, + async medium() { + const key = 'medium' + const questions = await getQuestionsByDifficult(key) + return normalizeQuestions(questions, key) + }, + async hard() { + const key = 'hard' + const questions = await getQuestionsByDifficult(key) + return normalizeQuestions(questions, key) + }, + }, + // Company() { + + // }, + // Favorite() { + + // }, + Contest: { + async contestKey({ titleSlug }) { + if (!titleSlug) { + return [] + } + const data = await api.fetchContest(titleSlug) + const questions = data.questions + return questions.map((question) => ({ + type: 'QuestionContest', + label: question.title, + id: 'QuestionContest' + question.id, + isLast: true, + param: { + titleSlug: question.title_slug, + weekname: titleSlug, + }, + })) + }, + }, + List: { + getListdifficulty(param) { + return ['Easy', 'Medium', 'Hard'].map((v) => ({ + key: v.toLowerCase(), + type: 'ListDetail', + label: v, + id: param.itemId + v, + param: { + itemId: param.itemId + } + })) + }, + }, + ListDetail: { + async easy(param) { + const key = 'easy' + const questions = await fetchFavoriteLists(param.itemId as string, key) + return normalizeQuestions(questions, key) + }, + } +} diff --git a/src/provider/resolver.ts b/src/provider/resolver.ts new file mode 100644 index 0000000000000000000000000000000000000000..17ccb14f8a208672331445f98a40906d821883f0 --- /dev/null +++ b/src/provider/resolver.ts @@ -0,0 +1,178 @@ +import { api, getTags, getQuestionsByTag, getQuestionsByDifficult, getAllQuestions } from '../api/api' +import { DailyWeekMap } from '../model/question' +import { QuestionTree } from './questionsProvider' +import { normalizeQuestions } from '../common/util' + +export interface ResolverParam { + tag: string + titleSlug: string + weekname: string + questionId: number + chapterId: string + itemId: string +} + +interface ResolverReturn extends Pick { + isLast?: boolean + isAC?: boolean + paidOnly?: boolean +} +export type ResolverFn = (param: Partial) => Promise | ResolverReturn[] + +interface RootResolver { + Query: () => Promise | ResolverReturn[] +} +export interface ResolverTypeBase { + [key: string]: ResolverFn | ResolverTypeBase +} +export type ResolverType = ResolverTypeBase & RootResolver + +export const resolverEn: ResolverType = { + Query() { + //'Company', 'Favorite', + return ['All', 'Difficulty', 'Tag', 'Contest', 'DailyChallenge'].map((v) => ({ + type: 'Catalogue', + key: v.toLowerCase(), + label: v, + id: v, + })) + }, + Catalogue: { + async all() { + const questions = await getAllQuestions() + return normalizeQuestions(questions, 'all') + }, + difficulty() { + return ['Easy', 'Medium', 'Hard'].map((v) => ({ + type: 'Difficulty', + key: v.toLowerCase(), + label: v, + id: v, + })) + }, + async tag() { + const tags = await getTags() + return tags.map((tag) => ({ + type: 'Tag', + key: 'tagkey', + label: tag, + id: tag, + param: { + tag, + }, + })) + }, + + // company() { + + // }, + // favorite() { + + // }, + async contest() { + const contests = await api.fetchContests() + return contests.map((contest) => ({ + type: 'Contest', + key: 'contestKey', + label: contest.title, + id: contest.title, + param: { + titleSlug: contest.titleSlug, + }, + })) + }, + async dailychallenge() { + const { chapters } = await api.fetchChapters() + return chapters.map((chapter) => ({ + type: 'Chapter', + label: chapter.title, + id: chapter.title, + param: { + // titleSlug: chapter.slug, + chapterId: chapter.id, + }, + })) + }, + }, + async Chapter({ chapterId }) { + if (!chapterId) { + return [] + } + const chapterDetail = await api.fetchChapter(chapterId) + const chaptersProgressRes = await api.fetchChapterProgress() + const progress = chaptersProgressRes?.getOrCreateExploreSession?.progress + let progressMap: DailyWeekMap | null = null + try { + progressMap = JSON.parse(progress) + } catch (err) { + progressMap = null + } + + const items = chapterDetail.chapter.items + return items.map((item) => { + return { + type: 'DailyQuestion', + label: item.title, + id: 'DailyQuestion' + item.title, + isLast: true, + isAC: progressMap ? progressMap[chapterId][item.id].is_complete : false, + paidOnly: item.paidOnly, + param: { + itemId: item.id, + }, + } + }) + }, + Tag: { + async tagkey({ tag }) { + if (!tag) { + return [] + } + const questions = await getQuestionsByTag(tag) + return normalizeQuestions(questions, 'tag' + tag) + }, + }, + + Difficulty: { + async easy() { + const key = 'easy' + const questions = await getQuestionsByDifficult(key) + return normalizeQuestions(questions, key) + }, + async medium() { + const key = 'medium' + const questions = await getQuestionsByDifficult(key) + return normalizeQuestions(questions, key) + }, + async hard() { + const key = 'hard' + const questions = await getQuestionsByDifficult(key) + return normalizeQuestions(questions, key) + }, + }, + // Company() { + + // }, + // Favorite() { + + // }, + Contest: { + async contestKey({ titleSlug }) { + if (!titleSlug) { + return [] + } + const data = await api.fetchContest(titleSlug) + const questions = data.questions + return questions.map((question) => ({ + type: 'QuestionContest', + label: question.id + ' ' + question.title, + id: 'QuestionContest' + question.id, + isLast: true, + param: { + titleSlug: question.title_slug, + fatherTitleSlug: titleSlug, + }, + })) + }, + }, +} diff --git a/src/provider/snippetProvider.ts b/src/provider/snippetProvider.ts new file mode 100644 index 0000000000000000000000000000000000000000..f709fd4bad3938dc0de058b59602d0abc6e008aa --- /dev/null +++ b/src/provider/snippetProvider.ts @@ -0,0 +1,44 @@ +import * as vscode from 'vscode' +import { setLinePrefix } from '../common/util' +import { tag } from 'pretty-tag' +export function registerForSnippetProviders(context: vscode.ExtensionContext) { + const forVariables = ['i', 'j', 'k'] + const fns = forVariables.map((forVariable) => { + return function provideCompletionItems(document: vscode.TextDocument, position: vscode.Position) { + const key = `for${forVariable}.` + let text = document.lineAt(position).text + if (!text.endsWith(key)) { + return + } + let whitePrefix = '' + for (let i = 0; i < text.length; i++) { + if (!/\s/.test(text[i])) { + whitePrefix = text.slice(0, i) + break + } + } + text = text.trimLeft() + const snippetCompletion = new vscode.CompletionItem(text) + const range = document.lineAt(position).range + snippetCompletion.range = range + const prefix = text.slice(0, text.length - 5) + let snippetString = tag` + for (let ${forVariable} = 0; ${forVariable} < ${prefix}.length; ${forVariable}++) { + let element = ${prefix}[${forVariable}] + $0 + }` + snippetString = setLinePrefix(snippetString, whitePrefix) + snippetCompletion.insertText = new vscode.SnippetString(snippetString) + return [snippetCompletion] + } + }) + fns.forEach((fn) => { + context.subscriptions.push( + vscode.languages.registerCompletionItemProvider( + { language: 'javascript', scheme: 'file' }, + { provideCompletionItems: fn }, + '.' + ) + ) + }) +} diff --git a/src/test/runTest.ts b/src/test/runTest.ts index 27b3ceb22f86ed1d54bbe0670606733a7bbcde99..da8f1bc7d9c7d8c4979abdee873c9168a0745361 100644 --- a/src/test/runTest.ts +++ b/src/test/runTest.ts @@ -1,23 +1,22 @@ -import * as path from 'path'; +import * as path from 'path' -import { runTests } from '@vscode/test-electron'; +import { runTests } from 'vscode-test' async function main() { try { // The folder containing the Extension Manifest package.json // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../../'); + const extensionDevelopmentPath = path.resolve(__dirname, '../../') // The path to test runner // Passed to --extensionTestsPath - const extensionTestsPath = path.resolve(__dirname, './suite/index'); - + const extensionTestsPath = path.resolve(__dirname, './suite/index') // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); + await runTests({ extensionDevelopmentPath, extensionTestsPath }) } catch (err) { - console.error('Failed to run tests'); - process.exit(1); + console.error('Failed to run tests') + process.exit(1) } } -main(); +main() diff --git a/src/test/suite/extension.test.ts b/src/test/suite/extension.test.ts index 4ca0ab419826dfd117400aa7547eb48d4022d89b..4d7524a3eb3e7c791131f8280cf80ecfb91305fb 100644 --- a/src/test/suite/extension.test.ts +++ b/src/test/suite/extension.test.ts @@ -1,15 +1,15 @@ -import * as assert from 'assert'; +import * as assert from 'assert' // You can import and use all API from the 'vscode' module // as well as import your extension to test it -import * as vscode from 'vscode'; +import * as vscode from 'vscode' // import * as myExtension from '../../extension'; suite('Extension Test Suite', () => { - vscode.window.showInformationMessage('Start all tests.'); + vscode.window.showInformationMessage('Start all tests.') test('Sample test', () => { - assert.strictEqual(-1, [1, 2, 3].indexOf(5)); - assert.strictEqual(-1, [1, 2, 3].indexOf(0)); - }); -}); + assert.equal(-1, [1, 2, 3].indexOf(5)) + assert.equal(-1, [1, 2, 3].indexOf(0)) + }) +}) diff --git a/src/test/suite/index.ts b/src/test/suite/index.ts index 7029e38ed315f25cad18db00c7334c47e00ad7fd..aaa4445ca2b4bee5e24326007a34b53e2e97cd70 100644 --- a/src/test/suite/index.ts +++ b/src/test/suite/index.ts @@ -1,38 +1,38 @@ -import * as path from 'path'; -import * as Mocha from 'mocha'; -import * as glob from 'glob'; +import * as path from 'path' +import * as Mocha from 'mocha' +import * as glob from 'glob' export function run(): Promise { // Create the mocha test const mocha = new Mocha({ ui: 'tdd', - color: true - }); + color: true, + }) - const testsRoot = path.resolve(__dirname, '..'); + const testsRoot = path.resolve(__dirname, '..') return new Promise((c, e) => { glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { if (err) { - return e(err); + return e(err) } // Add files to the test suite - files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); + files.forEach((f) => mocha.addFile(path.resolve(testsRoot, f))) try { // Run the mocha test - mocha.run(failures => { + mocha.run((failures) => { if (failures > 0) { - e(new Error(`${failures} tests failed.`)); + e(new Error(`${failures} tests failed.`)) } else { - c(); + c() } - }); + }) } catch (err) { - console.error(err); - e(err); + console.error(err) + e(err) } - }); - }); + }) + }) } diff --git a/src/test/suite/util.test.ts b/src/test/suite/util.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..1fcc719450f093b91f5337129a8c223ea4bec477 --- /dev/null +++ b/src/test/suite/util.test.ts @@ -0,0 +1,130 @@ +import * as assert from 'assert' + +// You can import and use all API from the 'vscode' module +// as well as import your extension to test it +// import * as myExtension from '../../extension'; +import { getTestCaseList, unionArr } from '../../common/util' +import { addComment } from '../../common/transformCode' + +interface UnionArrDemo { + params: T[][] + result: T[] +} +const cases = [ + `// @algorithm @lc id=1576 lang=javascript weekname=weekly-contest-191 +// @title reorder-routes-to-make-all-paths-lead-to-the-city-zero + +// @test(6,[[0,1],[1,3],[2,3],[4,0],[4,5]])=3 +// @test(5,[[1,0],[1,2],[3,2],[3,4]])=2 +// @test(3,[[1,0],[2,0]])=0 +/** + * @param {number} n + * @param {number[][]} connections + * @return {number} + */ +var minReorder = function (n, connections) { +} +`, + `// @algorithm + +//@test([1,2]) +/** + * @param {TreeNode} root + * @return {void} + */ +var func = function(root) { +} +`, + `// @algorithm + +// @test([4,2,7,1,3],2)=[2,1,3] +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @param {number} val + * @return {TreeNode} + */ +var searchBST = function (root, val) { +};`, +] +suite('Util Test Suite', () => { + test('test getTestCaseList', () => { + const testCaseList = getTestCaseList(cases[0]) + assert.equal(testCaseList.length, 1) + const { testCase, funcName, paramsTypes, resultType } = testCaseList[0] + assert.deepEqual(testCase, [ + '// @test(6,[[0,1],[1,3],[2,3],[4,0],[4,5]])=3', + '// @test(5,[[1,0],[1,2],[3,2],[3,4]])=2', + '// @test(3,[[1,0],[2,0]])=0', + ]) + assert.equal(funcName, 'minReorder') + assert.deepEqual(paramsTypes, ['number', 'number[][]']) + assert.equal(resultType, 'number') + }) + test('test void return', () => { + const testCaseList = getTestCaseList(cases[1]) + const { paramsTypes, resultType } = testCaseList[0] + assert.equal(testCaseList.length, 1) + assert.equal(resultType, 'void') + assert.deepEqual(paramsTypes, ['TreeNode']) + }) + test('test ', () => { + const testCaseList = getTestCaseList(cases[2]) + assert.equal(testCaseList.length, 1) + // assert.equal(resultType, 'void') + // assert.deepEqual(paramsTypes, ['TreeNode']) + }) + test('test add comment', () => { + const source = ` + //this is a test + /** + * this is a test too + */ + function main() { + + } + ` + const result = ` + //hhh + //this is a test + /** + * this is a test too + */ + function main() { + + } + ` + const out = addComment(source, 'hhh', 'main') + assert.deepStrictEqual(out, result) + }) + test('test unionArr', () => { + const list: UnionArrDemo[] = [ + { + params: [ + ['xiao', 'li'], + ['li', 'wang'], + ], + result: ['xiao', 'li', 'wang'], + }, + { + params: [['xiao', 'li'], []], + result: ['xiao', 'li'], + }, + { + params: [[], []], + result: [], + }, + { + params: [[], ['abc']], + result: ['abc'], + }, + ] + list.forEach(({ params, result }) => assert.deepStrictEqual(unionArr(params[0], params[1]), result)) + }) +}) diff --git a/src/test/unit/fileStorage.test.ts b/src/test/unit/fileStorage.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..7c0514bb603e64292e8485f4eab536dbaf3bd2ec --- /dev/null +++ b/src/test/unit/fileStorage.test.ts @@ -0,0 +1,58 @@ +import * as assert from 'assert' + +// You can import and use all API from the 'vscode' module +// as well as import your extension to test it +// import * as myExtension from '../../extension'; +import { crc32 } from '../../fileStorage/util' +import { convertToObj, convertToBuffer, Field } from '../../fileStorage/db' +interface FieldData { + v: number + h: string +} +suite('test file storage', () => { + test('test crc32', () => { + const data = Buffer.from([0x61, 0x62, 0x63]) + + const result = crc32(data) + assert.equal(result, 0x352441c2) + }) + test('test convertToObj', () => { + const config: Field[] = [ + { + field: 'v', + type: 'int', + len: 16, + }, + { + field: 'h', + type: 'hex', + len: 32, + }, + ] + const buffer = Buffer.from([0x00, 0x11, 0x00, 0x12, 0xab, 0xcd]) + const result = convertToObj(buffer, config) + assert.equal(result.v, 17) + assert.equal(result.h, '0012abcd') + }) + test('test convertToBuffer', () => { + const config: Field[] = [ + { + field: 'v', + type: 'int', + len: 16, + }, + { + field: 'h', + type: 'hex', + len: 32, + }, + ] + const obj: FieldData = { + v: 17, + h: '0012abcd', + } + const buffer = Buffer.from([0x00, 0x11, 0x00, 0x12, 0xab, 0xcd]) + const result = convertToBuffer(obj, config) + assert.deepEqual(result, buffer) + }) +}) diff --git a/src/test/unit/test.ts b/src/test/unit/test.ts new file mode 100644 index 0000000000000000000000000000000000000000..9ded804d7a31fee4868f596acbdee808f2fffab4 --- /dev/null +++ b/src/test/unit/test.ts @@ -0,0 +1,34 @@ +import * as assert from 'assert' + +// You can import and use all API from the 'vscode' module +// as well as import your extension to test it +// import * as myExtension from '../../extension'; +import { getTestCaseList } from '../../common/util' +const cases = [ + `// @algorithm @lc id=1576 lang=javascript weekname=weekly-contest-191 +// @title reorder-routes-to-make-all-paths-lead-to-the-city-zero + +// @test(6,[[0,1],[1,3],[2,3],[4,0],[4,5]])=3 +// @test(5,[[1,0],[1,2],[3,2],[3,4]])=2 +// @test(3,[[1,0],[2,0]])=0 +/** + * @param {number} n + * @param {number[][]} connections + * @return {number} + */ +var minReorder = function (n, connections) { +} +`, +] +suite('Util Test Suite', () => { + test('test getTestCaseList', () => { + const testCaseList = getTestCaseList(cases[0]) + assert.equal(testCaseList.length, 1) + const { testCase } = testCaseList[0] + assert.deepEqual(testCase, [ + '// @test(6,[[0,1],[1,3],[2,3],[4,0],[4,5]])=3', + '// @test(5,[[1,0],[1,2],[3,2],[3,4]])=2', + '// @test(3,[[1,0],[2,0]])=0', + ]) + }) +}) diff --git a/src/util.ts b/src/util.ts new file mode 100644 index 0000000000000000000000000000000000000000..9552c102ef49bd7b547a2fc33b21306cc9e5e377 --- /dev/null +++ b/src/util.ts @@ -0,0 +1,237 @@ +import * as vscode from 'vscode' +import { window } from 'vscode' +import { transformAsync } from '@babel/core' +import { generateAddTestCommentPlugin } from './babelPlugin' +import { langMap, getFileLang, CodeLang, ExtraType, transformToHightlightLang } from './common/langConfig' +import { ParseContent } from './common/parseContent' +import { config, updateConfig, updateEnv, InstallState, log, checkEsbuildDir } from './config' +import { tag } from 'pretty-tag' +import { AskForImportState, CodeSnippet, CommonQuestion, ConciseQuestion } from './model/common' +import { MemoFile } from './model/memo' +import { Service } from './lang/common' +import { LanguageMetaData, MetaData } from './common/lang' +// eslint-disable-next-line @typescript-eslint/no-var-requires +const hljs = require('highlight.js') + +// eslint-disable-next-line @typescript-eslint/no-var-requires +const md = require('markdown-it')({ + highlight: function (str, lang) { + if (lang && hljs.getLanguage(lang)) { + try { + return ( + '

' +
+					hljs.highlight(str, {
+						language: lang,
+						ignoreIllegals: true,
+					}).value +
+					'
' + ) + } catch (err) { + log.appendLine('highlight code error') + } + } + + return '
' + md.utils.escapeHtml(str) + '
' + }, +}) +export const highlightCode = (code: string, lang: string) => + md.render(`\`\`\`${transformToHightlightLang(lang)}\n${code}\n\`\`\``) +export async function execWithProgress(promise: Promise, message: string): Promise { + return window.withProgress({ location: vscode.ProgressLocation.Notification }, (p) => { + p.report({ message }) + return promise + }) +} +export async function execWithProgress2(promise: Promise, message: string): Promise { + return window.withProgress({ location: vscode.ProgressLocation.Window }, (p) => { + p.report({ message }) + return promise + }) +} +export async function appendComment(code: string, comment: string, funcName: string) { + const fileResult = await transformAsync(code, { + // comments: true, + // compact: false, + plugins: [generateAddTestCommentPlugin(funcName, comment)], + }) + return fileResult?.code +} + +const extraTypeValues = [ExtraType.ListNode, ExtraType.TreeNode] + +export function shouldAskForImport(): boolean { + return !config.hasAskForImport && config.env.askForImportState === AskForImportState.Later && !config.autoImportAlgm +} +export async function askForImport() { + config.hasAskForImport = true + const r = await window.showInformationMessage( + 'Would you like to import the algm module?', + AskForImportState.Yes, + AskForImportState.No, + AskForImportState.Later + ) + switch (r) { + case AskForImportState.Yes: { + updateConfig('autoImportAlgm', true, true) + updateEnv('askForImportState', AskForImportState.Yes) + break + } + case AskForImportState.No: { + updateConfig('autoImportAlgm', false, true) + updateEnv('askForImportState', AskForImportState.No) + break + } + } +} +function getExtraTypeSet(metaData: LanguageMetaData) { + const arr: Set = new Set() + const params = metaData.params + const r = metaData.return + params.forEach((p) => { + extraTypeValues.forEach((e) => { + if (p.type.includes(e)) { + arr.add(e) + } + }) + }) + extraTypeValues.forEach((e) => { + if (r.type.includes(e)) { + arr.add(e) + } + }) + return arr +} +function getImportStr(metaData: LanguageMetaData) { + const arr = getExtraTypeSet(metaData) + if (arr.size) { + return `import { ${[...arr].join(', ')} } from 'algm'` + } + return '' +} + +function isLanguageMetaData(metaData: MetaData): metaData is LanguageMetaData { + return 'name' in metaData +} +export function preprocessCode( + { questionId, metaData, content, titleSlug, questionSourceContent }: CommonQuestion, + weekname = '', + codeSnippet: CodeSnippet, + name: string +) { + const testCases = ParseContent.getTestCases(questionSourceContent || content) + const langSlug = codeSnippet.langSlug + const langConfig = langMap[langSlug] + const weektag = weekname ? `weekname=${weekname}` : '' + + const metaDataParse: MetaData = JSON.parse(metaData) + const LcComment = tag` + ${langConfig.comment} @algorithm @lc id=${questionId} lang=${langSlug} ${weektag} + ${langConfig.comment} @title ${titleSlug} + ` + if (!isLanguageMetaData(metaDataParse)) { + return LcComment + } + const supportImport = ['JavaScript', 'TypeScript'].includes(langConfig.lang) + const shouldImport = supportImport && config.autoImportAlgm + const importStr = shouldImport ? `import * as a from 'algm'\n` + getImportStr(metaDataParse) : '' + const autoImportStr = config.autoImportStr || '' + const preImport = Service.getPreImport(langConfig.lang, name, getExtraTypeSet(metaDataParse)) + const flag = tag` + ${LcComment} + ${importStr} + ${autoImportStr} + ${preImport} + ` + + let codeTestSnippet = '' + try { + codeTestSnippet = testCases + .map((testCase) => { + const pa = metaDataParse.params + .map((param, i) => { + const input = testCase.input.find(({ key }) => key === param.name) + if (input) { + return input.value + } else { + return testCase.input[i].value + } + }) + .join(',') + return `${langConfig.comment} @test(${pa})=${testCase.output}\n` + }) + .join('') + } catch (err) { + console.log(err) + } + + const code = codeSnippet.code + const newCode = flag + '\n' + codeTestSnippet + code + return newCode +} +export function getDebugConfig() { + const { nodeBinPath } = config + + return { + type: 'node', + request: 'launch', + name: 'debug question', + skipFiles: ['/**'], + program: '${workspaceFolder}/out/code.js', + outFiles: ['${workspaceFolder}/out/*.js'], + runtimeVersion: 'default', + runtimeExecutable: nodeBinPath, + sourceMaps: true, + args: ['${file}'], + preLaunchTask: 'algorithm: build', + } +} + +export function checkBeforeDebug(filePath: string): boolean { + const lang = getFileLang(filePath) + if (lang === CodeLang.TypeScript) { + if (InstallState.installEsbuild || !checkEsbuildDir()) { + log.appendLine('wait downloading esbuild') + return false + } + } + return true +} + +export function sortFiles(files: MemoFile[]) { + files.sort((q1, q2) => { + const fid1: string = q1.name + const fid2: string = q2.name + const sortOrder = ['LCP', '剑指 Offer', '面试题'] + const weight1 = sortOrder.findIndex((prefix) => fid1.startsWith(prefix)) + const weight2 = sortOrder.findIndex((prefix) => fid2.startsWith(prefix)) + if (weight1 !== weight2) { + return weight1 - weight2 + } else { + if (weight1 !== -1) { + return fid1.localeCompare(fid2) + } + return parseInt(fid1) - parseInt(fid2) + } + }) +} +export function sortQuestions(questions: ConciseQuestion[]) { + questions.sort((q1, q2) => { + const fid1: string = q1.fid + const fid2: string = q2.fid + const sortOrder = ['LCP', '剑指 Offer', '面试题'] + const weight1 = sortOrder.findIndex((prefix) => fid1.startsWith(prefix)) + const weight2 = sortOrder.findIndex((prefix) => fid2.startsWith(prefix)) + if (weight1 !== weight2) { + return weight1 - weight2 + } else { + if (weight1 !== -1) { + return fid1.localeCompare(fid2) + } + return parseInt(fid1) - parseInt(fid2) + } + }) +} +export function reRequire(moduleName: string) { + delete require.cache[moduleName] + return require(moduleName) +} diff --git a/src/webview/buildCodeWebview.ts b/src/webview/buildCodeWebview.ts new file mode 100644 index 0000000000000000000000000000000000000000..db7f62957c9005ea190b09928c523d8a943531be --- /dev/null +++ b/src/webview/buildCodeWebview.ts @@ -0,0 +1,155 @@ +import * as path from 'path' +import * as vscode from 'vscode' +import { Clipboard, env } from 'vscode' +import { highlightCode } from '../util' +// eslint-disable-next-line @typescript-eslint/no-var-requires + +class BuildCodePanel { + /** + * Track the currently panel. Only allow a single panel to exist at a time. + */ + public static currentPanel: BuildCodePanel | undefined + private static readonly buildCodeActiveContextKey = 'buildCodeFocus' + public static readonly viewType = 'buildCodeView' + + private readonly _panel: vscode.WebviewPanel + private readonly _extensionPath: string + private context: vscode.ExtensionContext + public text: string + public langSlug: string + private clipboard: Clipboard = env.clipboard + private _disposables: vscode.Disposable[] = [] + public static commands = new Map() + private setbuildCodeActiveContext(value: boolean) { + vscode.commands.executeCommand('setContext', BuildCodePanel.buildCodeActiveContextKey, value) + } + private registerCommand(id: string, impl: (...args: unknown[]) => void, thisArg?: unknown) { + if (!BuildCodePanel.commands.get(id)) { + const dispose = vscode.commands.registerCommand(id, impl, thisArg) + this.context.subscriptions.push(dispose) + BuildCodePanel.commands.set(id, dispose) + } + } + public static createOrShow(context: vscode.ExtensionContext, text: string, langSlug: string) { + const column = vscode.ViewColumn.Two + const extensionPath = context.extensionPath + // If we already have a panel, show it. + + if (BuildCodePanel.currentPanel) { + BuildCodePanel.currentPanel._panel.reveal(column) + BuildCodePanel.currentPanel.update(text, langSlug) + return + } + + // Otherwise, create a new panel. + const panel = vscode.window.createWebviewPanel(BuildCodePanel.viewType, 'code', vscode.ViewColumn.Two, { + // Enable javascript in the webview + enableScripts: true, + localResourceRoots: [vscode.Uri.file(path.join(extensionPath, 'media'))], + }) + + BuildCodePanel.currentPanel = new BuildCodePanel(panel, context, text, langSlug) + } + + private constructor(panel: vscode.WebviewPanel, context: vscode.ExtensionContext, text: string, langSlug: string) { + this._panel = panel + this._extensionPath = context.extensionPath + this.context = context + this.text = text + this.langSlug = langSlug + this.registerCommand('algorithm.copyCode', () => { + this.clipboard.writeText(this.text) + }) + + this.initView() + // Set the webview's initial html content + this._update() + + // Listen for when the panel is disposed + // This happens when the user closes the panel or when the panel is closed programatically + this._panel.onDidDispose(() => this.dispose(), null, this._disposables) + + // Update the content based on view changes + this._panel.onDidChangeViewState( + (e) => { + this.setbuildCodeActiveContext(e.webviewPanel.active) + if (e.webviewPanel.active) { + this._update() + } + }, + null, + this._disposables + ) + } + + public dispose() { + BuildCodePanel.currentPanel = undefined + + // Clean up our resources + this._panel.dispose() + this.setbuildCodeActiveContext(false) + while (this._disposables.length) { + const x = this._disposables.pop() + if (x) { + x.dispose() + } + } + } + public update(text: string, langSlug: string) { + this.text = text + this.langSlug = langSlug + this._update() + } + private getWebviewUri(name: string) { + const webview = this._panel.webview + const scriptPathOnDisk = vscode.Uri.file(path.join(this._extensionPath, 'media', name)) + return webview.asWebviewUri(scriptPathOnDisk) + } + private initView() { + const nonce = getNonce() + + // And the uri we use to load this script in the webview + const buildCodeUri = this.getWebviewUri('buildcode.js') + const scriptUri = this.getWebviewUri('highlight.min.js') + const cssUri = this.getWebviewUri('highlight.css') + this._panel.webview.html = ` + + + + + + + Cat Coding + + + +
+
+ + + + + ` + } + private _update() { + this.setbuildCodeActiveContext(true) + const code = highlightCode(this.text, this.langSlug) + this._panel.webview.postMessage({ command: 'newCode', data: code }) + } +} + +function getNonce() { + let text = '' + const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' + for (let i = 0; i < 32; i++) { + text += possible.charAt(Math.floor(Math.random() * possible.length)) + } + return text +} + +export function createPanel(context: vscode.ExtensionContext, text: string, langSlug: string) { + BuildCodePanel.createOrShow(context, text, langSlug) +} diff --git a/src/webview/questionPreview.ts b/src/webview/questionPreview.ts new file mode 100644 index 0000000000000000000000000000000000000000..66f57bb9be12c5e312571820e767e28877532fdb --- /dev/null +++ b/src/webview/questionPreview.ts @@ -0,0 +1,322 @@ +import * as path from 'path' +import * as vscode from 'vscode' +import { api } from '../api/index' +import { config } from '../config' +import { writeFile, parseHtml } from '../common/util' +import { preprocessCode, shouldAskForImport, askForImport } from '../util' +import { CodeLang, enNameLangs, isAlgorithm, langMap } from '../common/langConfig' +import { Service } from '../lang/common' +import { pathExists } from 'fs-extra' +import { getSolution } from '../common/website' +import { CodeSnippet, CommonQuestion } from '../model/common' +export const QuestionPreview = 'algorithm.questionPreview' + +// eslint-disable-next-line @typescript-eslint/no-var-requires +const md = require('markdown-it')({ + html: true, + inkify: true, + typographer: true, +}) + +function getNonce() { + let text = '' + const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' + for (let i = 0; i < 32; i++) { + text += possible.charAt(Math.floor(Math.random() * possible.length)) + } + return text +} +// type Param = Pick +interface Param { + titleSlug?: string + weekname?: string + questionId?: number | string + itemId?: string +} +export async function fetchQuestion(param: Param): Promise { + let { titleSlug, weekname, questionId: id, itemId } = param + let data: string + let question: CommonQuestion | null = null + if (itemId) { + const q = await api.fetchQuestionByItemId(itemId) + if (q) { + id = q.questionId + titleSlug = q.titleSlug + } + } + if (id) { + question = await api.fetchQuestionDetailById(id) + } + + if (!question && titleSlug) { + if (weekname) { + data = await api.fetchContestQuestionDetail(titleSlug, weekname) + question = parseHtml(data) + } else { + question = await api.fetchQuestionDetail(titleSlug) + } + if (question) { + api.saveQuestionDetail(question) + } + } + return question +} +function getCodeSnippet(codeSnippets) { + const langTypes = [config.codeLang, config.database] + for (const defaultLang of langTypes) { + const codeSnippet = codeSnippets.find((codeSnippet) => codeSnippet.lang === defaultLang) + if (codeSnippet) { + return codeSnippet + } + } + return codeSnippets[0] +} +export function getName( + questionFrontendId: string, + title: string, + translatedTitle: string, + codeSnippet: CodeSnippet +): { + filePath: string + name: string + filename: string +} { + const langSlug = codeSnippet.langSlug + const langConfig = langMap[langSlug] + let filename = questionFrontendId + langConfig.fileNameSep + title + langConfig.ext + if (config.lang === 'cn' && !enNameLangs.includes(langConfig.lang)) { + filename = questionFrontendId + langConfig.fileNameSep + translatedTitle + langConfig.ext + } + const questionDir = path.join(config.algDir, codeSnippet.lang) + + let filePath = path.join(questionDir, filename) + let name = path.parse(filename).name + if (langConfig.lang === CodeLang.Go) { + filePath = path.join(questionDir, name, 'solution.go') + } else if (langConfig.lang === CodeLang.Java) { + name = '_' + name.replace(/\./, '_') + name = name.replace(/[^\w]/g, '_') + filePath = path.join(questionDir, name, 'Solution.java') + } else if (langConfig.lang === CodeLang['C++']) { + name = name.replace(/[^\w]/g, '_') + filePath = path.join(questionDir, 'question', name + '.cpp') + } + return { + filePath, + name, + filename, + } +} + +class QuestionPreviewPanel { + /** + * Track the currently panel. Only allow a single panel to exist at a time. + */ + public static currentPanel: QuestionPreviewPanel | undefined + private static readonly buildCodeActiveContextKey = 'questionPreviewFocus' + public static readonly viewType = 'questionPreview' + public static readonly commandText = QuestionPreview + private readonly _panel: vscode.WebviewPanel + private readonly _extensionPath: string + public text: string + public titleSlug: string + private _disposables: vscode.Disposable[] = [] + public static commands = new Map() + private setbuildCodeActiveContext(value: boolean) { + vscode.commands.executeCommand('setContext', QuestionPreviewPanel.buildCodeActiveContextKey, value) + } + + public static createOrShow(extensionPath: string, text: string, titleSlug: string) { + const column = vscode.ViewColumn.Two + // If we already have a panel, show it. + + if (QuestionPreviewPanel.currentPanel) { + QuestionPreviewPanel.currentPanel._panel.reveal(column) + QuestionPreviewPanel.currentPanel.update(text, titleSlug) + return + } + + // Otherwise, create a new panel. + const panel = vscode.window.createWebviewPanel(QuestionPreviewPanel.viewType, 'algorithm', column, { + // Enable javascript in the webview + enableScripts: true, + // And restrict the webview to only loading content from our extension's `media` directory. + localResourceRoots: [vscode.Uri.file(path.join(extensionPath, 'media'))], + }) + + QuestionPreviewPanel.currentPanel = new QuestionPreviewPanel(panel, extensionPath, text, titleSlug) + } + + private constructor(panel: vscode.WebviewPanel, extensionPath: string, text: string, titleSlug: string) { + this._panel = panel + this._extensionPath = extensionPath + // QuestionPreviewPanel._text = text; + this.text = text + this.titleSlug = titleSlug + // Set the webview's initial html content + this._update() + + // Listen for when the panel is disposed + // This happens when the user closes the panel or when the panel is closed programatically + this._panel.onDidDispose(() => this.dispose(), null, this._disposables) + + // Update the content based on view changes + this._panel.onDidChangeViewState( + (e) => { + this.setbuildCodeActiveContext(e.webviewPanel.active) + if (this._panel.visible) { + this._update() + } + }, + null, + this._disposables + ) + + // Handle messages from the webview + this._panel.webview.onDidReceiveMessage( + (message) => { + switch (message.command) { + case 'alert': + vscode.window.showErrorMessage(message.text) + return + } + }, + null, + this._disposables + ) + } + + public doRefactor() { + // Send a message to the webview webview. + // You can send any JSON serializable data. + this._panel.webview.postMessage({ command: 'refactor' }) + } + + public dispose() { + QuestionPreviewPanel.currentPanel = undefined + + // Clean up our resources + this._panel.dispose() + this.setbuildCodeActiveContext(false) + while (this._disposables.length) { + const x = this._disposables.pop() + if (x) { + x.dispose() + } + } + } + public update(text: string, titleSlug: string) { + this.text = text + this.titleSlug = titleSlug + this._update() + } + private _update() { + this.setbuildCodeActiveContext(true) + const webview = this._panel.webview + const nonce = getNonce() + // const scriptPathOnDisk = vscode.Uri.file( + // path.join(this._extensionPath, 'media', 'highlight.min.js') + // ) + const cssPathOnDisk = vscode.Uri.file(path.join(this._extensionPath, 'media', 'highlight.css')) + const cssMdOnDisk = vscode.Uri.file(path.join(this._extensionPath, 'media', 'markdown.css')) + const text = this.text + const titleSlug = this.titleSlug + const solutionUrl = getSolution(titleSlug) + // let temp = QuestionPreviewPanel._text; + const temp = text.replace(/
/g, '
').replace(/<\/pre>/g, '
') + const code = md.render(temp) + const cssUri = webview.asWebviewUri(cssPathOnDisk) + const cssMd = webview.asWebviewUri(cssMdOnDisk) + this._panel.webview.html = ` + + + + + + + Cat Coding + + + + + + ${code} +
+
+ Solution + + + ` + } +} +export async function createQuestionPanelCommand(extensionPath: string, param: Param): Promise { + const { weekname } = param + try { + const question = await fetchQuestion(param) + + if (question) { + const { codeSnippets, questionFrontendId, title, content, translatedContent, translatedTitle, titleSlug } = + question + //preview + let previewText = `# ${title}\n` + content + if (config.lang === 'cn') { + previewText = `# ${translatedTitle}\n` + translatedContent + } + + const codeSnippet = getCodeSnippet(codeSnippets) + + const langSlug = codeSnippet.langSlug + const langConfig = langMap[langSlug] + + //generate code + const { filePath, name } = getName(questionFrontendId, title, translatedTitle, codeSnippet) + const exist = await pathExists(filePath) + + if (!exist) { + const supportImport = ['JavaScript', 'TypeScript'].includes(langConfig.lang) + if (supportImport && shouldAskForImport()) { + askForImport() + } + let code = preprocessCode(question, weekname, codeSnippet, name) + if (langConfig.lang === CodeLang.Java) { + code = code.replace('class Solution', 'public class Solution') + } + if (isAlgorithm(langConfig.lang)) { + await Service.handlePreImport(filePath) + } + + await writeFile(filePath, code) + } + const fileDocument = await vscode.workspace.openTextDocument(filePath) + await vscode.window.showTextDocument(fileDocument, vscode.ViewColumn.One) + QuestionPreviewPanel.createOrShow(extensionPath, previewText, titleSlug) + } else { + console.log('parse question error:', question) + } + + return + } catch (err) { + console.log(err) + } +} +export async function getQuestionDescription(extensionPath: string, param: Param): Promise { + const question = await fetchQuestion(param) + if (question) { + const { title, content, translatedContent, translatedTitle, titleSlug } = question + //preview + let previewText = `# ${title}\n` + content + if (config.lang === 'cn') { + previewText = `# ${translatedTitle}\n` + translatedContent + } + QuestionPreviewPanel.createOrShow(extensionPath, previewText, titleSlug) + } else { + console.log('question not found') + } +} diff --git a/src/webview/submitHistory.ts b/src/webview/submitHistory.ts new file mode 100644 index 0000000000000000000000000000000000000000..a93ec1e9133d7f115fefcf1e3a8bfd7a0b46c91f --- /dev/null +++ b/src/webview/submitHistory.ts @@ -0,0 +1,209 @@ +import * as path from 'path' +import * as vscode from 'vscode' +import { api } from '../api/index' +import { config } from '../config' +import { getHistory, getRemoteSubmits, updateComment } from '../history' +import { highlightCode } from '../util' + +class BuildSubmitHistoryPanel { + /** + * Track the currently panel. Only allow a single panel to exist at a time. + */ + public static currentPanel: BuildSubmitHistoryPanel | undefined + public static readonly viewType = 'submitHistoryView' + + private readonly _panel: vscode.WebviewPanel + private readonly _extensionPath: string + private context: vscode.ExtensionContext + public static _text: string + private _disposables: vscode.Disposable[] = [] + public static commands = new Map() + private question_id: string + + public static createOrShow(context: vscode.ExtensionContext, question_id: string) { + const column = vscode.ViewColumn.Two + const extensionPath = context.extensionPath + // If we already have a panel, show it. + + if (BuildSubmitHistoryPanel.currentPanel) { + BuildSubmitHistoryPanel.currentPanel._panel.reveal(column) + BuildSubmitHistoryPanel.currentPanel.update(question_id) + return + } + + // Otherwise, create a new panel. + const panel = vscode.window.createWebviewPanel( + BuildSubmitHistoryPanel.viewType, + 'history', + vscode.ViewColumn.Two, + { + // Enable javascript in the webview + enableScripts: true, + localResourceRoots: [vscode.Uri.file(path.join(extensionPath, 'media'))], + } + ) + + BuildSubmitHistoryPanel.currentPanel = new BuildSubmitHistoryPanel(panel, context, question_id) + } + + private constructor(panel: vscode.WebviewPanel, context: vscode.ExtensionContext, question_id: string) { + this._panel = panel + this._extensionPath = context.extensionPath + this.context = context + this.question_id = question_id + this.initView() + this._update() + // Listen for when the panel is disposed + // This happens when the user closes the panel or when the panel is closed programatically + this._panel.onDidDispose(() => this.dispose(), null, this._disposables) + this._panel.webview.onDidReceiveMessage( + (message) => { + switch (message.command) { + case 'getSubmissionCode': + api.fetchSubmissionDetail({ id: message.id }) + .then((code) => { + const p = highlightCode(code, message.lang) + console.log(p) + this._panel.webview.postMessage({ + command: 'submissionDetail', + data: { + code: highlightCode(code, message.lang), + id: message.id, + uuid: message.uuid, + }, + }) + }) + .catch((err) => { + this._panel.webview.postMessage({ + command: 'submissionDetail', + data: { + code: err, + id: message.id, + uuid: message.uuid, + }, + }) + }) + return + case 'updateComment': { + updateComment(message.type, message.params) + .then(() => { + this._panel.webview.postMessage({ + command: 'updateComment', + data: { + code: 200, + msg: 'ok', + uuid: message.uuid, + }, + }) + }) + .catch((err) => { + this._panel.webview.postMessage({ + command: 'updateComment', + data: { + code: 201, + msg: 'update fail', + uuid: message.uuid, + }, + }) + config.log.appendLine(err) + }) + } + } + }, + null, + this._disposables + ) + } + + public dispose() { + BuildSubmitHistoryPanel.currentPanel = undefined + + // Clean up our resources + this._panel.dispose() + while (this._disposables.length) { + const x = this._disposables.pop() + if (x) { + x.dispose() + } + } + } + public update(question_id: string) { + if (question_id !== this.question_id) { + this.question_id = question_id + // BuildSubmitHistoryPanel._text = text; + + this._update() + } + } + private getWebviewUri(name: string) { + const webview = this._panel.webview + const scriptPathOnDisk = vscode.Uri.file(path.join(this._extensionPath, 'media', name)) + return webview.asWebviewUri(scriptPathOnDisk) + } + private initView() { + const nonce = getNonce() + + const historyUri = this.getWebviewUri('history.js') + const scriptUri = this.getWebviewUri('highlight.min.js') + const cssUri = this.getWebviewUri('highlight.css') + const historyCssUri = this.getWebviewUri('history.css') + this._panel.webview.html = ` + + + + + + + Cat Coding + + + + + +
+
+ + + + + + ` + } + private async _update() { + const question_id = this.question_id + const data = await getHistory(question_id, highlightCode) + this._panel.webview.postMessage({ command: 'init', data: data }) + getRemoteSubmits(question_id).then((data) => { + this._panel.webview.postMessage({ + command: 'remoteStorageData', + data: data, + }) + }) + } +} + +function getNonce() { + let text = '' + const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' + for (let i = 0; i < 32; i++) { + text += possible.charAt(Math.floor(Math.random() * possible.length)) + } + return text +} + +export function createSubmitHistoryPanel(context: vscode.ExtensionContext, question_id: string): void { + BuildSubmitHistoryPanel.createOrShow(context, question_id) +} diff --git a/template/cpp/ListNode.h b/template/cpp/ListNode.h new file mode 100644 index 0000000000000000000000000000000000000000..384b628726a748881afc7ad6895b663f19e8f3f1 --- /dev/null +++ b/template/cpp/ListNode.h @@ -0,0 +1,12 @@ + +//Definition for singly-linked list. +#ifndef _LISTNODE +#define _LISTNODE +struct ListNode { + int val; + ListNode *next; + ListNode() : val(0), next(nullptr) {} + ListNode(int x) : val(x), next(nullptr) {} + ListNode(int x, ListNode *next) : val(x), next(next) {} +}; +#endif \ No newline at end of file diff --git a/template/cpp/TreeNode.h b/template/cpp/TreeNode.h new file mode 100644 index 0000000000000000000000000000000000000000..9676e14309ae2405ab10ee13bbed453aa70eddde --- /dev/null +++ b/template/cpp/TreeNode.h @@ -0,0 +1,14 @@ + +// Definition for a binary tree node. +#ifndef _TREENODE +#define _TREENODE +struct TreeNode +{ + int val; + TreeNode *left; + TreeNode *right; + TreeNode() : val(0), left(nullptr), right(nullptr) {} + TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} + TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} +}; +#endif \ No newline at end of file diff --git a/template/cpp/algm.h b/template/cpp/algm.h new file mode 100644 index 0000000000000000000000000000000000000000..b385bb45e59a2c625cd0e47c2087ee6950820a3e --- /dev/null +++ b/template/cpp/algm.h @@ -0,0 +1,2 @@ +#include "ListNode.h" +#include "TreeNode.h" \ No newline at end of file diff --git a/template/cpp/parse.h b/template/cpp/parse.h new file mode 100644 index 0000000000000000000000000000000000000000..5018d09ac71c47c7162c9e744f7e082039650d67 --- /dev/null +++ b/template/cpp/parse.h @@ -0,0 +1,587 @@ +#include +#include +#include +#include +#include +#include "algm.h" +// #include "ListNode.h" +// #include "TreeNode.h" +using namespace std; + +void split(string param, char seg, vector &arr) +{ + string temp = ""; + for (auto it = param.begin(); it != param.end(); it++) + { + if (*it == seg) + { + arr.push_back(temp); + temp = ""; + } + else + { + temp += *it; + } + } + arr.push_back(temp); +} +int parseInteger(string param) +{ + return atoi(param.data()); +} +double parseFloat(string param) +{ + string::size_type size; + return stod(param, &size); +} +string serializeFloat(double param) +{ + string str = to_string(param); + return str.substr(0, str.length() - 1); +} +string serializeBool(bool t) +{ + if (t == true) + { + return "true"; + } + return "false"; +} +vector parseIntegerArr(string param) +{ + vector nums; + if (param.length() <= 2) + { + return nums; + } + string temp = ""; + string::iterator it; + for (it = param.begin() + 1; it != param.end() - 1; it++) + { + if (*it == ',') + { + nums.push_back(stoi(temp)); + temp = ""; + } + else + { + temp += *it; + } + } + if (temp != "") + { + nums.push_back(stoi(temp)); + } + return nums; +} +vector> parseIntegerArrArr(string param) +{ + vector> nums; + int len = param.length(); + if (len <= 4) + { + return nums; + } + string subStr = param.substr(1, len - 2); + for (int i = 1; i < len - 1; i++) + { + if (param[i] == '[') + { + string temp = ""; + temp += param[i++]; + while (param[i] != ']') + { + temp += param[i++]; + } + temp += param[i++]; + vector arr = parseIntegerArr(temp); + nums.push_back(arr); + } + } + return nums; +} +string parseString(string param) +{ + if (param.length() <= 2) + { + return ""; + } + string out = ""; + string::iterator it; + for (int i = 1; i < param.length(); i++) + { + char c = param[i]; + if (c == '\\') + { + char n = param[i + 1]; + if (n == 'u') + { + string unicodeStr = param.substr(i + 2, 4); + char16_t num = strtol(unicodeStr.data(), NULL, 16); + out += num; + i += 5; + } + else + { + char echars[8] = {'"', '\\', '/', 'b', 'f', 'n', 'r', 't'}; + char realChars[8] = {'"', '\\', '/', '\b', '\f', '\n', '\r', '\t'}; + bool has = false; + for (int j = 0; j < 8; j++) + { + if (echars[j] == n) + { + has = true; + out += realChars[j]; + i++; + break; + } + } + if (!has) + { + throw "parse string error in " + param.substr(0, i + 1); + } + } + } + else if (c == '"') + { + return out; + } + else + { + out += c; + } + } + throw "parse string error in " + param; +} +vector parseStringArr(string param) +{ + vector strs; + int len = param.length(); + + if (len <= 2) + { + return strs; + } + regex e("\"(\\\\.|[^\"\\\\])*\""); + std::regex_iterator rit(param.begin(), param.end(), e); + std::regex_iterator rend; + + while (rit != rend) + { + string str = rit->str(); + strs.push_back(parseString(str)); + ++rit; + } + return strs; +} +vector> parseStringArrArr(string param) +{ + vector> strs; + int len = param.length(); + if (len <= 4) + { + return strs; + } + regex e("\"(\\\\.|[^\"\\\\])*\""); + regex_iterator rit(param.begin(), param.end(), e); + regex_iterator rend; + for (int i = 1; i < len - 1; i++) + { + if (param[i] == '[') + { + char nextChar = param[i + 1]; + string temp = "["; + i++; + while ((i < len - 1) && nextChar != ']') + { + + int start = rit->position(); + int end = start + rit->length(); + i = end; + nextChar = param[end]; + temp += param.substr(start, +rit->length()); + rit++; + } + i++; + temp += "]"; + + vector arr = parseStringArr(temp); + strs.push_back(arr); + } + } + return strs; +} + +char parseChar(string param) +{ + string str = parseString(param); + return str.at(0); +} + +vector parseCharArr(string param) +{ + vector r; + vector strArr = parseStringArr(param); + for (auto it = strArr.begin(); it != strArr.end(); it++) + { + r.push_back((*it).at(0)); + } + return r; +} + +vector> parseCharArrArr(string param) +{ + vector> r; + vector> strArrArr = parseStringArrArr(param); + for (auto it = strArrArr.begin(); it != strArrArr.end(); it++) + { + vector strArr = *it; + vector item; + for (auto it2 = strArr.begin(); it2 != strArr.end(); it2++) + { + item.push_back((*it2).at(0)); + } + r.push_back(item); + } + return r; +} + +string serializeChar(char param) +{ + string r = "\""; + if (param == '\\' || param == '"') + { + + r += '\\'; + } + r += param; + r += '"'; + return r; +} +string serializeCharArr(vector param) +{ + string r = "["; + for (auto it = param.begin(); it != param.end(); it++) + { + if (it != param.begin()) + { + r += ","; + } + r += serializeChar(*it); + } + r += "]"; + return r; +} +string serializeCharArrArr(vector> param) +{ + string r = "["; + for (auto it = param.begin(); it != param.end(); it++) + { + if (it != param.begin()) + { + r += ","; + } + r += serializeCharArr(*it); + } + r += "]"; + return r; +} +TreeNode *parseTreeNode(string param) +{ + int len = param.length(); + if (len <= 2) + { + return nullptr; + } + vector nodeData; + split(param.substr(1, len - 2), ',', nodeData); + if (nodeData.size() == 0) + { + return nullptr; + } + + int i = 0; + int val = stoi(nodeData[i++]); + TreeNode *root = new TreeNode(val); + queue q; + q.push(root); + while (q.size() > 0) + { + TreeNode *node = q.front(); + q.pop(); + if (i == nodeData.size()) + { + return root; + } + + string leftVal = nodeData[i++]; + if (leftVal != "null") + { + + node->left = new TreeNode(stoi(leftVal)); + q.push(node->left); + } + if (i == nodeData.size()) + { + return root; + } + string rightVal = nodeData[i++]; + if (rightVal != "null") + { + + node->right = new TreeNode(stoi(rightVal)); + q.push(node->right); + } + } + return root; +} +ListNode *parseListNode(string param) +{ + int len = param.length(); + if (len <= 2) + { + return nullptr; + } + vector arr; + split(param.substr(1, len - 2), ',', arr); + ListNode *head = new ListNode(); + ListNode *p = head; + + for (auto it = arr.begin(); it != arr.end(); it++) + { + p->next = new ListNode(stoi(*it)); + p = p->next; + } + + return head->next; +} +vector parseListNodeArr(string param) +{ + vector result; + int len = param.length(); + if (len <= 4) + { + return result; + } + string subStr = param.substr(1, len - 2); + for (int i = 1; i < len - 1; i++) + { + if (param[i] == '[') + { + string temp = ""; + temp += param[i++]; + while (param[i] != ']') + { + temp += param[i++]; + } + temp += param[i++]; + ListNode *arr = parseListNode(temp); + result.push_back(arr); + } + } + return result; +} +vector parseTreeNodeArr(string param) +{ + vector result; + int len = param.length(); + if (len <= 4) + { + return result; + } + string subStr = param.substr(1, len - 2); + for (int i = 1; i < len - 1; i++) + { + if (param[i] == '[') + { + string temp = ""; + temp += param[i++]; + while (param[i] != ']') + { + temp += param[i++]; + } + temp += param[i++]; + TreeNode *arr = parseTreeNode(temp); + result.push_back(arr); + } + } + return result; +} + +string serializeInteger(int param) +{ + string str = to_string(param); + return str; +} +string serializeIntegerArr(vector &arr) +{ + string out = ""; + for (auto it = arr.begin(); it != arr.end(); it++) + { + if (it == arr.end() - 1) + { + out += serializeInteger(*it); + } + else + { + out += serializeInteger(*it) + ","; + } + } + return "[" + out + "]"; +} +string serializeIntegerArrArr(vector> &arr) +{ + string out = ""; + for (auto it = arr.begin(); it != arr.end(); it++) + { + if (it == arr.end() - 1) + { + out += serializeIntegerArr(*it); + } + else + { + out += serializeIntegerArr(*it) + ","; + } + } + return "[" + out + "]"; +} +string serializeString(string param) +{ + int pos = 0; + string out = ""; + for (auto it = param.begin(); it != param.end(); it++) + { + if (*it == '\\' || *it == '"') + { + out += "\\" + *it; + } + else + { + out += *it; + } + } + return "\"" + out + "\""; +} +string serializeStringArr(vector ¶m) +{ + string out = ""; + for (auto it = param.begin(); it != param.end(); it++) + { + if (it == param.end() - 1) + { + out += serializeString(*it); + } + else + { + out += serializeString(*it) + ","; + } + } + return "[" + out + "]"; +} +string serializeStringArrArr(vector> ¶m) +{ + string out = ""; + for (auto it = param.begin(); it != param.end(); it++) + { + if (it == param.end() - 1) + { + out += serializeStringArr(*it); + } + else + { + out += serializeStringArr(*it) + ","; + } + } + return "[" + out + "]"; +} +string serializeListNode(ListNode *head) +{ + string out = ""; + while (head != nullptr) + { + out += to_string(head->val); + head = head->next; + if (head != nullptr) + { + out += ","; + } + } + return "[" + out + "]"; +} +string serializeTreeNode(TreeNode *root) +{ + if (root == nullptr) + { + return "[]"; + } + + vector arr; + queue q; + q.push(root); + while (q.size() > 0) + { + + TreeNode *node = q.front(); + q.pop(); + if (node == nullptr) + { + arr.push_back("null"); + } + else + { + arr.push_back(to_string(node->val)); + q.push(node->left); + q.push(node->right); + } + } + + while (arr.back() == "null") + { + arr.pop_back(); + } + string out = ""; + for (auto it = arr.begin(); it != arr.end(); it++) + { + if (it == arr.end() - 1) + { + out += *it; + } + else + { + out += *it + ","; + } + } + return "[" + out + "]"; +} +string serializeListNodeArr(vector &lists) +{ + string out = ""; + for (auto it = lists.begin(); it != lists.end(); it++) + { + if (it == lists.end() - 1) + { + out += serializeListNode(*it); + } + else + { + out += serializeListNode(*it) + ","; + } + } + return "[" + out + "]"; +} +string serializeTreeNodeArr(vector &arr) +{ + string out = ""; + for (auto it = arr.begin(); it != arr.end(); it++) + { + if (it == arr.end() - 1) + { + out += serializeTreeNode(*it); + } + else + { + out += serializeTreeNode(*it) + ","; + } + } + return "[" + out + "]"; +} diff --git a/template/cpp/parse_test.cpp b/template/cpp/parse_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8e61ed1a82d95150b70ad0020ac7acef33b56895 --- /dev/null +++ b/template/cpp/parse_test.cpp @@ -0,0 +1,146 @@ +#include "parse.h" +#include +#include "algm.h" +using namespace std; + +string transformBool(bool t) +{ + if (t == 1) + { + return "ok"; + } + else + { + return "fail"; + } +} + +bool deepEqual(vector &a, vector &b) +{ + if (a.size() != b.size()) + { + return false; + } + for (int i = 0; i < a.size(); i++) + { + if (a[i] != b[i]) + { + return false; + } + } + return true; +} +bool deepEqual(vector &a, vector &b) +{ + if (a.size() != b.size()) + { + return false; + } + for (int i = 0; i < a.size(); i++) + { + if (a[i] != b[i]) + { + return false; + } + } + return true; +} +bool deepEqual(vector> &a, vector> &b) +{ + if (a.size() != b.size()) + { + return false; + } + for (int i = 0; i < a.size(); i++) + { + if (!deepEqual(a[i], b[i])) + { + return false; + } + } + return true; +} +bool deepEqual(vector> &a, vector> &b) +{ + if (a.size() != b.size()) + { + return false; + } + for (int i = 0; i < a.size(); i++) + { + if (!deepEqual(a[i], b[i])) + { + return false; + } + } + return true; +} +int main() +{ + int num = parseInteger("1"); + cout << "test parseInteger: " << transformBool(num == 1) << endl; + + vector nums = parseIntegerArr("[1,2,3]"); + vector target{1, 2, 3}; + cout << "test parseIntegerArr: " << transformBool(deepEqual(nums, target)) << endl; + + vector> nums2 = parseIntegerArrArr("[[1,2,3],[4,5,6]]"); + vector> target2{vector{1, 2, 3}, vector{4, 5, 6}}; + cout << "test parseIntegerArrArr: " << transformBool(deepEqual(nums2, target2)) << endl; + + string str3 = parseString("\"abc\\\"\""); + string target3 = "abc\""; + cout << "test parseString: " << transformBool(str3 == target3) << endl; + + vector str4 = parseStringArr("[\"abc\\\"\"]"); + vector target4{"abc\""}; + cout << "test parseStringArr: " << transformBool(deepEqual(str4, target4)) << endl; + + vector> str5 = parseStringArrArr("[[\"1\",\"2\",\"3\"],[\"4\",\"5\",\"6\"]]"); + vector> target5{vector{"1", "2", "3"}, vector{"4", "5", "6"}}; + cout << "test parseStringArrArr: " << transformBool(deepEqual(str5, target5)) << endl; + + string origin6 = "[1,2,null,3]"; + TreeNode *treeNode6 = parseTreeNode("[1,2,null,3]"); + string target6 = serializeTreeNode(treeNode6); + cout << "test parseTreeNode: " << transformBool(origin6 == target6) << endl; + + string origin7 = "[1,2,3]"; + ListNode *listNode7 = parseListNode(origin7); + string target7 = serializeListNode(listNode7); + cout << "test parseListNode: " << transformBool(origin7 == target7) << endl; + + string origin8 = "[[1,2,3]]"; + vector listNodeArr8 = parseListNodeArr(origin8); + string target8 = serializeListNodeArr(listNodeArr8); + cout << "test parseListNodeArr: " << transformBool(origin8 == target8) << endl; + + string origin9 = "[[1,2,null,3],[1,2,3]]"; + vector listNodeArr9 = parseTreeNodeArr(origin9); + string target9 = serializeTreeNodeArr(listNodeArr9); + cout << "test parseTreeNodeArr: " << transformBool(origin9 == target9) << endl; + + string origin10 = "2.00000"; + double num10 = parseFloat(origin10); + string target10 = serializeFloat(num10); + cout << "test serializeFloat: " << transformBool(origin10 == target10) << endl; + + char char11 = parseChar("\"a\""); + char target11 = 'a'; + cout << "test parseString: " << transformBool(char11 == target11) << endl; + + string origin12 = "\"a\""; + char char12 = parseChar(origin12); + string str12 = serializeChar(char12); + cout << "test parseChar: " << transformBool(str12 == origin12) << endl; + + string origin13 = "[\"a\",\"v\"]"; + vector charArr13 = parseCharArr(origin13); + string str13 = serializeCharArr(charArr13); + cout << "test parseCharArr: " << transformBool(str13 == origin13) << endl; + + string origin14 = "[[\"a\",\"v\"]]"; + vector> charArrArr14 = parseCharArrArr(origin14); + string str14 = serializeCharArrArr(charArrArr14); + cout << "test parseCharArrArr: " << transformBool(str14 == origin14) << endl; +} \ No newline at end of file diff --git a/template/golang/algm.go b/template/golang/algm.go new file mode 100644 index 0000000000000000000000000000000000000000..5ef538d4680e6147b375e15e0e971b2b710b761c --- /dev/null +++ b/template/golang/algm.go @@ -0,0 +1,292 @@ +package main + +import ( + "encoding/json" + "fmt" + "strconv" + "strings" +) + +// ListNode Definition for singly-linked list. +type ListNode struct { + Val int + Next *ListNode +} + +// TreeNode Definition for a binary tree node. +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func serializeInterface(data interface{}) string { + r2, _ := json.Marshal(data) + return string(r2) +} + +func deserializeTreeNode(data string) *TreeNode { + length := len(data) + if length <= 2 { + return nil + } + + arr := strings.Split(data[1:length-1], ",") + val, _ := strconv.Atoi(arr[0]) + arr = arr[1:] + root := &TreeNode{Val: val} + queue := []*TreeNode{root} + for len(queue) > 0 { + node := queue[0] + queue = queue[1:] + if len(arr) == 0 { + return root + } + + leftVal := arr[0] + arr = arr[1:] + if leftVal != "null" { + val, _ := strconv.Atoi(leftVal) + left := &TreeNode{Val: val} + node.Left = left + queue = append(queue, left) + } + if len(arr) == 0 { + return root + } + rightVal := arr[0] + arr = arr[1:] + if rightVal != "null" { + val, _ := strconv.Atoi(rightVal) + right := &TreeNode{Val: val} + node.Right = right + queue = append(queue, right) + } + + } + return root + +} +func deserializeTreeNodeArr(data string) []*TreeNode { + length := len(data) + if length <= 4 { + return []*TreeNode{} + } + str := data[1 : length-1] + r := []*TreeNode{} + for i := 0; i < len(str); i++ { + if str[i:i+1] == "[" { + flag := false + j := i + 1 + for ; j < len(str); j++ { + if str[j:j+1] == "]" { + r = append(r, deserializeTreeNode(str[i:j+1])) + flag = true + break + } + } + if !flag { + fmt.Print("parse error") + return []*TreeNode{} + } + i = j + } + } + return r + +} +func serializeTreeNode(root *TreeNode) string { + if root == nil { + return "[]" + } + var arr []string + queue := []*TreeNode{root} + for len(queue) > 0 { + node := queue[0] + queue = queue[1:] + if node != nil { + arr = append(arr, strconv.Itoa(node.Val)) + queue = append(queue, node.Left) + queue = append(queue, node.Right) + } else { + arr = append(arr, "null") + } + + } + var i = len(arr) - 1 + for arr[i] == "null" { + i-- + } + arr = arr[0 : i+1] + return "[" + strings.Join(arr, ",") + "]" +} + +func serializeTreeNodeArr(arr []*TreeNode) string { + strArr := "[" + for i := 0; i < len(arr); i++ { + strArr += serializeTreeNode(arr[i]) + if i != len(arr)-1 { + strArr += "," + } + } + strArr += "]" + return strArr +} + +func deserializeListNode(data string) *ListNode { + length := len(data) + if length <= 2 { + return nil + } + arr := strings.Split(data[1:length-1], ",") + + c := arr[0] + arr = arr[1:] + val, _ := strconv.Atoi(c) + root := &ListNode{Val: val} + p := root + for len(arr) > 0 { + + c := arr[0] + arr = arr[1:] + val, _ := strconv.Atoi(c) + node := &ListNode{Val: val} + p.Next = node + p = node + } + return root +} + +func deserializeListNodeArr(data string) []*ListNode { + length := len(data) + if length <= 4 { + return []*ListNode{} + } + str := data[1 : length-1] + r := []*ListNode{} + for i := 0; i < len(str); i++ { + if str[i:i+1] == "[" { + flag := false + j := i + 1 + for ; j < len(str); j++ { + if str[j:j+1] == "]" { + r = append(r, deserializeListNode(str[i:j+1])) + flag = true + break + } + } + if !flag { + //解析错误 + fmt.Print("解析错误") + return []*ListNode{} + } + i = j + } + } + return r +} +func serializeListNode(root *ListNode) string { + var arr []string + p := root + for p != nil { + arr = append(arr, strconv.Itoa(p.Val)) + p = p.Next + } + return "[" + strings.Join(arr, ",") + "]" +} +func serializeListNodeArr(arr []*ListNode) string { + newArr := []string{} + for i := 0; i < len(arr); i++ { + newArr = append(newArr, serializeListNode(arr[i])) + } + return "[" + strings.Join(newArr, ",") + "]" +} + +func parseInteger(param string) int { + num, err := strconv.Atoi(param) + if err != nil { + panic(err) + } + return num +} +func parseString(param string) string { + var r string + json.Unmarshal([]byte(param), &r) + return r +} +func parseChar(param string) byte { + r := parseString(param) + return r[0] +} +func parseFloat(param string) float64 { + num, err := strconv.ParseFloat(param, 64) + if err != nil { + panic(err) + } + return num +} +func parseIntegerArr(param string) []int { + var r []int + json.Unmarshal([]byte(param), &r) + return r +} +func parseStringArr(param string) []string { + var r []string + json.Unmarshal([]byte(param), &r) + return r +} +func parseCharArr(param string) []byte { + strArr := parseStringArr(param) + var r []byte + for i := 0; i < len(strArr); i++ { + r = append(r, strArr[i][0]) + } + return r +} +func parseIntegerArrArr(param string) [][]int { + var r [][]int + json.Unmarshal([]byte(param), &r) + return r +} + +func parseStringArrArr(param string) [][]string { + var r [][]string + json.Unmarshal([]byte(param), &r) + return r +} +func parseCharArrArr(param string) [][]byte { + strArrArr := parseStringArrArr(param) + var r [][]byte + for i := 0; i < len(strArrArr); i++ { + var item []byte + for j := 0; j < len(strArrArr[i]); j++ { + item = append(item, strArrArr[i][j][0]) + } + r = append(r, item) + } + return r +} +func serializeFloat(a float64) string { + return strconv.FormatFloat(a, 'f', 5, 64) +} +func serializeChar(a byte) string { + return serializeInterface(string(a)) +} +func serializeCharArr(a []byte) string { + var strArr []string + for i := 0; i < len(a); i++ { + strArr = append(strArr, string(a[i])) + } + return serializeInterface(strArr) +} +func serializeCharArrArr(a [][]byte) string { + var strArr [][]string + for i := 0; i < len(a); i++ { + var item []string + for j := 0; j < len(a[i]); j++ { + item = append(item, string(a[i][j])) + } + strArr = append(strArr, item) + } + return serializeInterface(strArr) +} diff --git a/template/golang/go.mod b/template/golang/go.mod new file mode 100644 index 0000000000000000000000000000000000000000..854104af59ad7f1b9aab5f6f2432d590979aa2b9 --- /dev/null +++ b/template/golang/go.mod @@ -0,0 +1,5 @@ +module algm + +go 1.13 + +require github.com/franela/goblin v0.0.0-20210519012713-85d372ac71e2 diff --git a/template/golang/go.sum b/template/golang/go.sum new file mode 100644 index 0000000000000000000000000000000000000000..c6df1facc80571be4ee0e53c13c724416a097e41 --- /dev/null +++ b/template/golang/go.sum @@ -0,0 +1,2 @@ +github.com/franela/goblin v0.0.0-20210519012713-85d372ac71e2 h1:cZqz+yOJ/R64LcKjNQOdARott/jP7BnUQ9Ah7KaZCvw= +github.com/franela/goblin v0.0.0-20210519012713-85d372ac71e2/go.mod h1:VzmDKDJVZI3aJmnRI9VjAn9nJ8qPPsN1fqzr9dqInIo= diff --git a/template/golang/main_test.go b/template/golang/main_test.go new file mode 100644 index 0000000000000000000000000000000000000000..604fb010fa0e624a4ed236ef4508220450d9855f --- /dev/null +++ b/template/golang/main_test.go @@ -0,0 +1,111 @@ +package main + +import ( + "testing" + + . "github.com/franela/goblin" +) + +func Test(t *testing.T) { + g := Goblin(t) + g.Describe("test parse", func() { + g.It("should parse integer", func() { + a := parseInteger("12") + g.Assert(a).Equal(12) + }) + g.It("should parse string", func() { + a := parseString("\"12\"") + g.Assert(a).Equal("12") + }) + g.It("should parse float", func() { + a := parseFloat("1.22") + g.Assert(a).Equal(1.22) + }) + g.It("should parse integer[]", func() { + a := parseIntegerArr("[1,2,3]") + g.Assert(a).Equal([]int{1, 2, 3}) + }) + g.It("should parse string[]", func() { + a := parseStringArr("[\"1\",\"2\",\"3\"]") + g.Assert(a).Equal([]string{"1", "2", "3"}) + }) + g.It("should parse integer[][]", func() { + a := parseIntegerArrArr("[[1,2,3],[4,5,6]]") + g.Assert(a).Equal([][]int{[]int{1, 2, 3}, []int{4, 5, 6}}) + }) + g.It("should parse string[][]", func() { + a := parseStringArrArr("[[\"1\",\"2\",\"3\"],[\"4\",\"5\",\"6\"]]") + g.Assert(a).Equal([][]string{[]string{"1", "2", "3"}, []string{"4", "5", "6"}}) + }) + }) + g.Describe("test serialize", func() { + g.It("should serialize integer", func() { + a := serializeInterface(12) + g.Assert(a).Equal("12") + }) + g.It("should serialize string", func() { + a := serializeInterface("12") + g.Assert(a).Equal("\"12\"") + }) + g.It("should serialize double", func() { + a := serializeFloat(1.22) + g.Assert(a).Equal("1.22000") + }) + g.It("should serialize integer[]", func() { + a := serializeInterface([]int{1, 2, 3}) + g.Assert(a).Equal("[1,2,3]") + }) + g.It("should serialize string[]", func() { + a := serializeInterface([]string{"1", "2", "3"}) + g.Assert(a).Equal("[\"1\",\"2\",\"3\"]") + }) + g.It("should serialize integer[][]", func() { + a := serializeInterface([][]int{[]int{1, 2, 3}, []int{4, 5, 6}}) + g.Assert(a).Equal("[[1,2,3],[4,5,6]]") + }) + g.It("should serialize string[][]", func() { + a := serializeInterface([][]string{[]string{"1", "2", "3"}, []string{"4", "5", "6"}}) + g.Assert(a).Equal("[[\"1\",\"2\",\"3\"],[\"4\",\"5\",\"6\"]]") + }) + g.It("should serialize list", func() { + a := serializeInterface([]int{1, 2, 3}) + g.Assert(a).Equal("[1,2,3]") + }) + + g.It("should serialize list", func() { + a := serializeInterface([]string{"1", "2", "3"}) + g.Assert(a).Equal("[\"1\",\"2\",\"3\"]") + }) + g.It("should serialize list>", func() { + a := serializeInterface([][]int{[]int{1, 2, 3}, []int{4, 5, 6}}) + g.Assert(a).Equal("[[1,2,3],[4,5,6]]") + }) + g.It("should serialize list>", func() { + a := serializeInterface([][]string{[]string{"1", "2", "3"}, []string{"4", "5", "6"}}) + g.Assert(a).Equal("[[\"1\",\"2\",\"3\"],[\"4\",\"5\",\"6\"]]") + }) + g.It("should serialize TreeNode", func() { + treeNode := deserializeTreeNode("[1,2,3,null,null,4,5]") + str := serializeTreeNode(treeNode) + g.Assert(str).Equal("[1,2,3,null,null,4,5]") + + }) + g.It("should serialize ListNode", func() { + treeNode := deserializeListNode("[1,2,3,4,5]") + str := serializeListNode(treeNode) + g.Assert(str).Equal("[1,2,3,4,5]") + }) + g.It("should serialize list", func() { + data := "[[1,2,3,null,null,4,5],[1,2,3]]" + t1 := deserializeTreeNodeArr(data) + str := serializeTreeNodeArr(t1) + g.Assert(str).Equal(data) + }) + g.It("should serialize list", func() { + data := "[[4,5,6],[1,2,3]]" + t1 := deserializeListNodeArr(data) + str := serializeListNodeArr(t1) + g.Assert(str).Equal(data) + }) + }) +} diff --git a/template/java/ListNode.java b/template/java/ListNode.java new file mode 100644 index 0000000000000000000000000000000000000000..89c8f30dcc5314e38329948674a57b058b02d30a --- /dev/null +++ b/template/java/ListNode.java @@ -0,0 +1,19 @@ +package algm; + +// Definition for singly-linked list. +public class ListNode { + public int val; + public ListNode next; + + public ListNode() { + } + + public ListNode(int val) { + this.val = val; + } + + public ListNode(int val, ListNode next) { + this.val = val; + this.next = next; + } +} diff --git a/template/java/TreeNode.java b/template/java/TreeNode.java new file mode 100644 index 0000000000000000000000000000000000000000..238027ab3a164790e10ba096bfa2b7fac993ab2c --- /dev/null +++ b/template/java/TreeNode.java @@ -0,0 +1,21 @@ +package algm; + +// Definition for a binary tree node. +public class TreeNode { + public int val; + public TreeNode left; + public TreeNode right; + + public TreeNode() { + } + + public TreeNode(int val) { + this.val = val; + } + + public TreeNode(int val, TreeNode left, TreeNode right) { + this.val = val; + this.left = left; + this.right = right; + } +} diff --git a/template/java/Util.java b/template/java/Util.java new file mode 100644 index 0000000000000000000000000000000000000000..092e86e9aa35e031187f4829c6ca025cbc25e021 --- /dev/null +++ b/template/java/Util.java @@ -0,0 +1,569 @@ +package algm; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.LinkedList; +import java.util.Queue; + +public class Util { + static public int parseInteger(String param) { + return Integer.parseInt(param); + } + + static public Float parseFloat(String param) { + return Float.parseFloat(param); + } + + static public String parseString(String param) { + int len = param.length(); + assert param.charAt(0) == '"'; + String out = ""; + for (int i = 1; i < len; i++) { + if (param.charAt(i) == '\\') { + if (i == len - 2) { + throw new RuntimeException("parse string error"); + } + char nextChar = param.charAt(i + 1); + if (nextChar == 'u') { + String escapeStr = param.substring(i + 2, i + 6); + + String pattern = "^[0-9a-fA-F]{4}$"; + boolean isMatch = Pattern.matches(pattern, escapeStr); + if (!isMatch) { + throw new RuntimeException("parse string error in " + param.substring(0, i + 5)); + } + int num = Integer.parseInt(escapeStr, 16); + out += (char) num; + i += 5; + + } else { + char[] echars = new char[] { '"', '\\', '/', 'b', 'f', 'n', 'r', 't' }; + char[] realChars = new char[] { '"', '\\', '/', '\b', '\f', '\n', '\r', '\t' }; + boolean has = false; + for (int j = 0; j < echars.length; j++) { + if (echars[j] == nextChar) { + has = true; + out += realChars[j]; + i++; + break; + } + } + if (!has) { + throw new RuntimeException("parse string error in " + param.substring(0, i + 1)); + } + } + } else if (param.charAt(i) == '"') { + return out; + } else { + out += param.charAt(i); + } + } + throw new RuntimeException("parse string error in " + param); + + } + + static public char parseChar(String param) { + String str = parseString(param); + return str.charAt(0); + } + + static public char[] parseCharArr(String param) { + String[] arr = parseStringArr(param); + char r[] = new char[arr.length]; + for (int i = 0; i < arr.length; i++) { + r[i] = arr[i].charAt(0); + } + return r; + } + + static public char[][] parseCharArrArr(String param) { + String[][] arr = parseStringArrArr(param); + char[][] r = new char[arr.length][]; + for (int i = 0; i < arr.length; i++) { + r[i] = new char[arr[i].length]; + for (int j = 0; j < arr[i].length; j++) { + r[i][j] = arr[i][j].charAt(0); + } + } + return r; + } + + static public String serializeChar(char param) { + String r = String.valueOf(param); + return serializeString(r); + } + + static public String serializeCharArr(char[] param) { + String[] arr = new String[param.length]; + for (int i = 0; i < param.length; i++) { + arr[i] = String.valueOf(param[i]); + } + return serializeStringArr(arr); + } + + static public String serializeCharArrArr(char[][] param) { + String r = ""; + r += "["; + for (int i = 0; i < param.length; i++) { + r += "["; + for (int j = 0; j < param[i].length; j++) { + r += serializeChar(param[i][j]); + if (j != param[i].length - 1) { + r += ","; + } + + } + r += "]"; + } + r += "]"; + return r; + } + + static public int[] parseIntegerArr(String param) { + int[] r = {}; + int len = param.length(); + assert param.charAt(0) == '['; + assert param.charAt(len - 1) == ']'; + if (len == 2) { + return r; + } + List list = new ArrayList(); + String subStr = param.substring(1, len - 1); + String[] arr = subStr.split(","); + for (int i = 0; i < arr.length; i++) { + list.add(Integer.parseInt(arr[i])); + } + r = list.stream().mapToInt(Integer::valueOf).toArray(); + + return r; + } + + static public List parseIntegerList(String param) { + List list = new ArrayList(); + int len = param.length(); + assert param.charAt(0) == '['; + assert param.charAt(len - 1) == ']'; + if (len == 2) { + return list; + } + + String subStr = param.substring(1, len - 1); + String[] arr = subStr.split(","); + for (int i = 0; i < arr.length; i++) { + list.add(Integer.parseInt(arr[i])); + } + return list; + } + + static public List> parseIntegerListList(String param) { + List> list = new ArrayList>(); + int len = param.length(); + if (len <= 4) { + return list; + } + + for (int i = 1; i < len - 1; i++) { + if (param.charAt(i) == '[') { + String temp = ""; + i++; + while (param.charAt(i) != ']') { + temp += param.charAt(i++); + } + list.add(parseIntegerList("[" + temp + "]")); + } + } + return list; + } + + static public int[][] parseIntegerArrArr(String param) { + int len = param.length(); + int[][] r = {}; + if (len <= 4) { + return r; + } + List list = new ArrayList(); + + for (int i = 1; i < len - 1; i++) { + if (param.charAt(i) == '[') { + String temp = ""; + i++; + while (param.charAt(i) != ']') { + temp += param.charAt(i++); + } + list.add(parseIntegerArr("[" + temp + "]")); + } + } + r = new int[list.size()][]; + list.toArray(r); + return r; + } + + static public String[] parseStringArr(String param) { + + List list = new ArrayList(); + int len = param.length(); + assert param.charAt(0) == '['; + assert param.charAt(len - 1) == ']'; + if (len == 2) { + return new String[] {}; + } + Pattern p = Pattern.compile("\"(\\\\.|[^\"\\\\])*\""); + String subStr = param.substring(1, len - 1); + Matcher m = p.matcher(subStr); + while (m.find()) { + list.add(parseString(subStr.substring(m.start(), m.end()))); + + } + String[] r = new String[list.size()]; + + list.toArray(r); + return r; + } + + static public List parseStringList(String param) { + List list = new ArrayList(); + int len = param.length(); + assert param.charAt(0) == '['; + assert param.charAt(len - 1) == ']'; + if (len == 2) { + return list; + } + Pattern p = Pattern.compile("\"(\\\\.|[^\"\\\\])*\""); + String subStr = param.substring(1, len - 1); + Matcher m = p.matcher(subStr); + while (m.find()) { + list.add(parseString(subStr.substring(m.start(), m.end()))); + + } + + return list; + } + + static public String[][] parseStringArrArr(String param) { + + List list = new ArrayList(); + int len = param.length(); + assert param.charAt(0) == '['; + assert param.charAt(len - 1) == ']'; + if (len == 4) { + return new String[][] { new String[] {} }; + } + Pattern p = Pattern.compile("\"(\\\\.|[^\"\\\\])*\""); + String subStr = param.substring(1, len - 1); + Matcher m = p.matcher(subStr); + for (int i = 0; i < subStr.length(); i++) { + // System.out.print(subStr.charAt(i)); + char curChar = subStr.charAt(i); + char nextChar = subStr.charAt(i + 1); + List temp = new ArrayList(); + if (curChar == '[') { + while (nextChar != ']' && m.find()) { + + temp.add(parseString(subStr.substring(m.start(), m.end()))); + + i = m.end(); + nextChar = subStr.charAt(i); + } + String[] tempArr = new String[temp.size()]; + + temp.toArray(tempArr); + list.add(tempArr); + } + } + + String[][] r = new String[list.size()][]; + return list.toArray(r); + } + + static public List> parseStringListList(String param) { + List> list = new ArrayList>(); + int len = param.length(); + assert param.charAt(0) == '['; + assert param.charAt(len - 1) == ']'; + if (len == 4) { + return list; + } + Pattern p = Pattern.compile("\"(\\\\.|[^\"\\\\])*\""); + String subStr = param.substring(1, len - 1); + Matcher m = p.matcher(subStr); + for (int i = 0; i < subStr.length(); i++) { + char curChar = subStr.charAt(i); + char nextChar = subStr.charAt(i + 1); + List temp = new ArrayList(); + if (curChar == '[') { + while (nextChar != ']' && m.find()) { + + temp.add(parseString(subStr.substring(m.start(), m.end()))); + + i = m.end(); + nextChar = subStr.charAt(i); + } + list.add(temp); + } + } + + return list; + } + + static public String serializeInteger(int param) { + return Integer.toString(param); + } + + static public String serializeBool(boolean param) { + if (param == true) { + return "true"; + } else { + return "false"; + } + } + + static public String serializeFloat(double param) { + String r = param + ""; + String[] arr = r.split("\\."); + if (arr.length == 1) { + return r + ".00000"; + } else { + String decimalStr = arr[1] + "00000"; + return arr[0] + "." + decimalStr.substring(0, 5); + } + } + + static public String serializeIntegerArr(int[] param) { + List list = new ArrayList(); + for (int i = 0; i < param.length; i++) { + list.add(serializeInteger(param[i])); + } + return "[" + String.join(",", list) + "]"; + } + + static public String serializeIntegerList(List param) { + List list = new ArrayList(); + for (int i = 0; i < param.size(); i++) { + list.add(serializeInteger(param.get(i))); + } + return "[" + String.join(",", list) + "]"; + } + + static public String serializeIntegerArrArr(int[][] param) { + List list = new ArrayList(); + for (int i = 0; i < param.length; i++) { + list.add(serializeIntegerArr(param[i])); + } + return "[" + String.join(",", list) + "]"; + } + + static public String serializeIntegerListList(List> param) { + List list = new ArrayList(); + for (int i = 0; i < param.size(); i++) { + list.add(serializeIntegerList(param.get(i))); + } + return "[" + String.join(",", list) + "]"; + } + + static public String serializeString(String param) { + String out = param.replaceAll("(\\|\")", "\\$1"); + return "\"" + out + "\""; + } + + static public String serializeStringArr(String[] param) { + List list = new ArrayList(); + for (int i = 0; i < param.length; i++) { + list.add(serializeString(param[i])); + } + return "[" + String.join(",", list) + "]"; + } + + static public String serializeStringList(List param) { + List list = new ArrayList(); + for (int i = 0; i < param.size(); i++) { + list.add(serializeString(param.get(i))); + } + return "[" + String.join(",", list) + "]"; + } + + static public String serializeStringArrArr(String[][] param) { + List list = new ArrayList(); + for (int i = 0; i < param.length; i++) { + list.add(serializeStringArr(param[i])); + } + return "[" + String.join(",", list) + "]"; + } + + static public String serializeStringListList(List> param) { + List list = new ArrayList(); + for (int i = 0; i < param.size(); i++) { + list.add(serializeStringList(param.get(i))); + } + return "[" + String.join(",", list) + "]"; + } + + static public TreeNode parseTreeNode(String param) { + int len = param.length(); + assert param.charAt(0) == '['; + assert param.charAt(len - 1) == ']'; + if (len <= 2) { + return null; + } + String[] nodeData = param.substring(1, len - 1).split(","); + int i = 0; + String val = nodeData[i++]; + TreeNode root = new TreeNode(parseInteger(val)); + Queue queue; + queue = new LinkedList(); + queue.offer(root); + + while (!queue.isEmpty()) { + TreeNode node = queue.poll(); + if (i == nodeData.length) { + return root; + } + + String leftVal = nodeData[i++]; + if (!leftVal.equals("null")) { + TreeNode left = new TreeNode(parseInteger(leftVal)); + node.left = left; + queue.offer(left); + } + if (i == nodeData.length) { + return root; + } + String rightVal = nodeData[i++]; + if (!rightVal.equals("null")) { + TreeNode right = new TreeNode(parseInteger(rightVal)); + node.right = right; + queue.offer(right); + } + } + return root; + } + + static public ListNode parseListNode(String param) { + int len = param.length(); + assert param.charAt(0) == '['; + assert param.charAt(len - 1) == ']'; + if (len <= 2) { + return null; + } + int[] arr = parseIntegerArr(param); + ListNode root = new ListNode(arr[0]); + ListNode p = root; + for (int i = 1; i < arr.length; i++) { + p.next = new ListNode(arr[i]); + p = p.next; + } + return root; + } + + static public String serializeListNode(ListNode root) { + String out = ""; + ListNode p = root; + while (p != null) { + out += p.val; + + p = p.next; + if (p != null) { + out += ","; + } + } + return "[" + out + "]"; + } + + static public String serializeTreeNode(TreeNode root) { + if (root == null) { + return "[]"; + } + List list = new ArrayList(); + Queue queue; + queue = new LinkedList(); + queue.offer(root); + while (!queue.isEmpty()) { + TreeNode node = queue.poll(); + if (node != null) { + list.add(Integer.toString(node.val)); + queue.offer(node.left); + queue.offer(node.right); + } else { + list.add(null); + } + } + int i = list.size() - 1; + while (list.get(i) == null) { + i--; + } + return "[" + String.join(",", list.subList(0, i + 1)) + "]"; + + } + + static public String serializeListNodeArr(ListNode[] arr) { + String out = ""; + for (int i = 0; i < arr.length; i++) { + if (i == arr.length - 1) { + out += serializeListNode(arr[i]); + } else { + out += serializeListNode(arr[i]) + ","; + } + + } + return "[" + out + "]"; + } + + static public ListNode[] parseListNodeArr(String param) { + int len = param.length(); + ListNode[] r = {}; + if (len <= 4) { + return r; + } + + List list = new ArrayList(); + for (int i = 1; i < len - 1; i++) { + if (param.charAt(i) == '[') { + String temp = ""; + i++; + while (param.charAt(i) != ']') { + temp += param.charAt(i++); + } + list.add(parseListNode("[" + temp + "]")); + } + } + r = new ListNode[list.size()]; + list.toArray(r); + return r; + } + + static public String serializeTreeNodeArr(TreeNode[] arr) { + String out = ""; + for (int i = 0; i < arr.length; i++) { + out += serializeTreeNode(arr[i]); + if (i != arr.length - 1) { + out += ','; + } + } + return "[" + out + "]"; + } + + static public TreeNode[] parseTreeNodeArr(String param) { + int len = param.length(); + TreeNode[] r = {}; + if (len <= 4) { + return r; + } + + List list = new ArrayList(); + for (int i = 1; i < len - 1; i++) { + if (param.charAt(i) == '[') { + String temp = ""; + i++; + while (param.charAt(i) != ']') { + temp += param.charAt(i++); + } + list.add(parseTreeNode("[" + temp + "]")); + } + } + r = new TreeNode[list.size()]; + list.toArray(r); + return r; + } + +} diff --git a/tsconfig.json b/tsconfig.json index 315af7ec731c1ef626c891437fe29cd7d1e365dc..a7eab2b04be5bb2c0c8f780b52d08a6ce9ddfb5b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,17 +1,24 @@ { - "compilerOptions": { - "module": "commonjs", - "target": "ES2020", - "outDir": "out", - "lib": [ - "ES2020" - ], - "sourceMap": true, - "rootDir": "src", - "strict": true /* enable all strict type-checking options */ - /* Additional Checks */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - } -} + "compilerOptions": { + "module": "commonjs", + "target": "es6", + "outDir": "out", + "lib": [ + "es6" + ], + "useUnknownInCatchVariables":false, + "sourceMap": true, + "noImplicitAny": false, + "noImplicitThis": false, + "rootDir": "src", + "strict": true /* enable all strict type-checking options */ + /* Additional Checks */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + }, + "exclude": [ + "node_modules", + ".vscode-test" + ] +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 2c08e7374d72fbc2ab8a8e74f2f1313e61d22f9c..03126d9bf2bc4c4e05dade718bc0cf6ff44e241d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,38 +2,305 @@ # yarn lockfile v1 -"@eslint/eslintrc@^1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.0.tgz#29f92c30bb3e771e4a2048c95fa6855392dfac4f" - integrity sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw== +"@ampproject/remapping@^2.1.0": + version "2.2.0" + resolved "http://10.121.8.15:9813/repository/npm-group/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" + integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== + dependencies: + "@jridgewell/gen-mapping" "^0.1.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.18.6": + version "7.18.6" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" + integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== + dependencies: + "@babel/highlight" "^7.18.6" + +"@babel/compat-data@^7.18.6": + version "7.18.8" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/compat-data/-/compat-data-7.18.8.tgz#2483f565faca607b8535590e84e7de323f27764d" + integrity sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ== + +"@babel/core@^7.13.10": + version "7.18.6" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/core/-/core-7.18.6.tgz#54a107a3c298aee3fe5e1947a6464b9b6faca03d" + integrity sha512-cQbWBpxcbbs/IUredIPkHiAGULLV8iwgNRMFzvbhEXISp4f3rUUXE5+TIw6KwUWUR3DwyI6gmBRnmAtYaWehwQ== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.6" + "@babel/helper-compilation-targets" "^7.18.6" + "@babel/helper-module-transforms" "^7.18.6" + "@babel/helpers" "^7.18.6" + "@babel/parser" "^7.18.6" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.6" + "@babel/types" "^7.18.6" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.1" + semver "^6.3.0" + +"@babel/generator@^7.18.6", "@babel/generator@^7.18.7": + version "7.18.7" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/generator/-/generator-7.18.7.tgz#2aa78da3c05aadfc82dbac16c99552fc802284bd" + integrity sha512-shck+7VLlY72a2w9c3zYWuE1pwOKEiQHV7GTUbSnhyl5eu3i04t30tBY82ZRWrDfo3gkakCFtevExnxbkf2a3A== + dependencies: + "@babel/types" "^7.18.7" + "@jridgewell/gen-mapping" "^0.3.2" + jsesc "^2.5.1" + +"@babel/helper-annotate-as-pure@^7.18.6": + version "7.18.6" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb" + integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-compilation-targets@^7.18.6": + version "7.18.6" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.6.tgz#18d35bfb9f83b1293c22c55b3d576c1315b6ed96" + integrity sha512-vFjbfhNCzqdeAtZflUFrG5YIFqGTqsctrtkZ1D/NB0mDW9TwW3GmmUepYY4G9wCET5rY5ugz4OGTcLd614IzQg== + dependencies: + "@babel/compat-data" "^7.18.6" + "@babel/helper-validator-option" "^7.18.6" + browserslist "^4.20.2" + semver "^6.3.0" + +"@babel/helper-create-class-features-plugin@^7.18.6": + version "7.18.6" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.6.tgz#6f15f8459f3b523b39e00a99982e2c040871ed72" + integrity sha512-YfDzdnoxHGV8CzqHGyCbFvXg5QESPFkXlHtvdCkesLjjVMT2Adxe4FGUR5ChIb3DxSaXO12iIOCWoXdsUVwnqw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.6" + "@babel/helper-function-name" "^7.18.6" + "@babel/helper-member-expression-to-functions" "^7.18.6" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/helper-replace-supers" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + +"@babel/helper-environment-visitor@^7.18.6": + version "7.18.6" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.6.tgz#b7eee2b5b9d70602e59d1a6cad7dd24de7ca6cd7" + integrity sha512-8n6gSfn2baOY+qlp+VSzsosjCVGFqWKmDF0cCWOybh52Dw3SEyoWR1KrhMJASjLwIEkkAufZ0xvr+SxLHSpy2Q== + +"@babel/helper-function-name@^7.18.6": + version "7.18.6" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/helper-function-name/-/helper-function-name-7.18.6.tgz#8334fecb0afba66e6d87a7e8c6bb7fed79926b83" + integrity sha512-0mWMxV1aC97dhjCah5U5Ua7668r5ZmSC2DLfH2EZnf9c3/dHZKiFa5pRLMH5tjSl471tY6496ZWk/kjNONBxhw== + dependencies: + "@babel/template" "^7.18.6" + "@babel/types" "^7.18.6" + +"@babel/helper-hoist-variables@^7.18.6": + version "7.18.6" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" + integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-member-expression-to-functions@^7.18.6": + version "7.18.6" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.6.tgz#44802d7d602c285e1692db0bad9396d007be2afc" + integrity sha512-CeHxqwwipekotzPDUuJOfIMtcIHBuc7WAzLmTYWctVigqS5RktNMQ5bEwQSuGewzYnCtTWa3BARXeiLxDTv+Ng== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.18.6": + version "7.18.6" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" + integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-module-transforms@^7.18.6": + version "7.18.8" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/helper-module-transforms/-/helper-module-transforms-7.18.8.tgz#4f8408afead0188cfa48672f9d0e5787b61778c8" + integrity sha512-che3jvZwIcZxrwh63VfnFTUzcAM9v/lznYkkRxIBGMPt1SudOKHAEec0SIRCfiuIzTcF7VGj/CaTT6gY4eWxvA== + dependencies: + "@babel/helper-environment-visitor" "^7.18.6" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.18.6" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.8" + "@babel/types" "^7.18.8" + +"@babel/helper-optimise-call-expression@^7.18.6": + version "7.18.6" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz#9369aa943ee7da47edab2cb4e838acf09d290ffe" + integrity sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6": + version "7.18.6" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.6.tgz#9448974dd4fb1d80fefe72e8a0af37809cd30d6d" + integrity sha512-gvZnm1YAAxh13eJdkb9EWHBnF3eAub3XTLCZEehHT2kWxiKVRL64+ae5Y6Ivne0mVHmMYKT+xWgZO+gQhuLUBg== + +"@babel/helper-replace-supers@^7.18.6": + version "7.18.6" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/helper-replace-supers/-/helper-replace-supers-7.18.6.tgz#efedf51cfccea7b7b8c0f00002ab317e7abfe420" + integrity sha512-fTf7zoXnUGl9gF25fXCWE26t7Tvtyn6H4hkLSYhATwJvw2uYxd3aoXplMSe0g9XbwK7bmxNes7+FGO0rB/xC0g== + dependencies: + "@babel/helper-environment-visitor" "^7.18.6" + "@babel/helper-member-expression-to-functions" "^7.18.6" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/traverse" "^7.18.6" + "@babel/types" "^7.18.6" + +"@babel/helper-simple-access@^7.18.6": + version "7.18.6" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz#d6d8f51f4ac2978068df934b569f08f29788c7ea" + integrity sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-split-export-declaration@^7.18.6": + version "7.18.6" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" + integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-validator-identifier@^7.18.6": + version "7.18.6" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076" + integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g== + +"@babel/helper-validator-option@^7.14.5", "@babel/helper-validator-option@^7.18.6": + version "7.18.6" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" + integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== + +"@babel/helpers@^7.18.6": + version "7.18.6" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/helpers/-/helpers-7.18.6.tgz#4c966140eaa1fcaa3d5a8c09d7db61077d4debfd" + integrity sha512-vzSiiqbQOghPngUYt/zWGvK3LAsPhz55vc9XNN0xAl2gV4ieShI2OQli5duxWHD+72PZPTKAcfcZDE1Cwc5zsQ== + dependencies: + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.6" + "@babel/types" "^7.18.6" + +"@babel/highlight@^7.18.6": + version "7.18.6" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.18.6", "@babel/parser@^7.18.8": + version "7.18.8" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/parser/-/parser-7.18.8.tgz#822146080ac9c62dac0823bb3489622e0bc1cbdf" + integrity sha512-RSKRfYX20dyH+elbJK2uqAkVyucL+xXzhqlMD5/ZXx+dAAwpyB7HsvnHe/ZUGOF+xLr5Wx9/JoXVTj6BQE2/oA== + +"@babel/plugin-syntax-typescript@^7.18.6": + version "7.18.6" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz#1c09cd25795c7c2b8a4ba9ae49394576d4133285" + integrity sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-typescript@^7.16.0": + version "7.18.8" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.18.8.tgz#303feb7a920e650f2213ef37b36bbf327e6fa5a0" + integrity sha512-p2xM8HI83UObjsZGofMV/EdYjamsDm6MoN3hXPYIT0+gxIoopE+B7rPYKAxfrz9K9PK7JafTTjqYC6qipLExYA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-typescript" "^7.18.6" + +"@babel/preset-typescript@^7.13.0": + version "7.16.0" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/preset-typescript/-/preset-typescript-7.16.0.tgz#b0b4f105b855fb3d631ec036cdc9d1ffd1fa5eac" + integrity sha1-sLTxBbhV+z1jHsA2zcnR/9H6Xqw= + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-validator-option" "^7.14.5" + "@babel/plugin-transform-typescript" "^7.16.0" + +"@babel/template@^7.18.6": + version "7.18.6" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/template/-/template-7.18.6.tgz#1283f4993e00b929d6e2d3c72fdc9168a2977a31" + integrity sha512-JoDWzPe+wgBsTTgdnIma3iHNFC7YVJoPssVBDjiHfNlyt4YcunDtcDOUmfVDfCK5MfdsaIoX9PkijPhjH3nYUw== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.18.6" + "@babel/types" "^7.18.6" + +"@babel/traverse@^7.18.6", "@babel/traverse@^7.18.8": + version "7.18.8" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/traverse/-/traverse-7.18.8.tgz#f095e62ab46abf1da35e5a2011f43aee72d8d5b0" + integrity sha512-UNg/AcSySJYR/+mIcJQDCv00T+AqRO7j/ZEJLzpaYtgM48rMg5MnkJgyNqkzo88+p4tfRvZJCEiwwfG6h4jkRg== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.7" + "@babel/helper-environment-visitor" "^7.18.6" + "@babel/helper-function-name" "^7.18.6" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.18.8" + "@babel/types" "^7.18.8" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.0.0", "@babel/types@^7.18.6", "@babel/types@^7.18.7", "@babel/types@^7.18.8", "@babel/types@^7.3.0": + version "7.18.8" + resolved "http://10.121.8.15:9813/repository/npm-group/@babel/types/-/types-7.18.8.tgz#c5af199951bf41ba4a6a9a6d0d8ad722b30cd42f" + integrity sha512-qwpdsmraq0aJ3osLJRApsc2ouSJCdnMeZwB0DhbtHAtRpZNZCdlbRnHIgcRKzdE1g0iOGg644fzjOBcdOz9cPw== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + to-fast-properties "^2.0.0" + +"@jridgewell/gen-mapping@^0.1.0": + version "0.1.1" + resolved "http://10.121.8.15:9813/repository/npm-group/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" + integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^9.3.2" - globals "^13.15.0" - ignore "^5.2.0" - import-fresh "^3.2.1" - js-yaml "^4.1.0" - minimatch "^3.1.2" - strip-json-comments "^3.1.1" - -"@humanwhocodes/config-array@^0.9.2": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.5.tgz#2cbaf9a89460da24b5ca6531b8bbfc23e1df50c7" - integrity sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw== - dependencies: - "@humanwhocodes/object-schema" "^1.2.1" - debug "^4.1.1" - minimatch "^3.0.4" + "@jridgewell/set-array" "^1.0.0" + "@jridgewell/sourcemap-codec" "^1.4.10" -"@humanwhocodes/object-schema@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" - integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== +"@jridgewell/gen-mapping@^0.3.2": + version "0.3.2" + resolved "http://10.121.8.15:9813/repository/npm-group/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.0" + resolved "http://10.121.8.15:9813/repository/npm-group/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "http://10.121.8.15:9813/repository/npm-group/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.14" + resolved "http://10.121.8.15:9813/repository/npm-group/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/trace-mapping@^0.3.9": + version "0.3.14" + resolved "http://10.121.8.15:9813/repository/npm-group/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" + integrity sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" "@nodelib/fs.scandir@2.1.5": version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + resolved "http://10.121.8.15:9813/repository/npm-group/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== dependencies: "@nodelib/fs.stat" "2.0.5" @@ -41,175 +308,274 @@ "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + resolved "http://10.121.8.15:9813/repository/npm-group/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== "@nodelib/fs.walk@^1.2.3": version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + resolved "http://10.121.8.15:9813/repository/npm-group/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== dependencies: "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@rollup/plugin-babel@^5.0.4": + version "5.3.1" + resolved "http://10.121.8.15:9813/repository/npm-group/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283" + integrity sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q== + dependencies: + "@babel/helper-module-imports" "^7.10.4" + "@rollup/pluginutils" "^3.1.0" + +"@rollup/plugin-node-resolve@^11.2.1": + version "11.2.1" + resolved "http://10.121.8.15:9813/repository/npm-group/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz#82aa59397a29cd4e13248b106e6a4a1880362a60" + integrity sha1-gqpZOXopzU4TJIsQbmpKGIA2KmA= + dependencies: + "@rollup/pluginutils" "^3.1.0" + "@types/resolve" "1.17.1" + builtin-modules "^3.1.0" + deepmerge "^4.2.2" + is-module "^1.0.0" + resolve "^1.19.0" + +"@rollup/plugin-typescript@^8.2.0": + version "8.3.3" + resolved "http://10.121.8.15:9813/repository/npm-group/@rollup/plugin-typescript/-/plugin-typescript-8.3.3.tgz#eee7edab9cfc064f1cfd16570492693cf1432215" + integrity sha512-55L9SyiYu3r/JtqdjhwcwaECXP7JeJ9h1Sg1VWRJKIutla2MdZQodTgcCNybXLMCnqpNLEhS2vGENww98L1npg== + dependencies: + "@rollup/pluginutils" "^3.1.0" + resolve "^1.17.0" + +"@rollup/plugin-virtual@^2.1.0": + version "2.1.0" + resolved "http://10.121.8.15:9813/repository/npm-group/@rollup/plugin-virtual/-/plugin-virtual-2.1.0.tgz#a77bfd0dff74f0203401c75287ff4d1a1cfbc816" + integrity sha512-CPPAtlKT53HFqC8jFHb/V5WErpU8Hrq2TyCR0A7kPQMlF2wNUf0o1xuAc+Qxj8NCZM0Z3Yvl+FbUXfJjVWqDwA== + +"@rollup/pluginutils@^3.1.0": + version "3.1.0" + resolved "http://10.121.8.15:9813/repository/npm-group/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b" + integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg== + dependencies: + "@types/estree" "0.0.39" + estree-walker "^1.0.1" + picomatch "^2.2.2" + "@tootallnate/once@1": version "1.1.2" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + resolved "http://10.121.8.15:9813/repository/npm-group/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== -"@types/glob@^7.2.0": +"@types/babel__core@^7.1.9": + version "7.1.19" + resolved "http://10.121.8.15:9813/repository/npm-group/@types/babel__core/-/babel__core-7.1.19.tgz#7b497495b7d1b4812bdb9d02804d0576f43ee460" + integrity sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.4" + resolved "http://10.121.8.15:9813/repository/npm-group/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7" + integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.1" + resolved "http://10.121.8.15:9813/repository/npm-group/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" + integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*": + version "7.14.2" + resolved "http://10.121.8.15:9813/repository/npm-group/@types/babel__traverse/-/babel__traverse-7.14.2.tgz#ffcd470bbb3f8bf30481678fb5502278ca833a43" + integrity sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA== + dependencies: + "@babel/types" "^7.3.0" + +"@types/caseless@*": + version "0.12.2" + resolved "http://10.121.8.15:9813/repository/npm-group/@types/caseless/-/caseless-0.12.2.tgz#f65d3d6389e01eeb458bd54dc8f52b95a9463bc8" + integrity sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w== + +"@types/esprima@^4.0.2": + version "4.0.3" + resolved "http://10.121.8.15:9813/repository/npm-group/@types/esprima/-/esprima-4.0.3.tgz#e9068297cc3dd75231fa5cdaa6d75c50d5fb632f" + integrity sha512-jo14dIWVVtF0iMsKkYek6++4cWJjwpvog+rchLulwgFJGTXqIeTdCOvY0B3yMLTaIwMcKCdJ6mQbSR6wYHy98A== + dependencies: + "@types/estree" "*" + +"@types/estree@*": + version "0.0.51" + resolved "http://10.121.8.15:9813/repository/npm-group/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" + integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== + +"@types/estree@0.0.39": + version "0.0.39" + resolved "http://10.121.8.15:9813/repository/npm-group/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" + integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== + +"@types/glob@^7.1.1": version "7.2.0" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" - integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== + resolved "http://10.121.8.15:9813/repository/npm-group/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" + integrity sha1-vBtb86qS8lvV3TnzXFc2G9zlsus= dependencies: "@types/minimatch" "*" "@types/node" "*" -"@types/json-schema@^7.0.9": +"@types/json-schema@^7.0.7": version "7.0.11" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" + resolved "http://10.121.8.15:9813/repository/npm-group/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== "@types/minimatch@*": version "3.0.5" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" - integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== + resolved "http://10.121.8.15:9813/repository/npm-group/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" + integrity sha1-EAHMXmo3BLg8I2An538vWOoBD0A= -"@types/mocha@^9.1.1": - version "9.1.1" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.1.1.tgz#e7c4f1001eefa4b8afbd1eee27a237fee3bf29c4" - integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw== +"@types/mocha@^7.0.2": + version "7.0.2" + resolved "http://10.121.8.15:9813/repository/npm-group/@types/mocha/-/mocha-7.0.2.tgz#b17f16cf933597e10d6d78eae3251e692ce8b0ce" + integrity sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w== "@types/node@*": version "18.0.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.6.tgz#0ba49ac517ad69abe7a1508bc9b3a5483df9d5d7" + resolved "http://10.121.8.15:9813/repository/npm-group/@types/node/-/node-18.0.6.tgz#0ba49ac517ad69abe7a1508bc9b3a5483df9d5d7" integrity sha512-/xUq6H2aQm261exT6iZTMifUySEt4GR5KX8eYyY+C4MSNPqSh9oNIP7tz2GLKTlFaiBbgZNxffoR3CVRG+cljw== -"@types/node@16.x": - version "16.11.45" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.45.tgz#155b13a33c665ef2b136f7f245fa525da419e810" - integrity sha512-3rKg/L5x0rofKuuUt5zlXzOnKyIHXmIu5R8A0TuNDMF2062/AOIDBciFIjToLEJ/9F9DzkHNot+BpNsMI1OLdQ== - -"@types/vscode@^1.69.0": - version "1.69.0" - resolved "https://registry.yarnpkg.com/@types/vscode/-/vscode-1.69.0.tgz#a472011af392fbcf82cbb82f60b4c239c21b921c" - integrity sha512-RlzDAnGqUoo9wS6d4tthNyAdZLxOIddLiX3djMoWk29jFfSA1yJbIwr0epBYqqYarWB6s2Z+4VaZCQ80Jaa3kA== +"@types/node@^13.11.0": + version "13.13.52" + resolved "http://10.121.8.15:9813/repository/npm-group/@types/node/-/node-13.13.52.tgz#03c13be70b9031baaed79481c0c0cfb0045e53f7" + integrity sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ== -"@typescript-eslint/eslint-plugin@^5.30.0": - version "5.30.7" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.30.7.tgz#1621dabc1ae4084310e19e9efc80dfdbb97e7493" - integrity sha512-l4L6Do+tfeM2OK0GJsU7TUcM/1oN/N25xHm3Jb4z3OiDU4Lj8dIuxX9LpVMS9riSXQs42D1ieX7b85/r16H9Fw== +"@types/request@^2.48.5": + version "2.48.8" + resolved "http://10.121.8.15:9813/repository/npm-group/@types/request/-/request-2.48.8.tgz#0b90fde3b655ab50976cb8c5ac00faca22f5a82c" + integrity sha512-whjk1EDJPcAR2kYHRbFl/lKeeKYTi05A15K9bnLInCVroNDCtXce57xKdI0/rQaA3K+6q0eFyUBPmqfSndUZdQ== dependencies: - "@typescript-eslint/scope-manager" "5.30.7" - "@typescript-eslint/type-utils" "5.30.7" - "@typescript-eslint/utils" "5.30.7" - debug "^4.3.4" - functional-red-black-tree "^1.0.1" - ignore "^5.2.0" - regexpp "^3.2.0" - semver "^7.3.7" - tsutils "^3.21.0" + "@types/caseless" "*" + "@types/node" "*" + "@types/tough-cookie" "*" + form-data "^2.5.0" -"@typescript-eslint/parser@^5.30.0": - version "5.30.7" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.30.7.tgz#99d09729392aec9e64b1de45cd63cb81a4ddd980" - integrity sha512-Rg5xwznHWWSy7v2o0cdho6n+xLhK2gntImp0rJroVVFkcYFYQ8C8UJTSuTw/3CnExBmPjycjmUJkxVmjXsld6A== +"@types/resolve@1.17.1": + version "1.17.1" + resolved "http://10.121.8.15:9813/repository/npm-group/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6" + integrity sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw== dependencies: - "@typescript-eslint/scope-manager" "5.30.7" - "@typescript-eslint/types" "5.30.7" - "@typescript-eslint/typescript-estree" "5.30.7" - debug "^4.3.4" + "@types/node" "*" -"@typescript-eslint/scope-manager@5.30.7": - version "5.30.7" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.30.7.tgz#8269a931ef1e5ae68b5eb80743cc515c4ffe3dd7" - integrity sha512-7BM1bwvdF1UUvt+b9smhqdc/eniOnCKxQT/kj3oXtj3LqnTWCAM0qHRHfyzCzhEfWX0zrW7KqXXeE4DlchZBKw== - dependencies: - "@typescript-eslint/types" "5.30.7" - "@typescript-eslint/visitor-keys" "5.30.7" +"@types/tough-cookie@*": + version "4.0.1" + resolved "http://10.121.8.15:9813/repository/npm-group/@types/tough-cookie/-/tough-cookie-4.0.1.tgz#8f80dd965ad81f3e1bc26d6f5c727e132721ff40" + integrity sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg== -"@typescript-eslint/type-utils@5.30.7": - version "5.30.7" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.30.7.tgz#5693dc3db6f313f302764282d614cfdbc8a9fcfd" - integrity sha512-nD5qAE2aJX/YLyKMvOU5jvJyku4QN5XBVsoTynFrjQZaDgDV6i7QHFiYCx10wvn7hFvfuqIRNBtsgaLe0DbWhw== - dependencies: - "@typescript-eslint/utils" "5.30.7" - debug "^4.3.4" - tsutils "^3.21.0" +"@types/vscode@^1.46.0": + version "1.69.0" + resolved "http://10.121.8.15:9813/repository/npm-group/@types/vscode/-/vscode-1.69.0.tgz#a472011af392fbcf82cbb82f60b4c239c21b921c" + integrity sha512-RlzDAnGqUoo9wS6d4tthNyAdZLxOIddLiX3djMoWk29jFfSA1yJbIwr0epBYqqYarWB6s2Z+4VaZCQ80Jaa3kA== -"@typescript-eslint/types@5.30.7": - version "5.30.7" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.30.7.tgz#18331487cc92d0f1fb1a6f580c8ec832528079d0" - integrity sha512-ocVkETUs82+U+HowkovV6uxf1AnVRKCmDRNUBUUo46/5SQv1owC/EBFkiu4MOHeZqhKz2ktZ3kvJJ1uFqQ8QPg== - -"@typescript-eslint/typescript-estree@5.30.7": - version "5.30.7" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.7.tgz#05da9f1b281985bfedcf62349847f8d168eecc07" - integrity sha512-tNslqXI1ZdmXXrHER83TJ8OTYl4epUzJC0aj2i4DMDT4iU+UqLT3EJeGQvJ17BMbm31x5scSwo3hPM0nqQ1AEA== - dependencies: - "@typescript-eslint/types" "5.30.7" - "@typescript-eslint/visitor-keys" "5.30.7" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - semver "^7.3.7" +"@typescript-eslint/eslint-plugin@^4.26.0": + version "4.33.0" + resolved "http://10.121.8.15:9813/repository/npm-group/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz#c24dc7c8069c7706bc40d99f6fa87edcb2005276" + integrity sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg== + dependencies: + "@typescript-eslint/experimental-utils" "4.33.0" + "@typescript-eslint/scope-manager" "4.33.0" + debug "^4.3.1" + functional-red-black-tree "^1.0.1" + ignore "^5.1.8" + regexpp "^3.1.0" + semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/utils@5.30.7": - version "5.30.7" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.30.7.tgz#7135be070349e9f7caa262b0ca59dc96123351bb" - integrity sha512-Z3pHdbFw+ftZiGUnm1GZhkJgVqsDL5CYW2yj+TB2mfXDFOMqtbzQi2dNJIyPqPbx9mv2kUxS1gU+r2gKlKi1rQ== +"@typescript-eslint/experimental-utils@4.33.0": + version "4.33.0" + resolved "http://10.121.8.15:9813/repository/npm-group/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz#6f2a786a4209fa2222989e9380b5331b2810f7fd" + integrity sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q== dependencies: - "@types/json-schema" "^7.0.9" - "@typescript-eslint/scope-manager" "5.30.7" - "@typescript-eslint/types" "5.30.7" - "@typescript-eslint/typescript-estree" "5.30.7" + "@types/json-schema" "^7.0.7" + "@typescript-eslint/scope-manager" "4.33.0" + "@typescript-eslint/types" "4.33.0" + "@typescript-eslint/typescript-estree" "4.33.0" eslint-scope "^5.1.1" eslint-utils "^3.0.0" -"@typescript-eslint/visitor-keys@5.30.7": - version "5.30.7" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.7.tgz#c093abae75b4fd822bfbad9fc337f38a7a14909a" - integrity sha512-KrRXf8nnjvcpxDFOKej4xkD7657+PClJs5cJVSG7NNoCNnjEdc46juNAQt7AyuWctuCgs6mVRc1xGctEqrjxWw== - dependencies: - "@typescript-eslint/types" "5.30.7" - eslint-visitor-keys "^3.3.0" - -"@ungap/promise-all-settled@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" - integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== +"@typescript-eslint/parser@^4.26.0": + version "4.33.0" + resolved "http://10.121.8.15:9813/repository/npm-group/@typescript-eslint/parser/-/parser-4.33.0.tgz#dfe797570d9694e560528d18eecad86c8c744899" + integrity sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA== + dependencies: + "@typescript-eslint/scope-manager" "4.33.0" + "@typescript-eslint/types" "4.33.0" + "@typescript-eslint/typescript-estree" "4.33.0" + debug "^4.3.1" + +"@typescript-eslint/scope-manager@4.33.0": + version "4.33.0" + resolved "http://10.121.8.15:9813/repository/npm-group/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz#d38e49280d983e8772e29121cf8c6e9221f280a3" + integrity sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ== + dependencies: + "@typescript-eslint/types" "4.33.0" + "@typescript-eslint/visitor-keys" "4.33.0" + +"@typescript-eslint/types@4.33.0": + version "4.33.0" + resolved "http://10.121.8.15:9813/repository/npm-group/@typescript-eslint/types/-/types-4.33.0.tgz#a1e59036a3b53ae8430ceebf2a919dc7f9af6d72" + integrity sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ== + +"@typescript-eslint/typescript-estree@4.33.0": + version "4.33.0" + resolved "http://10.121.8.15:9813/repository/npm-group/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz#0dfb51c2908f68c5c08d82aefeaf166a17c24609" + integrity sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA== + dependencies: + "@typescript-eslint/types" "4.33.0" + "@typescript-eslint/visitor-keys" "4.33.0" + debug "^4.3.1" + globby "^11.0.3" + is-glob "^4.0.1" + semver "^7.3.5" + tsutils "^3.21.0" -"@vscode/test-electron@^2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@vscode/test-electron/-/test-electron-2.1.5.tgz#ac98f8f445ea4590753f5fa0c7f6e4298f08c3b7" - integrity sha512-O/ioqFpV+RvKbRykX2ItYPnbcZ4Hk5V0rY4uhQjQTLhGL9WZUvS7exzuYQCCI+ilSqJpctvxq2llTfGXf9UnnA== +"@typescript-eslint/visitor-keys@4.33.0": + version "4.33.0" + resolved "http://10.121.8.15:9813/repository/npm-group/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz#2a22f77a41604289b7a186586e9ec48ca92ef1dd" + integrity sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg== dependencies: - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - rimraf "^3.0.2" - unzipper "^0.10.11" + "@typescript-eslint/types" "4.33.0" + eslint-visitor-keys "^2.0.0" -acorn-jsx@^5.3.2: +acorn-jsx@^5.2.0: version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + resolved "http://10.121.8.15:9813/repository/npm-group/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn@^8.7.1: - version "8.8.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" - integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== +acorn@^7.1.1: + version "7.4.1" + resolved "http://10.121.8.15:9813/repository/npm-group/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + +acorn@^8.0.4: + version "8.7.1" + resolved "http://10.121.8.15:9813/repository/npm-group/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30" + integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A== agent-base@6: version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + resolved "http://10.121.8.15:9813/repository/npm-group/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== dependencies: debug "4" -ajv@^6.10.0, ajv@^6.12.4: +ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3: version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + resolved "http://10.121.8.15:9813/repository/npm-group/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== dependencies: fast-deep-equal "^3.1.1" @@ -217,364 +583,812 @@ ajv@^6.10.0, ajv@^6.12.4: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ansi-colors@4.1.1: +algm@^0.1.6: + version "0.1.9" + resolved "http://10.121.8.15:9813/repository/npm-group/algm/-/algm-0.1.9.tgz#470dda22c3f211ac2e0a1f42dbf2f62b559269e9" + integrity sha512-K6udeYucjsySZoMtsV09hR96m7YBgZmBqYLIWQj0fP/mddAB5ace0ofaKpJO2ujxoRn+bVjBRUuzdt0NrBzrvw== + +ansi-colors@3.2.3: + version "3.2.3" + resolved "http://10.121.8.15:9813/repository/npm-group/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" + integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw== + +ansi-escapes@^4.2.1: + version "4.3.2" + resolved "http://10.121.8.15:9813/repository/npm-group/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-regex@^3.0.0: + version "3.0.1" + resolved "http://10.121.8.15:9813/repository/npm-group/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" + integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw== + +ansi-regex@^4.1.0: version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + resolved "http://10.121.8.15:9813/repository/npm-group/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed" + integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== ansi-regex@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + resolved "http://10.121.8.15:9813/repository/npm-group/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-styles@^4.0.0, ansi-styles@^4.1.0: +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "http://10.121.8.15:9813/repository/npm-group/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.1.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + resolved "http://10.121.8.15:9813/repository/npm-group/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" -anymatch@~3.1.2: +anymatch@~3.1.1: version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + resolved "http://10.121.8.15:9813/repository/npm-group/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== dependencies: normalize-path "^3.0.0" picomatch "^2.0.4" -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== +argparse@^1.0.7: + version "1.0.10" + resolved "http://10.121.8.15:9813/repository/npm-group/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" array-union@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + resolved "http://10.121.8.15:9813/repository/npm-group/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== +asn1@~0.2.3: + version "0.2.6" + resolved "http://10.121.8.15:9813/repository/npm-group/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" + integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== + +ast-types@0.14.2, ast-types@^0.14.2: + version "0.14.2" + resolved "http://10.121.8.15:9813/repository/npm-group/ast-types/-/ast-types-0.14.2.tgz#600b882df8583e3cd4f2df5fa20fa83759d4bdfd" + integrity sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA== + dependencies: + tslib "^2.0.1" + +astral-regex@^1.0.0: + version "1.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + +asynckit@^0.4.0: + version "0.4.0" + resolved "http://10.121.8.15:9813/repository/npm-group/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +at-least-node@^1.0.0: + version "1.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "http://10.121.8.15:9813/repository/npm-group/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== + +aws4@^1.8.0: + version "1.11.0" + resolved "http://10.121.8.15:9813/repository/npm-group/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" + integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== + +axios@^0.21.1: + version "0.21.4" + resolved "http://10.121.8.15:9813/repository/npm-group/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" + integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== + dependencies: + follow-redirects "^1.14.0" + balanced-match@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + resolved "http://10.121.8.15:9813/repository/npm-group/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "http://10.121.8.15:9813/repository/npm-group/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== + dependencies: + tweetnacl "^0.14.3" + big-integer@^1.6.17: version "1.6.51" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" + resolved "http://10.121.8.15:9813/repository/npm-group/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== binary-extensions@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + resolved "http://10.121.8.15:9813/repository/npm-group/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== binary@~0.3.0: version "0.3.0" - resolved "https://registry.yarnpkg.com/binary/-/binary-0.3.0.tgz#9f60553bc5ce8c3386f3b553cff47462adecaa79" + resolved "http://10.121.8.15:9813/repository/npm-group/binary/-/binary-0.3.0.tgz#9f60553bc5ce8c3386f3b553cff47462adecaa79" integrity sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg== dependencies: buffers "~0.1.1" chainsaw "~0.1.0" +bl@^1.0.0: + version "1.2.3" + resolved "http://10.121.8.15:9813/repository/npm-group/bl/-/bl-1.2.3.tgz#1e8dd80142eac80d7158c9dccc047fb620e035e7" + integrity sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww== + dependencies: + readable-stream "^2.3.5" + safe-buffer "^5.1.1" + bluebird@~3.4.1: version "3.4.7" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" + resolved "http://10.121.8.15:9813/repository/npm-group/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" integrity sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA== +boolbase@^1.0.0: + version "1.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + brace-expansion@^1.1.7: version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + resolved "http://10.121.8.15:9813/repository/npm-group/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== dependencies: balanced-match "^1.0.0" concat-map "0.0.1" -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - braces@^3.0.2, braces@~3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + resolved "http://10.121.8.15:9813/repository/npm-group/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== dependencies: fill-range "^7.0.1" browser-stdout@1.3.1: version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + resolved "http://10.121.8.15:9813/repository/npm-group/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== +browserslist@^4.20.2: + version "4.21.2" + resolved "http://10.121.8.15:9813/repository/npm-group/browserslist/-/browserslist-4.21.2.tgz#59a400757465535954946a400b841ed37e2b4ecf" + integrity sha512-MonuOgAtUB46uP5CezYbRaYKBNt2LxP0yX+Pmj4LkcDFGkn9Cbpi83d9sCjwQDErXsIJSzY5oKGDbgOlF/LPAA== + dependencies: + caniuse-lite "^1.0.30001366" + electron-to-chromium "^1.4.188" + node-releases "^2.0.6" + update-browserslist-db "^1.0.4" + +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "http://10.121.8.15:9813/repository/npm-group/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "http://10.121.8.15:9813/repository/npm-group/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "http://10.121.8.15:9813/repository/npm-group/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== + +buffer-fill@^1.0.0: + version "1.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ== + buffer-indexof-polyfill@~1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz#d2732135c5999c64b277fcf9b1abe3498254729c" + resolved "http://10.121.8.15:9813/repository/npm-group/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz#d2732135c5999c64b277fcf9b1abe3498254729c" integrity sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A== buffers@~0.1.1: version "0.1.1" - resolved "https://registry.yarnpkg.com/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb" + resolved "http://10.121.8.15:9813/repository/npm-group/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb" integrity sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ== +builtin-modules@^3.1.0: + version "3.2.0" + resolved "http://10.121.8.15:9813/repository/npm-group/builtin-modules/-/builtin-modules-3.2.0.tgz#45d5db99e7ee5e6bc4f362e008bf917ab5049887" + integrity sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA== + +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "http://10.121.8.15:9813/repository/npm-group/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + callsites@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + resolved "http://10.121.8.15:9813/repository/npm-group/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -camelcase@^6.0.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== +camelcase@^5.0.0: + version "5.3.1" + resolved "http://10.121.8.15:9813/repository/npm-group/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +caniuse-lite@^1.0.30001366: + version "1.0.30001367" + resolved "http://10.121.8.15:9813/repository/npm-group/caniuse-lite/-/caniuse-lite-1.0.30001367.tgz#2b97fe472e8fa29c78c5970615d7cd2ee414108a" + integrity sha512-XDgbeOHfifWV3GEES2B8rtsrADx4Jf+juKX2SICJcaUhjYBO3bR96kvEIHa15VU6ohtOhBZuPGGYGbXMRn0NCw== + +caseless@~0.12.0: + version "0.12.0" + resolved "http://10.121.8.15:9813/repository/npm-group/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== chainsaw@~0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/chainsaw/-/chainsaw-0.1.0.tgz#5eab50b28afe58074d0d58291388828b5e5fbc98" + resolved "http://10.121.8.15:9813/repository/npm-group/chainsaw/-/chainsaw-0.1.0.tgz#5eab50b28afe58074d0d58291388828b5e5fbc98" integrity sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ== dependencies: traverse ">=0.3.0 <0.4" -chalk@^4.0.0, chalk@^4.1.0: +chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.2: + version "2.4.2" + resolved "http://10.121.8.15:9813/repository/npm-group/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.1.0: version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + resolved "http://10.121.8.15:9813/repository/npm-group/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== dependencies: ansi-styles "^4.1.0" supports-color "^7.1.0" -chokidar@3.5.3: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== +chardet@^0.7.0: + version "0.7.0" + resolved "http://10.121.8.15:9813/repository/npm-group/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +cheerio-select@^1.5.0: + version "1.5.0" + resolved "http://10.121.8.15:9813/repository/npm-group/cheerio-select/-/cheerio-select-1.5.0.tgz#faf3daeb31b17c5e1a9dabcee288aaf8aafa5823" + integrity sha1-+vPa6zGxfF4anavO4oiq+Kr6WCM= + dependencies: + css-select "^4.1.3" + css-what "^5.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + domutils "^2.7.0" + +cheerio@^1.0.0-rc.3: + version "1.0.0-rc.10" + resolved "http://10.121.8.15:9813/repository/npm-group/cheerio/-/cheerio-1.0.0-rc.10.tgz#2ba3dcdfcc26e7956fc1f440e61d51c643379f3e" + integrity sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw== + dependencies: + cheerio-select "^1.5.0" + dom-serializer "^1.3.2" + domhandler "^4.2.0" + htmlparser2 "^6.1.0" + parse5 "^6.0.1" + parse5-htmlparser2-tree-adapter "^6.0.1" + tslib "^2.2.0" + +chokidar@3.3.0: + version "3.3.0" + resolved "http://10.121.8.15:9813/repository/npm-group/chokidar/-/chokidar-3.3.0.tgz#12c0714668c55800f659e262d4962a97faf554a6" + integrity sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A== dependencies: - anymatch "~3.1.2" + anymatch "~3.1.1" braces "~3.0.2" - glob-parent "~5.1.2" + glob-parent "~5.1.0" is-binary-path "~2.1.0" is-glob "~4.0.1" normalize-path "~3.0.0" - readdirp "~3.6.0" + readdirp "~3.2.0" optionalDependencies: - fsevents "~2.3.2" + fsevents "~2.1.1" -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== +cli-cursor@^3.1.0: + version "3.1.0" + resolved "http://10.121.8.15:9813/repository/npm-group/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" + restore-cursor "^3.1.0" + +cli-width@^3.0.0: + version "3.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" + integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== + +cliui@^5.0.0: + version "5.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "http://10.121.8.15:9813/repository/npm-group/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" color-convert@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + resolved "http://10.121.8.15:9813/repository/npm-group/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== dependencies: color-name "~1.1.4" +color-name@1.1.3: + version "1.1.3" + resolved "http://10.121.8.15:9813/repository/npm-group/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + color-name@~1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + resolved "http://10.121.8.15:9813/repository/npm-group/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "http://10.121.8.15:9813/repository/npm-group/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +compressing@^1.5.1: + version "1.6.2" + resolved "https://registry.yarnpkg.com/compressing/-/compressing-1.6.2.tgz#87320c2d867364045403792c08694e4e8284099c" + integrity sha512-1HK+eK//Tx45n2kuVCl2ITDMZD2JkZAolOYyJrV260lUnq1rPt4d+6L6OvwRFLqAt5aR0vAtGGGiJNmTxqff/g== + dependencies: + flushwritable "^1.0.0" + get-ready "^1.0.0" + iconv-lite "^0.5.0" + mkdirp "^0.5.1" + pump "^3.0.0" + streamifier "^0.1.1" + tar-stream "^1.5.2" + yauzl "^2.7.0" + yazl "^2.4.2" + concat-map@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + resolved "http://10.121.8.15:9813/repository/npm-group/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== +convert-source-map@^1.7.0: + version "1.8.0" + resolved "http://10.121.8.15:9813/repository/npm-group/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== + dependencies: + safe-buffer "~5.1.1" + +core-util-is@1.0.2: + version "1.0.2" + resolved "http://10.121.8.15:9813/repository/npm-group/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== + core-util-is@~1.0.0: version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + resolved "http://10.121.8.15:9813/repository/npm-group/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== -cross-spawn@^7.0.2: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== +cross-spawn@^6.0.5: + version "6.0.5" + resolved "http://10.121.8.15:9813/repository/npm-group/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +css-select@^4.1.3: + version "4.2.1" + resolved "http://10.121.8.15:9813/repository/npm-group/css-select/-/css-select-4.2.1.tgz#9e665d6ae4c7f9d65dbe69d0316e3221fb274cdd" + integrity sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ== + dependencies: + boolbase "^1.0.0" + css-what "^5.1.0" + domhandler "^4.3.0" + domutils "^2.8.0" + nth-check "^2.0.1" + +css-what@^5.0.1, css-what@^5.1.0: + version "5.1.0" + resolved "http://10.121.8.15:9813/repository/npm-group/css-what/-/css-what-5.1.0.tgz#3f7b707aadf633baf62c2ceb8579b545bb40f7fe" + integrity sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw== + +dashdash@^1.12.0: + version "1.14.1" + resolved "http://10.121.8.15:9813/repository/npm-group/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== + dependencies: + assert-plus "^1.0.0" + +debug@3.2.6: + version "3.2.6" + resolved "http://10.121.8.15:9813/repository/npm-group/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" + ms "^2.1.1" -debug@4, debug@4.3.4, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: +debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.3.1: version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + resolved "http://10.121.8.15:9813/repository/npm-group/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" -decamelize@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" - integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== +decamelize@^1.2.0: + version "1.2.0" + resolved "http://10.121.8.15:9813/repository/npm-group/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== -deep-is@^0.1.3: +deep-is@~0.1.3: version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + resolved "http://10.121.8.15:9813/repository/npm-group/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== -diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== +deepmerge@^4.2.2: + version "4.2.2" + resolved "http://10.121.8.15:9813/repository/npm-group/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + +define-properties@^1.1.2, define-properties@^1.1.3: + version "1.1.3" + resolved "http://10.121.8.15:9813/repository/npm-group/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + +diff@3.5.0: + version "3.5.0" + resolved "http://10.121.8.15:9813/repository/npm-group/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== dir-glob@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + resolved "http://10.121.8.15:9813/repository/npm-group/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== dependencies: path-type "^4.0.0" doctrine@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + resolved "http://10.121.8.15:9813/repository/npm-group/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== dependencies: esutils "^2.0.2" +dom-serializer@^1.0.1, dom-serializer@^1.3.2: + version "1.4.1" + resolved "http://10.121.8.15:9813/repository/npm-group/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30" + integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.2.0" + entities "^2.0.0" + +domelementtype@^2.0.1, domelementtype@^2.2.0: + version "2.3.0" + resolved "http://10.121.8.15:9813/repository/npm-group/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.0: + version "4.3.1" + resolved "http://10.121.8.15:9813/repository/npm-group/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" + integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== + dependencies: + domelementtype "^2.2.0" + +domutils@^2.5.2, domutils@^2.7.0, domutils@^2.8.0: + version "2.8.0" + resolved "http://10.121.8.15:9813/repository/npm-group/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" + integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + duplexer2@~0.1.4: version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" + resolved "http://10.121.8.15:9813/repository/npm-group/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" integrity sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA== dependencies: readable-stream "^2.0.2" +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "http://10.121.8.15:9813/repository/npm-group/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +electron-to-chromium@^1.4.188: + version "1.4.192" + resolved "http://10.121.8.15:9813/repository/npm-group/electron-to-chromium/-/electron-to-chromium-1.4.192.tgz#fac050058b3e0713b401a1088cc579e14c2ab165" + integrity sha512-8nCXyIQY9An88NXAp+PuPy5h3/w5ZY7Iu2lag65Q0XREprcat5F8gKhoHsBUnQcFuCRnmevpR8yEBYRU3d2HDw== + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "http://10.121.8.15:9813/repository/npm-group/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + emoji-regex@^8.0.0: version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + resolved "http://10.121.8.15:9813/repository/npm-group/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.4" + resolved "http://10.121.8.15:9813/repository/npm-group/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +entities@^2.0.0: + version "2.2.0" + resolved "http://10.121.8.15:9813/repository/npm-group/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + +entities@~2.0.0: + version "2.0.3" + resolved "http://10.121.8.15:9813/repository/npm-group/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f" + integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ== + +es-abstract@^1.19.1: + version "1.19.1" + resolved "http://10.121.8.15:9813/repository/npm-group/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" + integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + get-intrinsic "^1.1.1" + get-symbol-description "^1.0.0" + has "^1.0.3" + has-symbols "^1.0.2" + internal-slot "^1.0.3" + is-callable "^1.2.4" + is-negative-zero "^2.0.1" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.1" + is-string "^1.0.7" + is-weakref "^1.0.1" + object-inspect "^1.11.0" + object-keys "^1.1.1" + object.assign "^4.1.2" + string.prototype.trimend "^1.0.4" + string.prototype.trimstart "^1.0.4" + unbox-primitive "^1.0.1" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "http://10.121.8.15:9813/repository/npm-group/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + escalade@^3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + resolved "http://10.121.8.15:9813/repository/npm-group/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== -escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "http://10.121.8.15:9813/repository/npm-group/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== -eslint-scope@^5.1.1: +eslint-config-prettier@^8.3.0: + version "8.5.0" + resolved "http://10.121.8.15:9813/repository/npm-group/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1" + integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q== + +eslint-plugin-prettier@^3.4.0: + version "3.4.1" + resolved "http://10.121.8.15:9813/repository/npm-group/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz#e9ddb200efb6f3d05ffe83b1665a716af4a387e5" + integrity sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g== + dependencies: + prettier-linter-helpers "^1.0.0" + +eslint-scope@^5.0.0, eslint-scope@^5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + resolved "http://10.121.8.15:9813/repository/npm-group/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== dependencies: esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-scope@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" - integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== +eslint-utils@^1.4.3: + version "1.4.3" + resolved "http://10.121.8.15:9813/repository/npm-group/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" + integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" + eslint-visitor-keys "^1.1.0" eslint-utils@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" + resolved "http://10.121.8.15:9813/repository/npm-group/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== dependencies: eslint-visitor-keys "^2.0.0" +eslint-visitor-keys@^1.1.0: + version "1.3.0" + resolved "http://10.121.8.15:9813/repository/npm-group/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + eslint-visitor-keys@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + resolved "http://10.121.8.15:9813/repository/npm-group/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== -eslint-visitor-keys@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" - integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== - -eslint@^8.18.0: - version "8.20.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.20.0.tgz#048ac56aa18529967da8354a478be4ec0a2bc81b" - integrity sha512-d4ixhz5SKCa1D6SCPrivP7yYVi7nyD6A4vs6HIAul9ujBzcEmZVM3/0NN/yu5nKhmO1wjp5xQ46iRfmDGlOviA== +eslint@^6.8.0: + version "6.8.0" + resolved "http://10.121.8.15:9813/repository/npm-group/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" + integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== dependencies: - "@eslint/eslintrc" "^1.3.0" - "@humanwhocodes/config-array" "^0.9.2" + "@babel/code-frame" "^7.0.0" ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^4.0.1" doctrine "^3.0.0" - escape-string-regexp "^4.0.0" - eslint-scope "^7.1.1" - eslint-utils "^3.0.0" - eslint-visitor-keys "^3.3.0" - espree "^9.3.2" - esquery "^1.4.0" + eslint-scope "^5.0.0" + eslint-utils "^1.4.3" + eslint-visitor-keys "^1.1.0" + espree "^6.1.2" + esquery "^1.0.1" esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" + file-entry-cache "^5.0.1" functional-red-black-tree "^1.0.1" - glob-parent "^6.0.1" - globals "^13.15.0" - ignore "^5.2.0" + glob-parent "^5.0.0" + globals "^12.1.0" + ignore "^4.0.6" import-fresh "^3.0.0" imurmurhash "^0.1.4" + inquirer "^7.0.0" is-glob "^4.0.0" - js-yaml "^4.1.0" + js-yaml "^3.13.1" json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" + levn "^0.3.0" + lodash "^4.17.14" + minimatch "^3.0.4" + mkdirp "^0.5.1" natural-compare "^1.4.0" - optionator "^0.9.1" - regexpp "^3.2.0" - strip-ansi "^6.0.1" - strip-json-comments "^3.1.0" + optionator "^0.8.3" + progress "^2.0.0" + regexpp "^2.0.1" + semver "^6.1.2" + strip-ansi "^5.2.0" + strip-json-comments "^3.0.1" + table "^5.2.3" text-table "^0.2.0" v8-compile-cache "^2.0.3" -espree@^9.3.2: - version "9.3.2" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.2.tgz#f58f77bd334731182801ced3380a8cc859091596" - integrity sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA== +espree@^6.1.2: + version "6.2.1" + resolved "http://10.121.8.15:9813/repository/npm-group/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" + integrity sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw== dependencies: - acorn "^8.7.1" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.3.0" + acorn "^7.1.1" + acorn-jsx "^5.2.0" + eslint-visitor-keys "^1.1.0" + +esprima@^4.0.0, esprima@~4.0.0: + version "4.0.1" + resolved "http://10.121.8.15:9813/repository/npm-group/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.4.0: +esquery@^1.0.1: version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + resolved "http://10.121.8.15:9813/repository/npm-group/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== dependencies: estraverse "^5.1.0" esrecurse@^4.3.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + resolved "http://10.121.8.15:9813/repository/npm-group/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: estraverse "^5.2.0" estraverse@^4.1.1: version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + resolved "http://10.121.8.15:9813/repository/npm-group/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== estraverse@^5.1.0, estraverse@^5.2.0: version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + resolved "http://10.121.8.15:9813/repository/npm-group/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== +estree-walker@^1.0.1: + version "1.0.1" + resolved "http://10.121.8.15:9813/repository/npm-group/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" + integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== + esutils@^2.0.2: version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + resolved "http://10.121.8.15:9813/repository/npm-group/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: +extend@~3.0.2: + version "3.0.2" + resolved "http://10.121.8.15:9813/repository/npm-group/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +external-editor@^3.0.3: + version "3.1.0" + resolved "http://10.121.8.15:9813/repository/npm-group/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +extsprintf@1.3.0: + version "1.3.0" + resolved "http://10.121.8.15:9813/repository/npm-group/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== + +extsprintf@^1.2.0: + version "1.4.1" + resolved "http://10.121.8.15:9813/repository/npm-group/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" + integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== + +fast-deep-equal@^3.1.1: version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + resolved "http://10.121.8.15:9813/repository/npm-group/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== +fast-diff@^1.1.2: + version "1.2.0" + resolved "http://10.121.8.15:9813/repository/npm-group/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + fast-glob@^3.2.9: version "3.2.11" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" + resolved "http://10.121.8.15:9813/repository/npm-group/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== dependencies: "@nodelib/fs.stat" "^2.0.2" @@ -585,74 +1399,143 @@ fast-glob@^3.2.9: fast-json-stable-stringify@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + resolved "http://10.121.8.15:9813/repository/npm-group/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fast-levenshtein@^2.0.6: +fast-levenshtein@~2.0.6: version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + resolved "http://10.121.8.15:9813/repository/npm-group/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fastq@^1.6.0: version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + resolved "http://10.121.8.15:9813/repository/npm-group/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== dependencies: reusify "^1.0.4" -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== +fd-slicer@~1.1.0: + version "1.1.0" + resolved "http://10.121.8.15:9813/repository/npm-group/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g== + dependencies: + pend "~1.2.0" + +figures@^3.0.0: + version "3.2.0" + resolved "http://10.121.8.15:9813/repository/npm-group/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^5.0.1: + version "5.0.1" + resolved "http://10.121.8.15:9813/repository/npm-group/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== dependencies: - flat-cache "^3.0.4" + flat-cache "^2.0.1" fill-range@^7.0.1: version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + resolved "http://10.121.8.15:9813/repository/npm-group/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== dependencies: to-regex-range "^5.0.1" -find-up@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== +find-up@3.0.0, find-up@^3.0.0: + version "3.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" + locate-path "^3.0.0" -flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== +flat-cache@^2.0.1: + version "2.0.1" + resolved "http://10.121.8.15:9813/repository/npm-group/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== dependencies: - flatted "^3.1.0" - rimraf "^3.0.2" + flatted "^2.0.0" + rimraf "2.6.3" + write "1.0.3" -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== +flat@^4.1.0: + version "4.1.1" + resolved "http://10.121.8.15:9813/repository/npm-group/flat/-/flat-4.1.1.tgz#a392059cc382881ff98642f5da4dde0a959f309b" + integrity sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA== + dependencies: + is-buffer "~2.0.3" -flatted@^3.1.0: - version "3.2.6" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.6.tgz#022e9218c637f9f3fc9c35ab9c9193f05add60b2" - integrity sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ== +flatted@^2.0.0: + version "2.0.2" + resolved "http://10.121.8.15:9813/repository/npm-group/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" + integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== + +flushwritable@^1.0.0: + version "1.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/flushwritable/-/flushwritable-1.0.0.tgz#3e328d8fde412ad47e738e3be750b4d290043498" + integrity sha1-PjKNj95BKtR+c44751C00pAENJg= + +follow-redirects@^1.14.0: + version "1.14.9" + resolved "http://10.121.8.15:9813/repository/npm-group/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7" + integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w== + +forever-agent@~0.6.1: + version "0.6.1" + resolved "http://10.121.8.15:9813/repository/npm-group/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== + +form-data@^2.5.0: + version "2.5.1" + resolved "http://10.121.8.15:9813/repository/npm-group/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" + integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +form-data@~2.3.2: + version "2.3.3" + resolved "http://10.121.8.15:9813/repository/npm-group/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +fs-constants@^1.0.0: + version "1.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + +fs-extra@^9.1.0: + version "9.1.0" + resolved "http://10.121.8.15:9813/repository/npm-group/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" fs.realpath@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + resolved "http://10.121.8.15:9813/repository/npm-group/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== +fsevents@~2.1.1: + version "2.1.3" + resolved "http://10.121.8.15:9813/repository/npm-group/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" + integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== + fsevents@~2.3.2: version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + resolved "http://10.121.8.15:9813/repository/npm-group/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== fstream@^1.0.12: version "1.0.12" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" + resolved "http://10.121.8.15:9813/repository/npm-group/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== dependencies: graceful-fs "^4.1.2" @@ -660,34 +1543,66 @@ fstream@^1.0.12: mkdirp ">=0.5 0" rimraf "2" +function-bind@^1.1.1: + version "1.1.1" + resolved "http://10.121.8.15:9813/repository/npm-group/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + functional-red-black-tree@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + resolved "http://10.121.8.15:9813/repository/npm-group/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== -get-caller-file@^2.0.5: +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "http://10.121.8.15:9813/repository/npm-group/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-caller-file@^2.0.1: version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + resolved "http://10.121.8.15:9813/repository/npm-group/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -glob-parent@^5.1.2, glob-parent@~5.1.2: +get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: + version "1.1.2" + resolved "http://10.121.8.15:9813/repository/npm-group/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598" + integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + +get-ready@^1.0.0: + version "1.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/get-ready/-/get-ready-1.0.0.tgz#f91817f1e9adecfea13a562adfc8de883ab34782" + integrity sha1-+RgX8emt7P6hOlYq38jeiDqzR4I= + +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + +getpass@^0.1.1: + version "0.1.7" + resolved "http://10.121.8.15:9813/repository/npm-group/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== + dependencies: + assert-plus "^1.0.0" + +glob-parent@^5.0.0, glob-parent@^5.1.2, glob-parent@~5.1.0: version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + resolved "http://10.121.8.15:9813/repository/npm-group/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" -glob-parent@^6.0.1: - version "6.0.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - -glob@7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== +glob@7.1.3: + version "7.1.3" + resolved "http://10.121.8.15:9813/repository/npm-group/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -696,9 +1611,9 @@ glob@7.2.0: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.1.3: +glob@^7.1.3, glob@^7.1.6: version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + resolved "http://10.121.8.15:9813/repository/npm-group/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== dependencies: fs.realpath "^1.0.0" @@ -708,27 +1623,21 @@ glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^8.0.3: - version "8.0.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-8.0.3.tgz#415c6eb2deed9e502c68fa44a272e6da6eeca42e" - integrity sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ== +globals@^11.1.0: + version "11.12.0" + resolved "http://10.121.8.15:9813/repository/npm-group/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globals@^12.1.0: + version "12.4.0" + resolved "http://10.121.8.15:9813/repository/npm-group/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" + integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^5.0.1" - once "^1.3.0" - -globals@^13.15.0: - version "13.17.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.17.0.tgz#902eb1e680a41da93945adbdcb5a9f361ba69bd4" - integrity sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw== - dependencies: - type-fest "^0.20.2" + type-fest "^0.8.1" -globby@^11.1.0: +globby@^11.0.3: version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + resolved "http://10.121.8.15:9813/repository/npm-group/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== dependencies: array-union "^2.1.0" @@ -738,46 +1647,141 @@ globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" -graceful-fs@^4.1.2, graceful-fs@^4.2.2: +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2: version "4.2.10" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + resolved "http://10.121.8.15:9813/repository/npm-group/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== +growl@1.10.5: + version "1.10.5" + resolved "http://10.121.8.15:9813/repository/npm-group/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + +har-schema@^2.0.0: + version "2.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q== + +har-validator@~5.1.3: + version "5.1.5" + resolved "http://10.121.8.15:9813/repository/npm-group/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== + dependencies: + ajv "^6.12.3" + har-schema "^2.0.0" + +has-bigints@^1.0.1: + version "1.0.1" + resolved "http://10.121.8.15:9813/repository/npm-group/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== + +has-flag@^3.0.0: + version "3.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + has-flag@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + resolved "http://10.121.8.15:9813/repository/npm-group/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-symbols@^1.0.0, has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "http://10.121.8.15:9813/repository/npm-group/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +has@^1.0.3: + version "1.0.3" + resolved "http://10.121.8.15:9813/repository/npm-group/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + he@1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + resolved "http://10.121.8.15:9813/repository/npm-group/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +highlight.js@^11.0.0: + version "11.5.0" + resolved "http://10.121.8.15:9813/repository/npm-group/highlight.js/-/highlight.js-11.5.0.tgz#00abb7ed926491adbdabc93a4f3fd2b88b451b4a" + integrity sha512-SM6WDj5/C+VfIY8pZ6yW6Xa0Fm1tniYVYWYW1Q/DcMnISZFrC3aQAZZZFAAZtybKNrGId3p/DNbFTtcTXXgYBw== + +htmlparser2@^6.1.0: + version "6.1.0" + resolved "http://10.121.8.15:9813/repository/npm-group/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" + integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.0.0" + domutils "^2.5.2" + entities "^2.0.0" + http-proxy-agent@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + resolved "http://10.121.8.15:9813/repository/npm-group/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== dependencies: "@tootallnate/once" "1" agent-base "6" debug "4" +http-signature@~1.2.0: + version "1.2.0" + resolved "http://10.121.8.15:9813/repository/npm-group/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ== + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + https-proxy-agent@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" - integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + version "5.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== dependencies: agent-base "6" debug "4" -ignore@^5.2.0: +husky@^6.0.0: + version "6.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/husky/-/husky-6.0.0.tgz#810f11869adf51604c32ea577edbc377d7f9319e" + integrity sha512-SQS2gDTB7tBN486QSoKPKQItZw97BMOd+Kdb6ghfpBc0yXyzrddI0oDV5MkDAbuB4X2mO3/nj60TRMcYxwzZeQ== + +iconv-lite@^0.4.24: + version "0.4.24" + resolved "http://10.121.8.15:9813/repository/npm-group/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@^0.5.0: + version "0.5.2" + resolved "http://10.121.8.15:9813/repository/npm-group/iconv-lite/-/iconv-lite-0.5.2.tgz#af6d628dccfb463b7364d97f715e4b74b8c8c2b8" + integrity sha512-kERHXvpSaB4aU3eANwidg79K8FlrN77m8G9V+0vOR3HYaRifrlwMEpT7ZBJqLSEIHnEgJTHcWK82wwLwwKwtag== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ignore@^4.0.6: + version "4.0.6" + resolved "http://10.121.8.15:9813/repository/npm-group/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +ignore@^5.1.8, ignore@^5.2.0: version "5.2.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + resolved "http://10.121.8.15:9813/repository/npm-group/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== -import-fresh@^3.0.0, import-fresh@^3.2.1: +import-fresh@^3.0.0: version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + resolved "http://10.121.8.15:9813/repository/npm-group/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== dependencies: parent-module "^1.0.0" @@ -785,12 +1789,12 @@ import-fresh@^3.0.0, import-fresh@^3.2.1: imurmurhash@^0.1.4: version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + resolved "http://10.121.8.15:9813/repository/npm-group/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== inflight@^1.0.4: version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + resolved "http://10.121.8.15:9813/repository/npm-group/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== dependencies: once "^1.3.0" @@ -798,309 +1802,693 @@ inflight@^1.0.4: inherits@2, inherits@~2.0.0, inherits@~2.0.3: version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + resolved "http://10.121.8.15:9813/repository/npm-group/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +inquirer@^7.0.0: + version "7.3.3" + resolved "http://10.121.8.15:9813/repository/npm-group/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" + integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA== + dependencies: + ansi-escapes "^4.2.1" + chalk "^4.1.0" + cli-cursor "^3.1.0" + cli-width "^3.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.19" + mute-stream "0.0.8" + run-async "^2.4.0" + rxjs "^6.6.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + through "^2.3.6" + +internal-slot@^1.0.3: + version "1.0.3" + resolved "http://10.121.8.15:9813/repository/npm-group/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" + integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== + dependencies: + get-intrinsic "^1.1.0" + has "^1.0.3" + side-channel "^1.0.4" + +is-bigint@^1.0.1: + version "1.0.4" + resolved "http://10.121.8.15:9813/repository/npm-group/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + is-binary-path@~2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + resolved "http://10.121.8.15:9813/repository/npm-group/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== dependencies: binary-extensions "^2.0.0" +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "http://10.121.8.15:9813/repository/npm-group/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-buffer@~2.0.3: + version "2.0.5" + resolved "http://10.121.8.15:9813/repository/npm-group/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" + integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== + +is-callable@^1.1.4, is-callable@^1.2.4: + version "1.2.4" + resolved "http://10.121.8.15:9813/repository/npm-group/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" + integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== + +is-core-module@^2.9.0: + version "2.9.0" + resolved "http://10.121.8.15:9813/repository/npm-group/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" + integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== + dependencies: + has "^1.0.3" + +is-date-object@^1.0.1: + version "1.0.5" + resolved "http://10.121.8.15:9813/repository/npm-group/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + is-extglob@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + resolved "http://10.121.8.15:9813/repository/npm-group/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w== + is-fullwidth-code-point@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + resolved "http://10.121.8.15:9813/repository/npm-group/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + resolved "http://10.121.8.15:9813/repository/npm-group/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== dependencies: is-extglob "^2.1.1" +is-module@^1.0.0: + version "1.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" + integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g== + +is-negative-zero@^2.0.1: + version "2.0.2" + resolved "http://10.121.8.15:9813/repository/npm-group/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== + +is-number-object@^1.0.4: + version "1.0.6" + resolved "http://10.121.8.15:9813/repository/npm-group/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0" + integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g== + dependencies: + has-tostringtag "^1.0.0" + is-number@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + resolved "http://10.121.8.15:9813/repository/npm-group/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-plain-obj@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== +is-regex@^1.1.4: + version "1.1.4" + resolved "http://10.121.8.15:9813/repository/npm-group/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== +is-shared-array-buffer@^1.0.1: + version "1.0.1" + resolved "http://10.121.8.15:9813/repository/npm-group/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" + integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== + +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "http://10.121.8.15:9813/repository/npm-group/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "http://10.121.8.15:9813/repository/npm-group/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== + +is-weakref@^1.0.1: + version "1.0.2" + resolved "http://10.121.8.15:9813/repository/npm-group/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" isarray@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + resolved "http://10.121.8.15:9813/repository/npm-group/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== isexe@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + resolved "http://10.121.8.15:9813/repository/npm-group/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -js-yaml@4.1.0, js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== +isstream@~0.1.2: + version "0.1.2" + resolved "http://10.121.8.15:9813/repository/npm-group/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== + +js-tokens@^4.0.0: + version "4.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@3.13.1: + version "3.13.1" + resolved "http://10.121.8.15:9813/repository/npm-group/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js-yaml@^3.13.1: + version "3.14.1" + resolved "http://10.121.8.15:9813/repository/npm-group/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== dependencies: - argparse "^2.0.1" + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "http://10.121.8.15:9813/repository/npm-group/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== + +jsesc@^2.5.1: + version "2.5.2" + resolved "http://10.121.8.15:9813/repository/npm-group/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== json-schema-traverse@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + resolved "http://10.121.8.15:9813/repository/npm-group/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== +json-schema@0.4.0: + version "0.4.0" + resolved "http://10.121.8.15:9813/repository/npm-group/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== + json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + resolved "http://10.121.8.15:9813/repository/npm-group/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "http://10.121.8.15:9813/repository/npm-group/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== + +json5@^2.2.1: + version "2.2.1" + resolved "http://10.121.8.15:9813/repository/npm-group/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" + integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + +jsonfile@^6.0.1: + version "6.1.0" + resolved "http://10.121.8.15:9813/repository/npm-group/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +jsprim@^1.2.2: + version "1.4.2" + resolved "http://10.121.8.15:9813/repository/npm-group/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" + integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.4.0" + verror "1.10.0" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "http://10.121.8.15:9813/repository/npm-group/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +linkify-it@^2.0.0: + version "2.2.0" + resolved "http://10.121.8.15:9813/repository/npm-group/linkify-it/-/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf" + integrity sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw== dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" + uc.micro "^1.0.1" listenercount@~1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/listenercount/-/listenercount-1.0.1.tgz#84c8a72ab59c4725321480c975e6508342e70937" + resolved "http://10.121.8.15:9813/repository/npm-group/listenercount/-/listenercount-1.0.1.tgz#84c8a72ab59c4725321480c975e6508342e70937" integrity sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ== -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== +locate-path@^3.0.0: + version "3.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== dependencies: - p-locate "^5.0.0" + p-locate "^3.0.0" + path-exists "^3.0.0" -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19: + version "4.17.21" + resolved "http://10.121.8.15:9813/repository/npm-group/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -log-symbols@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== +log-symbols@3.0.0: + version "3.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" + integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ== dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" + chalk "^2.4.2" lru-cache@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + resolved "http://10.121.8.15:9813/repository/npm-group/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== dependencies: yallist "^4.0.0" +markdown-it@^10.0.0: + version "10.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/markdown-it/-/markdown-it-10.0.0.tgz#abfc64f141b1722d663402044e43927f1f50a8dc" + integrity sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg== + dependencies: + argparse "^1.0.7" + entities "~2.0.0" + linkify-it "^2.0.0" + mdurl "^1.0.1" + uc.micro "^1.0.5" + +mdurl@^1.0.1: + version "1.0.1" + resolved "http://10.121.8.15:9813/repository/npm-group/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g== + merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + resolved "http://10.121.8.15:9813/repository/npm-group/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== micromatch@^4.0.4: version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + resolved "http://10.121.8.15:9813/repository/npm-group/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== dependencies: braces "^3.0.2" picomatch "^2.3.1" -minimatch@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" - integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== +mime-db@1.52.0: + version "1.52.0" + resolved "http://10.121.8.15:9813/repository/npm-group/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12, mime-types@~2.1.19: + version "2.1.35" + resolved "http://10.121.8.15:9813/repository/npm-group/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: - brace-expansion "^2.0.1" + mime-db "1.52.0" -minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== +mimic-fn@^2.1.0: + version "2.1.0" + resolved "http://10.121.8.15:9813/repository/npm-group/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimatch@3.0.4: + version "3.0.4" + resolved "http://10.121.8.15:9813/repository/npm-group/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" -minimatch@^5.0.1: - version "5.1.0" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7" - integrity sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg== +minimatch@^3.0.4, minimatch@^3.1.1: + version "3.1.2" + resolved "http://10.121.8.15:9813/repository/npm-group/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: - brace-expansion "^2.0.1" + brace-expansion "^1.1.7" -minimist@^1.2.6: +minimist@^1.2.5, minimist@^1.2.6: version "1.2.6" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" + resolved "http://10.121.8.15:9813/repository/npm-group/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== -"mkdirp@>=0.5 0": +mkdirp@0.5.5: + version "0.5.5" + resolved "http://10.121.8.15:9813/repository/npm-group/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +"mkdirp@>=0.5 0", mkdirp@^0.5.1: version "0.5.6" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + resolved "http://10.121.8.15:9813/repository/npm-group/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== dependencies: minimist "^1.2.6" -mocha@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.0.0.tgz#205447d8993ec755335c4b13deba3d3a13c4def9" - integrity sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA== +mocha@^7.1.2: + version "7.2.0" + resolved "http://10.121.8.15:9813/repository/npm-group/mocha/-/mocha-7.2.0.tgz#01cc227b00d875ab1eed03a75106689cfed5a604" + integrity sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ== dependencies: - "@ungap/promise-all-settled" "1.1.2" - ansi-colors "4.1.1" + ansi-colors "3.2.3" browser-stdout "1.3.1" - chokidar "3.5.3" - debug "4.3.4" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.2.0" + chokidar "3.3.0" + debug "3.2.6" + diff "3.5.0" + escape-string-regexp "1.0.5" + find-up "3.0.0" + glob "7.1.3" + growl "1.10.5" he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "5.0.1" - ms "2.1.3" - nanoid "3.3.3" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - workerpool "6.2.1" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" + js-yaml "3.13.1" + log-symbols "3.0.0" + minimatch "3.0.4" + mkdirp "0.5.5" + ms "2.1.1" + node-environment-flags "1.0.6" + object.assign "4.1.0" + strip-json-comments "2.0.1" + supports-color "6.0.0" + which "1.3.1" + wide-align "1.1.3" + yargs "13.3.2" + yargs-parser "13.1.2" + yargs-unparser "1.6.0" + +ms@2.1.1: + version "2.1.1" + resolved "http://10.121.8.15:9813/repository/npm-group/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== ms@2.1.2: version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + resolved "http://10.121.8.15:9813/repository/npm-group/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3: +ms@^2.1.1: version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + resolved "http://10.121.8.15:9813/repository/npm-group/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -nanoid@3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" - integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== +mute-stream@0.0.8: + version "0.0.8" + resolved "http://10.121.8.15:9813/repository/npm-group/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== natural-compare@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + resolved "http://10.121.8.15:9813/repository/npm-group/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== +nice-try@^1.0.4: + version "1.0.5" + resolved "http://10.121.8.15:9813/repository/npm-group/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +node-environment-flags@1.0.6: + version "1.0.6" + resolved "http://10.121.8.15:9813/repository/npm-group/node-environment-flags/-/node-environment-flags-1.0.6.tgz#a30ac13621f6f7d674260a54dede048c3982c088" + integrity sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw== + dependencies: + object.getownpropertydescriptors "^2.0.3" + semver "^5.7.0" + +node-releases@^2.0.6: + version "2.0.6" + resolved "http://10.121.8.15:9813/repository/npm-group/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" + integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== + normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + resolved "http://10.121.8.15:9813/repository/npm-group/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -once@^1.3.0: +nth-check@^2.0.1: + version "2.1.1" + resolved "http://10.121.8.15:9813/repository/npm-group/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "http://10.121.8.15:9813/repository/npm-group/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-inspect@^1.11.0, object-inspect@^1.9.0: + version "1.12.0" + resolved "http://10.121.8.15:9813/repository/npm-group/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" + integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== + +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "http://10.121.8.15:9813/repository/npm-group/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@4.1.0: + version "4.1.0" + resolved "http://10.121.8.15:9813/repository/npm-group/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.assign@^4.1.2: + version "4.1.2" + resolved "http://10.121.8.15:9813/repository/npm-group/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + +object.getownpropertydescriptors@^2.0.3: + version "2.1.3" + resolved "http://10.121.8.15:9813/repository/npm-group/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz#b223cf38e17fefb97a63c10c91df72ccb386df9e" + integrity sha1-siPPOOF/77l6Y8EMkd9yzLOG354= + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + resolved "http://10.121.8.15:9813/repository/npm-group/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== +onetime@^5.1.0: + version "5.1.2" + resolved "http://10.121.8.15:9813/repository/npm-group/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== 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" + mimic-fn "^2.1.0" -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== +optionator@^0.8.3: + version "0.8.3" + resolved "http://10.121.8.15:9813/repository/npm-group/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== dependencies: - yocto-queue "^0.1.0" + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "http://10.121.8.15:9813/repository/npm-group/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== + +p-limit@^2.0.0: + version "2.3.0" + resolved "http://10.121.8.15:9813/repository/npm-group/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== dependencies: - p-limit "^3.0.2" + p-limit "^2.0.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "http://10.121.8.15:9813/repository/npm-group/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== parent-module@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + resolved "http://10.121.8.15:9813/repository/npm-group/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== dependencies: callsites "^3.0.0" -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== +parse5-htmlparser2-tree-adapter@^6.0.1: + version "6.0.1" + resolved "http://10.121.8.15:9813/repository/npm-group/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6" + integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA== + dependencies: + parse5 "^6.0.1" + +parse5@^6.0.1: + version "6.0.1" + resolved "http://10.121.8.15:9813/repository/npm-group/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + +path-exists@^3.0.0: + version "3.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== path-is-absolute@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + resolved "http://10.121.8.15:9813/repository/npm-group/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== -path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== +path-key@^2.0.1: + version "2.0.1" + resolved "http://10.121.8.15:9813/repository/npm-group/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== + +path-parse@^1.0.7: + version "1.0.7" + resolved "http://10.121.8.15:9813/repository/npm-group/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== path-type@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + resolved "http://10.121.8.15:9813/repository/npm-group/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: +pend@~1.2.0: + version "1.2.0" + resolved "http://10.121.8.15:9813/repository/npm-group/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== + +performance-now@^2.1.0: + version "2.1.0" + resolved "http://10.121.8.15:9813/repository/npm-group/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== + +picocolors@^1.0.0: + version "1.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.2, picomatch@^2.3.1: version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + resolved "http://10.121.8.15:9813/repository/npm-group/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== +prelude-ls@~1.1.2: + version "1.1.2" + resolved "http://10.121.8.15:9813/repository/npm-group/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== + +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@^2.3.0: + version "2.7.1" + resolved "http://10.121.8.15:9813/repository/npm-group/prettier/-/prettier-2.7.1.tgz#e235806850d057f97bb08368a4f7d899f7760c64" + integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g== + +pretty-object-string@2.0.0-beta.3: + version "2.0.0-beta.3" + resolved "http://10.121.8.15:9813/repository/npm-group/pretty-object-string/-/pretty-object-string-2.0.0-beta.3.tgz#24b7b16cdc7695c68c2db50fe92ca65ac03f08f3" + integrity sha512-avVrBGrWGbbr/ZMUdP2Lc7jbUf6mOTJvvFm/2CgsAfGi7o/qNaAWc0oUwSnPyQF5/2pR3dJCbpYYAXM002efXw== + +pretty-tag@^0.1.1: + version "0.1.1" + resolved "http://10.121.8.15:9813/repository/npm-group/pretty-tag/-/pretty-tag-0.1.1.tgz#44aa3a58ec0cb2ada1f989f580d6666c24c86b5b" + integrity sha512-eBMBER1RCCZClLO14bnLq4rt5TFQMUU8FbuwK+7P3kZt1uXgpNoIEIXdYg0lxFzyD+VCuZpJa1trq6fmIdEm7Q== process-nextick-args@~2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + resolved "http://10.121.8.15:9813/repository/npm-group/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== -punycode@^2.1.0: +progress@^2.0.0: + version "2.0.3" + resolved "http://10.121.8.15:9813/repository/npm-group/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +psl@^1.1.28: + version "1.8.0" + resolved "http://10.121.8.15:9813/repository/npm-group/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + +pump@^3.0.0: + version "3.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + resolved "http://10.121.8.15:9813/repository/npm-group/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +qs@~6.5.2: + version "6.5.3" + resolved "http://10.121.8.15:9813/repository/npm-group/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" + integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== + queue-microtask@^1.2.2: version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + resolved "http://10.121.8.15:9813/repository/npm-group/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -readable-stream@^2.0.2, readable-stream@~2.3.6: +readable-stream@^2.0.2, readable-stream@^2.3.0, readable-stream@^2.3.5, readable-stream@~2.3.6: version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + resolved "http://10.121.8.15:9813/repository/npm-group/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== dependencies: core-util-is "~1.0.0" @@ -1111,191 +2499,510 @@ readable-stream@^2.0.2, readable-stream@~2.3.6: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== +readdirp@~3.2.0: + version "3.2.0" + resolved "http://10.121.8.15:9813/repository/npm-group/readdirp/-/readdirp-3.2.0.tgz#c30c33352b12c96dfb4b895421a49fd5a9593839" + integrity sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ== + dependencies: + picomatch "^2.0.4" + +recast@^0.20.4: + version "0.20.5" + resolved "http://10.121.8.15:9813/repository/npm-group/recast/-/recast-0.20.5.tgz#8e2c6c96827a1b339c634dd232957d230553ceae" + integrity sha512-E5qICoPoNL4yU0H0NoBDntNB0Q5oMSNh9usFctYniLBluTthi3RsQVBXIJNbApOlvSwW/RGxIuokPcAc59J5fQ== dependencies: - picomatch "^2.2.1" + ast-types "0.14.2" + esprima "~4.0.0" + source-map "~0.6.1" + tslib "^2.0.1" + +regexpp@^2.0.1: + version "2.0.1" + resolved "http://10.121.8.15:9813/repository/npm-group/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== -regexpp@^3.2.0: +regexpp@^3.1.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + resolved "http://10.121.8.15:9813/repository/npm-group/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== +request@^2.88.2: + version "2.88.2" + resolved "http://10.121.8.15:9813/repository/npm-group/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + require-directory@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + resolved "http://10.121.8.15:9813/repository/npm-group/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== +require-main-filename@^2.0.0: + version "2.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + resolve-from@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + resolved "http://10.121.8.15:9813/repository/npm-group/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== +resolve@^1.17.0, resolve@^1.19.0: + version "1.22.1" + resolved "http://10.121.8.15:9813/repository/npm-group/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +restore-cursor@^3.1.0: + version "3.1.0" + resolved "http://10.121.8.15:9813/repository/npm-group/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + reusify@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + resolved "http://10.121.8.15:9813/repository/npm-group/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== rimraf@2: version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + resolved "http://10.121.8.15:9813/repository/npm-group/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== dependencies: glob "^7.1.3" +rimraf@2.6.3: + version "2.6.3" + resolved "http://10.121.8.15:9813/repository/npm-group/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + rimraf@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + resolved "http://10.121.8.15:9813/repository/npm-group/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" +rollup@^2.40.0: + version "2.77.0" + resolved "http://10.121.8.15:9813/repository/npm-group/rollup/-/rollup-2.77.0.tgz#749eaa5ac09b6baa52acc076bc46613eddfd53f4" + integrity sha512-vL8xjY4yOQEw79DvyXLijhnhh+R/O9zpF/LEgkCebZFtb6ELeN9H3/2T0r8+mp+fFTBHZ5qGpOpW2ela2zRt3g== + optionalDependencies: + fsevents "~2.3.2" + +run-async@^2.4.0: + version "2.4.1" + resolved "http://10.121.8.15:9813/repository/npm-group/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" + integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== + run-parallel@^1.1.9: version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + resolved "http://10.121.8.15:9813/repository/npm-group/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== dependencies: queue-microtask "^1.2.2" -safe-buffer@^5.1.0: +rxjs@^6.6.0: + version "6.6.7" + resolved "http://10.121.8.15:9813/repository/npm-group/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" + integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== + dependencies: + tslib "^1.9.0" + +safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@^5.1.2: version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + resolved "http://10.121.8.15:9813/repository/npm-group/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + resolved "http://10.121.8.15:9813/repository/npm-group/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -semver@^7.3.7: +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "http://10.121.8.15:9813/repository/npm-group/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +semver@^5.5.0, semver@^5.7.0: + version "5.7.1" + resolved "http://10.121.8.15:9813/repository/npm-group/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^6.1.2, semver@^6.3.0: + version "6.3.0" + resolved "http://10.121.8.15:9813/repository/npm-group/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^7.3.5: version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + resolved "http://10.121.8.15:9813/repository/npm-group/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== dependencies: lru-cache "^6.0.0" -serialize-javascript@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== - dependencies: - randombytes "^2.1.0" +set-blocking@^2.0.0: + version "2.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== setimmediate@~1.0.4: version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + resolved "http://10.121.8.15:9813/repository/npm-group/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== +shebang-command@^1.2.0: + version "1.2.0" + resolved "http://10.121.8.15:9813/repository/npm-group/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== dependencies: - shebang-regex "^3.0.0" + shebang-regex "^1.0.0" -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== +shebang-regex@^1.0.0: + version "1.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== + +side-channel@^1.0.4: + version "1.0.4" + resolved "http://10.121.8.15:9813/repository/npm-group/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +signal-exit@^3.0.2: + version "3.0.7" + resolved "http://10.121.8.15:9813/repository/npm-group/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== slash@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + resolved "http://10.121.8.15:9813/repository/npm-group/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -string-width@^4.1.0, string-width@^4.2.0: +slice-ansi@^2.1.0: + version "2.1.0" + resolved "http://10.121.8.15:9813/repository/npm-group/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== + dependencies: + ansi-styles "^3.2.0" + astral-regex "^1.0.0" + is-fullwidth-code-point "^2.0.0" + +source-map@^0.7.3: + version "0.7.3" + resolved "http://10.121.8.15:9813/repository/npm-group/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +source-map@~0.6.1: + version "0.6.1" + resolved "http://10.121.8.15:9813/repository/npm-group/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "http://10.121.8.15:9813/repository/npm-group/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + +sshpk@^1.7.0: + version "1.17.0" + resolved "http://10.121.8.15:9813/repository/npm-group/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" + integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +streamifier@^0.1.1: + version "0.1.1" + resolved "http://10.121.8.15:9813/repository/npm-group/streamifier/-/streamifier-0.1.1.tgz#97e98d8fa4d105d62a2691d1dc07e820db8dfc4f" + integrity sha1-l+mNj6TRBdYqJpHR3AfoINuN/E8= + +"string-width@^1.0.2 || 2": + version "2.1.1" + resolved "http://10.121.8.15:9813/repository/npm-group/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.0, string-width@^3.1.0: + version "3.1.0" + resolved "http://10.121.8.15:9813/repository/npm-group/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string-width@^4.1.0: version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + resolved "http://10.121.8.15:9813/repository/npm-group/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string.prototype.trimend@^1.0.4: + version "1.0.4" + resolved "http://10.121.8.15:9813/repository/npm-group/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +string.prototype.trimstart@^1.0.4: + version "1.0.4" + resolved "http://10.121.8.15:9813/repository/npm-group/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + string_decoder@~1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + resolved "http://10.121.8.15:9813/repository/npm-group/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== dependencies: safe-buffer "~5.1.0" +strip-ansi@^4.0.0: + version "4.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow== + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "http://10.121.8.15:9813/repository/npm-group/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + resolved "http://10.121.8.15:9813/repository/npm-group/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" -strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: +strip-json-comments@2.0.1: + version "2.0.1" + resolved "http://10.121.8.15:9813/repository/npm-group/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== + +strip-json-comments@^3.0.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + resolved "http://10.121.8.15:9813/repository/npm-group/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -supports-color@8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== +supports-color@6.0.0: + version "6.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/supports-color/-/supports-color-6.0.0.tgz#76cfe742cf1f41bb9b1c29ad03068c05b4c0e40a" + integrity sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg== dependencies: - has-flag "^4.0.0" + has-flag "^3.0.0" + +supports-color@^5.3.0: + version "5.5.0" + resolved "http://10.121.8.15:9813/repository/npm-group/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" supports-color@^7.1.0: version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + resolved "http://10.121.8.15:9813/repository/npm-group/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== dependencies: has-flag "^4.0.0" +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +table@^5.2.3: + version "5.4.6" + resolved "http://10.121.8.15:9813/repository/npm-group/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" + integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== + dependencies: + ajv "^6.10.2" + lodash "^4.17.14" + slice-ansi "^2.1.0" + string-width "^3.0.0" + +tar-stream@^1.5.2: + version "1.6.2" + resolved "http://10.121.8.15:9813/repository/npm-group/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" + integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== + dependencies: + bl "^1.0.0" + buffer-alloc "^1.2.0" + end-of-stream "^1.0.0" + fs-constants "^1.0.0" + readable-stream "^2.3.0" + to-buffer "^1.1.1" + xtend "^4.0.0" + text-table@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + resolved "http://10.121.8.15:9813/repository/npm-group/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== +through@^2.3.6: + version "2.3.8" + resolved "http://10.121.8.15:9813/repository/npm-group/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== + +tmp@^0.0.33: + version "0.0.33" + resolved "http://10.121.8.15:9813/repository/npm-group/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +to-buffer@^1.1.1: + version "1.1.1" + resolved "http://10.121.8.15:9813/repository/npm-group/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" + integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + to-regex-range@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + resolved "http://10.121.8.15:9813/repository/npm-group/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== dependencies: is-number "^7.0.0" +tough-cookie@~2.5.0: + version "2.5.0" + resolved "http://10.121.8.15:9813/repository/npm-group/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + "traverse@>=0.3.0 <0.4": version "0.3.9" - resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9" + resolved "http://10.121.8.15:9813/repository/npm-group/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9" integrity sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ== -tslib@^1.8.1: +tslib@^1.8.1, tslib@^1.9.0: version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + resolved "http://10.121.8.15:9813/repository/npm-group/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== +tslib@^2.0.1, tslib@^2.2.0: + version "2.4.0" + resolved "http://10.121.8.15:9813/repository/npm-group/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== + tsutils@^3.21.0: version "3.21.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + resolved "http://10.121.8.15:9813/repository/npm-group/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== dependencies: tslib "^1.8.1" -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "http://10.121.8.15:9813/repository/npm-group/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "http://10.121.8.15:9813/repository/npm-group/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== + +type-check@~0.3.2: + version "0.3.2" + resolved "http://10.121.8.15:9813/repository/npm-group/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== dependencies: - prelude-ls "^1.2.1" + prelude-ls "~1.1.2" -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== +type-fest@^0.21.3: + version "0.21.3" + resolved "http://10.121.8.15:9813/repository/npm-group/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -typescript@^4.7.4: +type-fest@^0.8.1: + version "0.8.1" + resolved "http://10.121.8.15:9813/repository/npm-group/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + +typescript@^4.3.2: version "4.7.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235" + resolved "http://10.121.8.15:9813/repository/npm-group/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235" integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ== +uc.micro@^1.0.1, uc.micro@^1.0.5: + version "1.0.6" + resolved "http://10.121.8.15:9813/repository/npm-group/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" + integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== + +unbox-primitive@^1.0.1: + version "1.0.1" + resolved "http://10.121.8.15:9813/repository/npm-group/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" + integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== + dependencies: + function-bind "^1.1.1" + has-bigints "^1.0.1" + has-symbols "^1.0.2" + which-boxed-primitive "^1.0.2" + +universalify@^2.0.0: + version "2.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + unzipper@^0.10.11: version "0.10.11" - resolved "https://registry.yarnpkg.com/unzipper/-/unzipper-0.10.11.tgz#0b4991446472cbdb92ee7403909f26c2419c782e" + resolved "http://10.121.8.15:9813/repository/npm-group/unzipper/-/unzipper-0.10.11.tgz#0b4991446472cbdb92ee7403909f26c2419c782e" integrity sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw== dependencies: big-integer "^1.6.17" @@ -1309,98 +3016,170 @@ unzipper@^0.10.11: readable-stream "~2.3.6" setimmediate "~1.0.4" +update-browserslist-db@^1.0.4: + version "1.0.4" + resolved "http://10.121.8.15:9813/repository/npm-group/update-browserslist-db/-/update-browserslist-db-1.0.4.tgz#dbfc5a789caa26b1db8990796c2c8ebbce304824" + integrity sha512-jnmO2BEGUjsMOe/Fg9u0oczOe/ppIDZPebzccl1yDWGLFP16Pa1/RM5wEoKYPG2zstNcDuAStejyxsOuKINdGA== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + uri-js@^4.2.2: version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + resolved "http://10.121.8.15:9813/repository/npm-group/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" util-deprecate@~1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + resolved "http://10.121.8.15:9813/repository/npm-group/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== +uuid@^3.3.2: + version "3.4.0" + resolved "http://10.121.8.15:9813/repository/npm-group/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + v8-compile-cache@^2.0.3: version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + resolved "http://10.121.8.15:9813/repository/npm-group/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== -which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== +verror@1.10.0: + version "1.10.0" + resolved "http://10.121.8.15:9813/repository/npm-group/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vscode-test@^1.3.0: + version "1.6.1" + resolved "http://10.121.8.15:9813/repository/npm-group/vscode-test/-/vscode-test-1.6.1.tgz#44254c67036de92b00fdd72f6ace5f1854e1a563" + integrity sha512-086q88T2ca1k95mUzffvbzb7esqQNvJgiwY4h29ukPhFo8u+vXOOmelUoU5EQUHs3Of8+JuQ3oGdbVCqaxuTXA== + dependencies: + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + rimraf "^3.0.2" + unzipper "^0.10.11" + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "http://10.121.8.15:9813/repository/npm-group/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +which-module@^2.0.0: + version "2.0.0" + resolved "http://10.121.8.15:9813/repository/npm-group/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q== + +which@1.3.1, which@^1.2.9: + version "1.3.1" + resolved "http://10.121.8.15:9813/repository/npm-group/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" -word-wrap@^1.2.3: +wide-align@1.1.3: + version "1.1.3" + resolved "http://10.121.8.15:9813/repository/npm-group/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +word-wrap@~1.2.3: version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + resolved "http://10.121.8.15:9813/repository/npm-group/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== -workerpool@6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" - integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "http://10.121.8.15:9813/repository/npm-group/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" wrappy@1: version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + resolved "http://10.121.8.15:9813/repository/npm-group/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== +write@1.0.3: + version "1.0.3" + resolved "http://10.121.8.15:9813/repository/npm-group/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== + dependencies: + mkdirp "^0.5.1" + +xtend@^4.0.0: + version "4.0.2" + resolved "http://10.121.8.15:9813/repository/npm-group/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +y18n@^4.0.0: + version "4.0.3" + resolved "http://10.121.8.15:9813/repository/npm-group/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== yallist@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + resolved "http://10.121.8.15:9813/repository/npm-group/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== +yargs-parser@13.1.2, yargs-parser@^13.1.2: + version "13.1.2" + resolved "http://10.121.8.15:9813/repository/npm-group/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" + integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" -yargs-unparser@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" - integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== +yargs-unparser@1.6.0: + version "1.6.0" + resolved "http://10.121.8.15:9813/repository/npm-group/yargs-unparser/-/yargs-unparser-1.6.0.tgz#ef25c2c769ff6bd09e4b0f9d7c605fb27846ea9f" + integrity sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw== dependencies: - camelcase "^6.0.0" - decamelize "^4.0.0" - flat "^5.0.2" - is-plain-obj "^2.1.0" + flat "^4.1.0" + lodash "^4.17.15" + yargs "^13.3.0" -yargs@16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== +yargs@13.3.2, yargs@^13.3.0: + version "13.3.2" + resolved "http://10.121.8.15:9813/repository/npm-group/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" + integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.2" + +yauzl@^2.7.0: + version "2.10.0" + resolved "http://10.121.8.15:9813/repository/npm-group/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g== + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" + +yazl@^2.4.2: + version "2.5.1" + resolved "http://10.121.8.15:9813/repository/npm-group/yazl/-/yazl-2.5.1.tgz#a3d65d3dd659a5b0937850e8609f22fffa2b5c35" + integrity sha1-o9ZdPdZZpbCTeFDoYJ8i//orXDU= + dependencies: + buffer-crc32 "~0.2.3"