diff --git a/frontend/angular.json b/frontend/angular.json index 0d1e5d759..30cee872d 100644 --- a/frontend/angular.json +++ b/frontend/angular.json @@ -389,10 +389,10 @@ }, "configurations": { "production": { - "tsConfig": "projects/shared/tsconfig.lib.prod.json" + "tsConfig": "projects/shared/tsconfig.prod.json" }, "development": { - "tsConfig": "projects/shared/tsconfig.lib.json" + "tsConfig": "projects/shared/tsconfig.json" } }, "defaultConfiguration": "production" diff --git a/frontend/package-lock.json b/frontend/package-lock.json index cd59af1e3..b5eab0fc2 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -95,16 +95,31 @@ "node": ">=6.0.0" } }, + "node_modules/@angular-devkit/architect": { + "version": "0.1302.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1302.3.tgz", + "integrity": "sha512-0m8jMKrFfIqsYt33zTUwSmyekyfuS67hna08RQ6USjzWQSE3z4S8ulCUARSjM6AzdMblX+whfy56nJUpT17NSA==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "13.2.3", + "rxjs": "6.6.7" + }, + "engines": { + "node": "^12.20.0 || ^14.15.0 || >=16.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, "node_modules/@angular-devkit/build-angular": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-13.2.0.tgz", - "integrity": "sha512-cHnm/P7uKJjKh2BCN8gnnd240J5z3IesQyRAx88kFSlL5sKCGyGoAYKAjU585/lllIXjtFXSR/S2d/cHg8ShKw==", + "version": "13.2.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-13.2.3.tgz", + "integrity": "sha512-cZ2gRcMRgW3t1WCeP+2D/wmr2M+BR/RICAh0wL9irIdypWAzIFt3Z2+2R/HmgAAxoEkdUMIfB9AnkYmwRVgFeA==", "dev": true, "dependencies": { "@ampproject/remapping": "1.1.1", - "@angular-devkit/architect": "0.1302.0", - "@angular-devkit/build-webpack": "0.1302.0", - "@angular-devkit/core": "13.2.0", + "@angular-devkit/architect": "0.1302.3", + "@angular-devkit/build-webpack": "0.1302.3", + "@angular-devkit/core": "13.2.3", "@babel/core": "7.16.12", "@babel/generator": "7.16.8", "@babel/helper-annotate-as-pure": "7.16.7", @@ -115,7 +130,7 @@ "@babel/runtime": "7.16.7", "@babel/template": "7.16.7", "@discoveryjs/json-ext": "0.5.6", - "@ngtools/webpack": "13.2.0", + "@ngtools/webpack": "13.2.3", "ansi-colors": "4.1.1", "babel-loader": "8.2.3", "babel-plugin-istanbul": "6.1.1", @@ -134,7 +149,7 @@ "karma-source-map-support": "1.4.0", "less": "4.1.2", "less-loader": "10.2.0", - "license-webpack-plugin": "4.0.0", + "license-webpack-plugin": "4.0.1", "loader-utils": "3.2.0", "mini-css-extract-plugin": "2.5.3", "minimatch": "3.0.4", @@ -205,94 +220,95 @@ } } }, - "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/architect": { - "version": "0.1302.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1302.0.tgz", - "integrity": "sha512-1CmVYvxyfvK/khTcDJwwXibm/z4upM2j5SDpwuIdaLx21E4oQPmHn+U/quT/jE5VI1zfZi2vfvIaSXn9XQzMiQ==", - "dev": true, - "dependencies": { - "@angular-devkit/core": "13.2.0", - "rxjs": "6.6.7" - }, - "engines": { - "node": "^12.20.0 || ^14.15.0 || >=16.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/core": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.2.0.tgz", - "integrity": "sha512-5+aV2W2QUazySMKusBuT2pi2qsXWpTHJG2x62mKGAy0lxzwG8l3if+WP3Uh85SQS+zqlHeKxEbmm9zNn8ZrzFg==", - "dev": true, - "dependencies": { - "ajv": "8.9.0", - "ajv-formats": "2.1.1", - "fast-json-stable-stringify": "2.1.0", - "magic-string": "0.25.7", - "rxjs": "6.6.7", - "source-map": "0.7.3" - }, - "engines": { - "node": "^12.20.0 || ^14.15.0 || >=16.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/ajv": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", - "integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "node_modules/@angular-devkit/build-angular/node_modules/@types/estree": { + "version": "0.0.50", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", + "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", "dev": true }, - "node_modules/@angular-devkit/build-webpack": { - "version": "0.1302.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1302.0.tgz", - "integrity": "sha512-x5BLdobF7c7j4W8frJuKM73ZYvPygjPN8vq1iKhsEraClqJG8cLiDwLEEFcrzIfmCHTX1o1o75sWC0FNln2LfQ==", + "node_modules/@angular-devkit/build-angular/node_modules/core-js": { + "version": "3.20.3", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.20.3.tgz", + "integrity": "sha512-vVl8j8ph6tRS3B8qir40H7yw7voy17xL0piAjlbBUsH7WIfzoedL/ZOr1OV9FyZQLWXsayOJyV4tnRyXR85/ag==", + "dev": true, + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/schema-utils": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", "dev": true, "dependencies": { - "@angular-devkit/architect": "0.1302.0", + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/webpack": { + "version": "5.67.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.67.0.tgz", + "integrity": "sha512-LjFbfMh89xBDpUMgA1W9Ur6Rn/gnr2Cq1jjHFPo4v6a79/ypznSYbAyPgGhwsxBtMIaEmDD1oJoA7BEYw/Fbrw==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.0", + "@types/estree": "^0.0.50", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.4.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.8.3", + "es-module-lexer": "^0.9.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.3.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-webpack": { + "version": "0.1302.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1302.3.tgz", + "integrity": "sha512-+JYH1lWU0UOjaWYxpoR2VLsdcb6nG9Gv+M1gH+kT0r2sAKOFaHnrksbOvca3EhDoaMa2b9LSGEE0OcSHWnN+eQ==", + "dev": true, + "dependencies": { + "@angular-devkit/architect": "0.1302.3", "rxjs": "6.6.7" }, "engines": { @@ -305,25 +321,10 @@ "webpack-dev-server": "^4.0.0" } }, - "node_modules/@angular-devkit/build-webpack/node_modules/@angular-devkit/architect": { - "version": "0.1302.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1302.0.tgz", - "integrity": "sha512-1CmVYvxyfvK/khTcDJwwXibm/z4upM2j5SDpwuIdaLx21E4oQPmHn+U/quT/jE5VI1zfZi2vfvIaSXn9XQzMiQ==", - "dev": true, - "dependencies": { - "@angular-devkit/core": "13.2.0", - "rxjs": "6.6.7" - }, - "engines": { - "node": "^12.20.0 || ^14.15.0 || >=16.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular-devkit/build-webpack/node_modules/@angular-devkit/core": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.2.0.tgz", - "integrity": "sha512-5+aV2W2QUazySMKusBuT2pi2qsXWpTHJG2x62mKGAy0lxzwG8l3if+WP3Uh85SQS+zqlHeKxEbmm9zNn8ZrzFg==", + "node_modules/@angular-devkit/core": { + "version": "13.2.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.2.3.tgz", + "integrity": "sha512-/47RA8qmWzeS60xSdaprIn1MiSv0Iw83t0M9/ENH7irFS5vMAq62NCcwiWXH59pZmvvLbF+7xy/RgYUZLr4nHQ==", "dev": true, "dependencies": { "ajv": "8.9.0", @@ -347,7 +348,7 @@ } } }, - "node_modules/@angular-devkit/build-webpack/node_modules/ajv": { + "node_modules/@angular-devkit/core/node_modules/ajv": { "version": "8.9.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", "integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==", @@ -363,33 +364,34 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@angular-devkit/build-webpack/node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/@angular-devkit/build-webpack/node_modules/json-schema-traverse": { + "node_modules/@angular-devkit/core/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, + "node_modules/@angular-devkit/schematics": { + "version": "13.2.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-13.2.3.tgz", + "integrity": "sha512-+dyC4iKV0huvpjiuz4uyjLNK3FsCIp/Ghv5lXvhG6yok/dCAubsJItJOxi6G16aVCzG/E9zbsDfm9fNMyVOkgQ==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "13.2.3", + "jsonc-parser": "3.0.0", + "magic-string": "0.25.7", + "ora": "5.4.1", + "rxjs": "6.6.7" + }, + "engines": { + "node": "^12.20.0 || ^14.15.0 || >=16.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, "node_modules/@angular/animations": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-13.2.0.tgz", - "integrity": "sha512-zLmNxkfxDQShJ97V9gTyQdlEbCD/zDUdpHXKlUViBIbe2M13FLGV3e2D+x9jGr/PRzFe0cukOnYxNEHJqqjqPA==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-13.2.2.tgz", + "integrity": "sha512-qX8LAMuCJaueHBVyuwKtqunx96G0Dr26k7y5Z03VTcscYst4Ib4V2d4i5dwn3HS82DehFdO86cm3Hi2PqE/qww==", "dependencies": { "tslib": "^2.3.0" }, @@ -397,20 +399,20 @@ "node": "^12.20.0 || ^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/core": "13.2.0" + "@angular/core": "13.2.2" } }, "node_modules/@angular/cli": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-13.2.0.tgz", - "integrity": "sha512-xrtClCucVSBwELG6zgaHrjC71p1rZOkwjF/HewnOFNjyjXSbWIO2y5d/6O2wxmNASoeStpiEU0zPpwDGhXiYpQ==", + "version": "13.2.3", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-13.2.3.tgz", + "integrity": "sha512-QsakxpdQuO67u4fQNuOASqabYUO9gJb/5CpUGpWbuBzru0/9CMEF1CtXoF4EoDiwa5sJMirz3SJMKhtzFlv1cQ==", "dev": true, "hasInstallScript": true, "dependencies": { - "@angular-devkit/architect": "0.1302.0", - "@angular-devkit/core": "13.2.0", - "@angular-devkit/schematics": "13.2.0", - "@schematics/angular": "13.2.0", + "@angular-devkit/architect": "0.1302.3", + "@angular-devkit/core": "13.2.3", + "@angular-devkit/schematics": "13.2.3", + "@schematics/angular": "13.2.3", "@yarnpkg/lockfile": "1.1.0", "ansi-colors": "4.1.1", "debug": "4.3.3", @@ -436,109 +438,10 @@ "yarn": ">= 1.13.0" } }, - "node_modules/@angular/cli/node_modules/@angular-devkit/architect": { - "version": "0.1302.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1302.0.tgz", - "integrity": "sha512-1CmVYvxyfvK/khTcDJwwXibm/z4upM2j5SDpwuIdaLx21E4oQPmHn+U/quT/jE5VI1zfZi2vfvIaSXn9XQzMiQ==", - "dev": true, - "dependencies": { - "@angular-devkit/core": "13.2.0", - "rxjs": "6.6.7" - }, - "engines": { - "node": "^12.20.0 || ^14.15.0 || >=16.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular/cli/node_modules/@angular-devkit/core": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.2.0.tgz", - "integrity": "sha512-5+aV2W2QUazySMKusBuT2pi2qsXWpTHJG2x62mKGAy0lxzwG8l3if+WP3Uh85SQS+zqlHeKxEbmm9zNn8ZrzFg==", - "dev": true, - "dependencies": { - "ajv": "8.9.0", - "ajv-formats": "2.1.1", - "fast-json-stable-stringify": "2.1.0", - "magic-string": "0.25.7", - "rxjs": "6.6.7", - "source-map": "0.7.3" - }, - "engines": { - "node": "^12.20.0 || ^14.15.0 || >=16.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@angular/cli/node_modules/@angular-devkit/schematics": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-13.2.0.tgz", - "integrity": "sha512-EwoqDqLJH5YpWiLuQJwonnJu2bi4xQlyKXyUTuXsQ4gIsAPrg+ijyAe+F/brAtDLBj0sU7JHoC0U1yx2pZ7f1A==", - "dev": true, - "dependencies": { - "@angular-devkit/core": "13.2.0", - "jsonc-parser": "3.0.0", - "magic-string": "0.25.7", - "ora": "5.4.1", - "rxjs": "6.6.7" - }, - "engines": { - "node": "^12.20.0 || ^14.15.0 || >=16.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular/cli/node_modules/ajv": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", - "integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@angular/cli/node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/@angular/cli/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, "node_modules/@angular/common": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-13.2.0.tgz", - "integrity": "sha512-zyq3kscl5BoY+xxl4YOfbKP72xwzx/vKLE+2ougjPu2spm5KIllIAo/VrxVqIBrsGWT/4gs9pvIOqOdOfufxUA==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-13.2.2.tgz", + "integrity": "sha512-56C/bheNLKtTCyQUZCiYtKbBIZN9jj6rjFILPtJCGls3cBCxp7t9tIdoLiQG/wVQRmaxdj1ioLT+sCWz7mLtQw==", "dependencies": { "tslib": "^2.3.0" }, @@ -546,14 +449,14 @@ "node": "^12.20.0 || ^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/core": "13.2.0", + "@angular/core": "13.2.2", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/compiler": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-13.2.0.tgz", - "integrity": "sha512-TTA+Mn31vAwI4qiaH0h8DqNV3DWgZF+Q9G8Qqbw17k8Jf+B5CdLkMYBF8wbGegIdsEfo+6DebCp71W+aJxuSlw==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-13.2.2.tgz", + "integrity": "sha512-XXQtB0/e7pR2LPrHmpEiTU72SX4xxHGy91vYWIj1JCjSn0fYF7vtHzSJPXDvkbnkNow/PXXzJJYaU1ctdMZPcA==", "dependencies": { "tslib": "^2.3.0" }, @@ -562,13 +465,12 @@ } }, "node_modules/@angular/compiler-cli": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-13.2.0.tgz", - "integrity": "sha512-IDX0X3GXjhUzd/cFyNZBG3eVqh6Y2W7MYvH9tXbZHcJ6vH9RkN2+zh/XQautVWy4EP33oQoDlsydfYKqbHr9TA==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-13.2.2.tgz", + "integrity": "sha512-tuOIcEEKVIht+mKrj0rtX3I8gc+ByPjzpCZhFQRggxM6xbKJIToO1zERbEGKrZ+sUJ6BB5KLvscDy+Pddy3b8w==", "dev": true, "dependencies": { "@babel/core": "^7.8.6", - "canonical-path": "1.0.0", "chokidar": "^3.0.0", "convert-source-map": "^1.5.1", "dependency-graph": "^0.11.0", @@ -588,14 +490,14 @@ "node": "^12.20.0 || ^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/compiler": "13.2.0", + "@angular/compiler": "13.2.2", "typescript": ">=4.4.2 <4.6" } }, "node_modules/@angular/core": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-13.2.0.tgz", - "integrity": "sha512-mWRWbbZ6k00AicA/GrxmWKaw8upo77sRQz4tSYKpwVKt2TtCeoW8OkdYUpnmuVjxpF0bD6PtVc0e1fD6es/ElA==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-13.2.2.tgz", + "integrity": "sha512-zpctw0BxIVOsRFnckchK15SD1L8tzhf5GzwIDaM6+VylDQj1uYkm8mvAjJTQZyUuApomoFet2Rfj7XQPV+cNSQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -608,9 +510,9 @@ } }, "node_modules/@angular/forms": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-13.2.0.tgz", - "integrity": "sha512-aduXLuvqynDRRdb316yY1O5rdMQ2DKeNxu5P2FG1nkLQ3hqZvpiaUMhFyXvKDG3s0rV5e/PZs1cpg0Aqdfwevw==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-13.2.2.tgz", + "integrity": "sha512-T61W4Ay9X9qhxjc6lLqpNFeHrGKwg2mqdsZ3zIm/c7oKo37mgl9TB5kkrtnS+205r3N2hF4ICnGFZ4a/egUP/g==", "dependencies": { "tslib": "^2.3.0" }, @@ -618,25 +520,25 @@ "node": "^12.20.0 || ^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/common": "13.2.0", - "@angular/core": "13.2.0", - "@angular/platform-browser": "13.2.0", + "@angular/common": "13.2.2", + "@angular/core": "13.2.2", + "@angular/platform-browser": "13.2.2", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/language-service": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-13.2.0.tgz", - "integrity": "sha512-nK40YXy9f2MsrejvTiKMrS7YHNvBxp3QIBU8aJN36LpkTTWC8aVqZ5A3to8JL0U6Anra8mkcC070xoYfh6miwg==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-13.2.2.tgz", + "integrity": "sha512-2P5+wRsbHgpI2rVeFwnsLWxyntUiw8kG9Tqh5BkVDqtQovbYtzFiaMkf5TFz/g938JBBgeRQzvXr1kQhEidAWQ==", "dev": true, "engines": { "node": "^12.20.0 || ^14.15.0 || >=16.10.0" } }, "node_modules/@angular/platform-browser": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-13.2.0.tgz", - "integrity": "sha512-FB9eKdRqpjopTFbea5JXnqSPFR7DZD4nepOSGnYttV9cVj4pABqx2A6FJCnyvPPUSTamODye/pNkGmzP2P1gcw==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-13.2.2.tgz", + "integrity": "sha512-M7gWC8fFCPc/CRcHCzqe/j7WzwAUMeKt9vwlK633XnesHBoqZdYgbb3YHHc6WPVU0YI09Nb/Hm5sezEKmjUmPg==", "dependencies": { "tslib": "^2.3.0" }, @@ -644,9 +546,9 @@ "node": "^12.20.0 || ^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/animations": "13.2.0", - "@angular/common": "13.2.0", - "@angular/core": "13.2.0" + "@angular/animations": "13.2.2", + "@angular/common": "13.2.2", + "@angular/core": "13.2.2" }, "peerDependenciesMeta": { "@angular/animations": { @@ -655,9 +557,9 @@ } }, "node_modules/@angular/platform-browser-dynamic": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-13.2.0.tgz", - "integrity": "sha512-VPL0uF/KWk+jBfkZwt60K6YbTFOvQzZbhwE4LttjjejstdvR0IMD3PtVDrdgIUWNfjikcCVN5Ds0GB6zZUb04Q==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-13.2.2.tgz", + "integrity": "sha512-lj6xwat0StLp+ROFqXU62upwHQhlxaQi0djhrS+DGKUK0Xu9bkBeaSCfBFgS78jPm1SwL8Xztu9/vuDAHLRrqw==", "dependencies": { "tslib": "^2.3.0" }, @@ -665,16 +567,16 @@ "node": "^12.20.0 || ^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/common": "13.2.0", - "@angular/compiler": "13.2.0", - "@angular/core": "13.2.0", - "@angular/platform-browser": "13.2.0" + "@angular/common": "13.2.2", + "@angular/compiler": "13.2.2", + "@angular/core": "13.2.2", + "@angular/platform-browser": "13.2.2" } }, "node_modules/@angular/router": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-13.2.0.tgz", - "integrity": "sha512-8fWxcWT/LpaGhmXJ8xH+E7UObzt5IMGzK1sJGRu508y5tcbuBlTJt3yV97mCeUQ0g/E+2GEv6vuxY7OcfDaZow==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-13.2.2.tgz", + "integrity": "sha512-dt2b9/kGJAkmOqUmUD3aKlp4pGpdqLwB0zmhUYF3ktNEcQaPf4ZjWT/4jhy09gFL+TKOHG5OQW9GxBbhWI4bSg==", "dependencies": { "tslib": "^2.3.0" }, @@ -682,9 +584,9 @@ "node": "^12.20.0 || ^14.15.0 || >=16.10.0" }, "peerDependencies": { - "@angular/common": "13.2.0", - "@angular/core": "13.2.0", - "@angular/platform-browser": "13.2.0", + "@angular/common": "13.2.2", + "@angular/core": "13.2.2", + "@angular/platform-browser": "13.2.2", "rxjs": "^6.5.3 || ^7.4.0" } }, @@ -707,9 +609,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.8.tgz", - "integrity": "sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.0.tgz", + "integrity": "sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==", "dev": true, "engines": { "node": ">=6.9.0" @@ -839,9 +741,9 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.16.10", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.10.tgz", - "integrity": "sha512-wDeej0pu3WN/ffTxMNCPW5UCiOav8IcLRxSIyp/9+IF2xJUM9h/OYjg0IJLHaL6F8oU8kqMz9nc1vryXhMsgXg==", + "version": "7.17.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.1.tgz", + "integrity": "sha512-JBdSr/LtyYIno/pNnJ75lBcqc3Z1XXujzPanHqjvvrhOA+DTceTFuJi8XjmWTZh4r3fsdfqaCMN0iZemdkxZHQ==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.16.7", @@ -860,13 +762,13 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.7.tgz", - "integrity": "sha512-fk5A6ymfp+O5+p2yCkXAu5Kyj6v0xh0RBeNcAkYUMDvvAAoxvSKXn+Jb37t/yWFiQVDFK1ELpUTD8/aLhCPu+g==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.0.tgz", + "integrity": "sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.16.7", - "regexpu-core": "^4.7.1" + "regexpu-core": "^5.0.1" }, "engines": { "node": ">=6.9.0" @@ -1129,14 +1031,14 @@ } }, "node_modules/@babel/helpers": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.7.tgz", - "integrity": "sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw==", + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz", + "integrity": "sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==", "dev": true, "dependencies": { "@babel/template": "^7.16.7", - "@babel/traverse": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/traverse": "^7.17.0", + "@babel/types": "^7.17.0" }, "engines": { "node": ">=6.9.0" @@ -1157,9 +1059,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.16.12", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.12.tgz", - "integrity": "sha512-VfaV15po8RiZssrkPweyvbGVSe4x2y+aciFCgn0n0/SJMR22cwofRV1mtnJQYcSB1wUTaA/X1LnA3es66MCO5A==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.0.tgz", + "integrity": "sha512-VKXSCQx5D8S04ej+Dqsr1CzYvvWgf20jIw2D+YhQCrIlr2UZGaDds23Y0xg75/skOxpLCRpUZvk/1EAVkGoDOw==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -2300,19 +2202,19 @@ } }, "node_modules/@babel/traverse": { - "version": "7.16.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.10.tgz", - "integrity": "sha512-yzuaYXoRJBGMlBhsMJoUW7G1UmSb/eXr/JHYM/MsOJgavJibLwASijW7oXBdw3NQ6T0bW7Ty5P/VarOs9cHmqw==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.0.tgz", + "integrity": "sha512-fpFIXvqD6kC7c7PUNnZ0Z8cQXlarCLtCUpt2S1Dx7PjoRtCFffvOkHHSom+m5HIxMZn5bIBVb71lhabcmjEsqg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.16.8", + "@babel/generator": "^7.17.0", "@babel/helper-environment-visitor": "^7.16.7", "@babel/helper-function-name": "^7.16.7", "@babel/helper-hoist-variables": "^7.16.7", "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.16.10", - "@babel/types": "^7.16.8", + "@babel/parser": "^7.17.0", + "@babel/types": "^7.17.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -2320,10 +2222,33 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/traverse/node_modules/@babel/generator": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.0.tgz", + "integrity": "sha512-I3Omiv6FGOC29dtlZhkfXO6pgkmukJSlT26QjVvS1DGZe/NzSVCPG41X0tS21oZkJYlovfj9qDWgKP+Cn4bXxw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.17.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@babel/types": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.8.tgz", - "integrity": "sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.16.7", @@ -2354,6 +2279,21 @@ "node": ">=12" } }, + "node_modules/@csstools/postcss-progressive-custom-properties": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.1.0.tgz", + "integrity": "sha512-DO76V3295AqhjJZvgeaDP5GAGAat4g6wYfF8X+1n+76MpJat8ffY5bCJ9eSUqFY71nImxXgaDTRYJcRnA9oo7g==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "peerDependencies": { + "postcss": "^8.3" + } + }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz", @@ -2370,11 +2310,11 @@ "dev": true }, "node_modules/@ionic/angular": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@ionic/angular/-/angular-6.0.4.tgz", - "integrity": "sha512-+xUJFu4kS1cCFNoraIonHv/6Sr3kFX8odowA1c+EcElCKZ6rTD+ZQyawKnOFebyF9WIGeVDD4j2Bw7VujBV0ag==", + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/@ionic/angular/-/angular-6.0.7.tgz", + "integrity": "sha512-/nNuwkt+oqQ44jokT+YKuHqsknGnhkmXn9hcd+RuDVW/Q8mZXK4YQZs8e5Rxs6T2ttkyjUHZg77lF6eS/W76hQ==", "dependencies": { - "@ionic/core": "^6.0.4", + "@ionic/core": "^6.0.7", "jsonc-parser": "^3.0.0", "tslib": "^2.0.0" }, @@ -2732,11 +2672,11 @@ } }, "node_modules/@ionic/core": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.0.4.tgz", - "integrity": "sha512-s/hJidmB3qtuBE/IY6cfPYJb8U7pWP2c1oUfyZGp9dyqLy9F4fYOKBog6Pzgfs0U50CArCGJfHSp6ufPFA0G2w==", + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.0.7.tgz", + "integrity": "sha512-Yl6itMcddfwfNNa6BjCxXxrIS+vPsrYSTfCmQwVfB4AiuZ5ZgE/jaZ9lMN7b0WIAy56bfX9etRlW+EjnK1znyQ==", "dependencies": { - "@stencil/core": "~2.12.0", + "@stencil/core": "~2.13.0", "ionicons": "^6.0.0", "tslib": "^2.1.0" } @@ -2936,12 +2876,12 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.3.tgz", - "integrity": "sha512-fuIOnc81C5iRNevb/XPiM8Khp9bVjreydRQ37rt0C/dY0PAW1DRvEM3WrKX/5rStS5lbgwS0FCgqSndh9tvK5w==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", + "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", "dev": true, "engines": { - "node": ">=10.0.0" + "node": ">=6.0.0" } }, "node_modules/@materia-ui/ngx-monaco-editor": { @@ -2957,9 +2897,9 @@ } }, "node_modules/@ngtools/webpack": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-13.2.0.tgz", - "integrity": "sha512-dQKPsEsST/HSBYtC75E0ARI1zVsW65h/NYzcAwtOd8DKFmlj8EZMqKC4KwcJ/EKlwR1PN12nBZhuQ1HUVH8Vtg==", + "version": "13.2.3", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-13.2.3.tgz", + "integrity": "sha512-wooUZiV92QyoeFxkhqIwH/cfiAAAn+l8fEEuaaEIfJtpjpbShvvlboEVsqb28soeGiFJfLcmsZM3mUFgsG4QBQ==", "dev": true, "engines": { "node": "^12.20.0 || ^14.15.0 || >=16.10.0", @@ -3008,16 +2948,13 @@ } }, "node_modules/@npmcli/fs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.0.tgz", - "integrity": "sha512-VhP1qZLXcrXRIaPoqb4YA55JQxLNF3jNR4T55IdOJa3+IFJKNYHtPvtXx8slmeMavj37vCzCfrqQM1vWLsYKLA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", + "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", "dev": true, "dependencies": { "@gar/promisify": "^1.0.1", "semver": "^7.3.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" } }, "node_modules/@npmcli/git": { @@ -3141,20 +3078,14 @@ "rollup": "^1.20.0||^2.0.0" } }, - "node_modules/@rollup/pluginutils/node_modules/@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", - "dev": true - }, "node_modules/@schematics/angular": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-13.2.0.tgz", - "integrity": "sha512-DlUJ+ix9u/wz7IWc82dix5xsDGu0nztZ6Litrv+EsFDRYc95IFxTWuNwwjL2eRkI2KLIk79wmO7xhlUwrUyNlg==", + "version": "13.2.3", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-13.2.3.tgz", + "integrity": "sha512-jloooGC7eco9AKxlIMMqFRptJYzZ0jNRBStWOp2dCISg6rmOKqpxbsHLtYFQIT1PnlomSxtKDAgYGQMDi9zhXw==", "dev": true, "dependencies": { - "@angular-devkit/core": "13.2.0", - "@angular-devkit/schematics": "13.2.0", + "@angular-devkit/core": "13.2.3", + "@angular-devkit/schematics": "13.2.3", "jsonc-parser": "3.0.0" }, "engines": { @@ -3163,90 +3094,6 @@ "yarn": ">= 1.13.0" } }, - "node_modules/@schematics/angular/node_modules/@angular-devkit/core": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.2.0.tgz", - "integrity": "sha512-5+aV2W2QUazySMKusBuT2pi2qsXWpTHJG2x62mKGAy0lxzwG8l3if+WP3Uh85SQS+zqlHeKxEbmm9zNn8ZrzFg==", - "dev": true, - "dependencies": { - "ajv": "8.9.0", - "ajv-formats": "2.1.1", - "fast-json-stable-stringify": "2.1.0", - "magic-string": "0.25.7", - "rxjs": "6.6.7", - "source-map": "0.7.3" - }, - "engines": { - "node": "^12.20.0 || ^14.15.0 || >=16.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@schematics/angular/node_modules/@angular-devkit/schematics": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-13.2.0.tgz", - "integrity": "sha512-EwoqDqLJH5YpWiLuQJwonnJu2bi4xQlyKXyUTuXsQ4gIsAPrg+ijyAe+F/brAtDLBj0sU7JHoC0U1yx2pZ7f1A==", - "dev": true, - "dependencies": { - "@angular-devkit/core": "13.2.0", - "jsonc-parser": "3.0.0", - "magic-string": "0.25.7", - "ora": "5.4.1", - "rxjs": "6.6.7" - }, - "engines": { - "node": "^12.20.0 || ^14.15.0 || >=16.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@schematics/angular/node_modules/ajv": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", - "integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@schematics/angular/node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/@schematics/angular/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, "node_modules/@start9labs/argon2": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/@start9labs/argon2/-/argon2-0.1.0.tgz", @@ -3258,9 +3105,9 @@ "integrity": "sha512-1dhiG03VkfEwSLx/JPKVms6srAbYFQgwfSGhwpUKMDliMXuAHGVaueStmqzVxn3JpH/HEVz0QW8w/PXHqjdiIg==" }, "node_modules/@stencil/core": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.12.1.tgz", - "integrity": "sha512-u24TZ+FEvjnZt5ZgIkLjLpUNsO6Ml3mUZqwmqk81w6RWWz75hgB5p4RFI5rvuErFeh2xvMIGo+pNdG24XUBz1A==", + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.13.0.tgz", + "integrity": "sha512-EEKHOHgYpg3/iFUKMXTZJjUayRul7sXDwNw0OGgkEOe4t7JWiibDkzUHuruvpbqEydX+z1+ez5K2bMMY76c2wA==", "bin": { "stencil": "bin/stencil" }, @@ -3376,9 +3223,9 @@ } }, "node_modules/@types/estree": { - "version": "0.0.50", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", - "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", "dev": true }, "node_modules/@types/express": { @@ -3444,9 +3291,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "16.11.21", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.21.tgz", - "integrity": "sha512-Pf8M1XD9i1ksZEcCP8vuSNwooJ/bZapNmIzpmsMaL+jMI+8mEYU3PKvs+xDNuQcJWF/x24WzY4qxLtB0zNow9A==", + "version": "16.11.25", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.25.tgz", + "integrity": "sha512-NrTwfD7L1RTc2qrHQD4RTTy4p0CO2LatKBEKEds3CaVuhoM/+DJzmWZl5f+ikR8cm8F5mfJxK+9rQq07gRiSjQ==", "dev": true }, "node_modules/@types/parse-json": { @@ -3717,27 +3564,18 @@ "dev": true }, "node_modules/accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, "dependencies": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" }, "engines": { "node": ">= 0.6" } }, - "node_modules/accepts/node_modules/negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/acorn": { "version": "8.7.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", @@ -3854,6 +3692,45 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz", + "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, "node_modules/ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", @@ -3953,16 +3830,16 @@ "dev": true }, "node_modules/are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.0.tgz", + "integrity": "sha512-0GWpv50YSOcLXaN6/FAKY3vfRbllXWV2xvfA/oKJF8pzFhWXPV+yjhJXDBbjscDYowv7Yw1A3uigpzn5iEGTyw==", "dev": true, "dependencies": { "delegates": "^1.0.0", "readable-stream": "^3.6.0" }, "engines": { - "node": ">=10" + "node": "^12.13.0 || ^14.15.0 || >=16" } }, "node_modules/arg": { @@ -4172,13 +4049,13 @@ } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.1.tgz", - "integrity": "sha512-TihqEe4sQcb/QcPJvxe94/9RZuLQuF1+To4WqQcRvc+3J3gLCPIPgDKzGLG6zmQLfH3nn25heRuDNkS2KR4I8A==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz", + "integrity": "sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ==", "dev": true, "dependencies": { "@babel/helper-define-polyfill-provider": "^0.3.1", - "core-js-compat": "^3.20.0" + "core-js-compat": "^3.21.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" @@ -4278,6 +4155,15 @@ "node": ">= 0.8" } }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", + "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/body-parser/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -4305,6 +4191,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/body-parser/node_modules/raw-body": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", + "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", + "dev": true, + "dependencies": { + "bytes": "3.1.1", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/bonjour": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", @@ -4425,9 +4326,9 @@ "dev": true }, "node_modules/bytes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", - "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, "engines": { "node": ">= 0.8" @@ -4493,21 +4394,15 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001303", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001303.tgz", - "integrity": "sha512-/Mqc1oESndUNszJP0kx0UaQU9kEv9nNtJ7Kn8AdA0mNnH8eR1cj0kG+NbNuC1Wq/b21eA8prhKRA3bbkjONegQ==", + "version": "1.0.30001312", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz", + "integrity": "sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==", "dev": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/browserslist" } }, - "node_modules/canonical-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/canonical-path/-/canonical-path-1.0.0.tgz", - "integrity": "sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg==", - "dev": true - }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -4806,6 +4701,12 @@ "color-support": "bin.js" } }, + "node_modules/colorette": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", + "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", + "dev": true + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -5028,9 +4929,9 @@ } }, "node_modules/copy-webpack-plugin/node_modules/ajv": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", - "integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz", + "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", @@ -5043,23 +4944,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/copy-webpack-plugin/node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, "node_modules/copy-webpack-plugin/node_modules/ajv-keywords": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", @@ -5110,9 +4994,9 @@ } }, "node_modules/core-js": { - "version": "3.20.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.20.3.tgz", - "integrity": "sha512-vVl8j8ph6tRS3B8qir40H7yw7voy17xL0piAjlbBUsH7WIfzoedL/ZOr1OV9FyZQLWXsayOJyV4tnRyXR85/ag==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.21.0.tgz", + "integrity": "sha512-YUdI3fFu4TF/2WykQ2xzSiTQdldLB4KVuL9WeAy5XONZYt5Cun/fpQvctoKbCgvPhmzADeesTk/j2Rdx77AcKQ==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -5120,9 +5004,9 @@ } }, "node_modules/core-js-compat": { - "version": "3.20.3", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.20.3.tgz", - "integrity": "sha512-c8M5h0IkNZ+I92QhIpuSijOxGAcj3lgpsWdkCqmUTZNwidujF4r3pi6x1DCN+Vcs5qTS2XWWMfWSuCqyupX8gw==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.21.0.tgz", + "integrity": "sha512-OSXseNPSK2OPJa6GdtkMz/XxeXx8/CJvfhQWTqd6neuUraujcL4jVsjkLQz1OWnax8xVQJnRPe0V2jqNWORA+A==", "dev": true, "dependencies": { "browserslist": "^4.19.1", @@ -5305,12 +5189,12 @@ } }, "node_modules/css-blank-pseudo": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.2.tgz", - "integrity": "sha512-hOb1LFjRR+8ocA071xUSmg5VslJ8NGo/I2qpUpdeAYyBVCgupS5O8SEVo4SxEMYyFBNodBkzG3T1iqW9HCXxew==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz", + "integrity": "sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ==", "dev": true, "dependencies": { - "postcss-selector-parser": "^6.0.8" + "postcss-selector-parser": "^6.0.9" }, "bin": { "css-blank-pseudo": "dist/cli.cjs" @@ -5319,16 +5203,16 @@ "node": "^12 || ^14 || >=16" }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.4" } }, "node_modules/css-has-pseudo": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.3.tgz", - "integrity": "sha512-0gDYWEKaGacwxCqvQ3Ypg6wGdD1AztbMm5h1JsactG2hP2eiflj808QITmuWBpE7sjSEVrAlZhPTVd/nNMj/hQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz", + "integrity": "sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==", "dev": true, "dependencies": { - "postcss-selector-parser": "^6.0.8" + "postcss-selector-parser": "^6.0.9" }, "bin": { "css-has-pseudo": "dist/cli.cjs" @@ -5337,7 +5221,7 @@ "node": "^12 || ^14 || >=16" }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.4" } }, "node_modules/css-loader": { @@ -5367,9 +5251,9 @@ } }, "node_modules/css-prefers-color-scheme": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.2.tgz", - "integrity": "sha512-gv0KQBEM+q/XdoKyznovq3KW7ocO7k+FhPP+hQR1MenJdu0uPGS6IZa9PzlbqBeS6XcZJNAoqoFxlAUW461CrA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", + "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==", "dev": true, "bin": { "css-prefers-color-scheme": "dist/cli.cjs" @@ -5378,7 +5262,7 @@ "node": "^12 || ^14 || >=16" }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.4" } }, "node_modules/css-select": { @@ -5836,9 +5720,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.57", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.57.tgz", - "integrity": "sha512-FNC+P5K1n6pF+M0zIK+gFCoXcJhhzDViL3DRIGy2Fv5PohuSES1JHR7T+GlwxSxlzx4yYbsuzCZvHxcBSRCIOw==", + "version": "1.4.71", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.71.tgz", + "integrity": "sha512-Hk61vXXKRb2cd3znPE9F+2pLWdIOmP7GjiTj45y6L3W/lO+hSnUSUhq+6lEaERWBdZOHbk2s3YV5c9xVl3boVw==", "dev": true }, "node_modules/elementtree": { @@ -5914,9 +5798,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", - "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.0.tgz", + "integrity": "sha512-weDYmzbBygL7HzGGS26M3hGQx68vehdEg6VUmqSOaFzXExFqlnKuSvsEJCVGQHScS8CQMbrAqftT+AzzHNt/YA==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -6720,9 +6604,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.14.7", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz", - "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==", + "version": "1.14.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz", + "integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==", "dev": true, "funding": [ { @@ -6773,9 +6657,9 @@ } }, "node_modules/fraction.js": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.1.2.tgz", - "integrity": "sha512-o2RiJQ6DZaR/5+Si0qJUIy637QMRudSi9kU/FFzx9EZazrIdnBgpU+3sEWCxAVhH2RtxW2Oz+T4p2o8uOPVcgA==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.1.3.tgz", + "integrity": "sha512-pUHWWt6vHzZZiQJcM6S/0PXfS+g6FM4BF5rj9wZyreivhQPdsh5PpE25VtSNxq80wHS5RfY51Ii+8Z0Zl/pmzg==", "dev": true, "engines": { "node": "*" @@ -7327,9 +7211,9 @@ } }, "node_modules/http-proxy-middleware": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.2.tgz", - "integrity": "sha512-XtmDN5w+vdFTBZaYhdJAbMqn0DP/EhkUaAeo963mojwpKMMbw6nivtFKw07D7DDOH745L5k0VL0P8KRYNEVF/g==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.3.tgz", + "integrity": "sha512-1bloEwnrHMnCoO/Gcwbz7eSVvW50KPES01PecpagI+YLNLci4AcuKJrujW4Mc3sBLpFxMSlsLNHS5Nl/lvrTPA==", "dev": true, "dependencies": { "@types/http-proxy": "^1.17.8", @@ -7343,6 +7227,11 @@ }, "peerDependencies": { "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } } }, "node_modules/https-proxy-agent": { @@ -7813,9 +7702,9 @@ } }, "node_modules/inquirer/node_modules/rxjs": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.2.tgz", - "integrity": "sha512-PwDt186XaL3QN5qXj/H9DGyHhP3/RYYgZZwqBv9Tv8rsAaiwFH1IsJJlcgD37J7UW5a6O67qX0KWKS3/pu0m4w==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.4.tgz", + "integrity": "sha512-h5M3Hk78r6wAheJF0a5YahB1yRQKCsZ4MsGdZ5O9ETbVtjPcScGfrMmoOq7EBsCRzd4BDkvDJ7ogP8Sz5tTFiQ==", "dev": true, "dependencies": { "tslib": "^2.1.0" @@ -7841,6 +7730,18 @@ "@stencil/core": "~2.12.0" } }, + "node_modules/ionicons/node_modules/@stencil/core": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.12.1.tgz", + "integrity": "sha512-u24TZ+FEvjnZt5ZgIkLjLpUNsO6Ml3mUZqwmqk81w6RWWz75hgB5p4RFI5rvuErFeh2xvMIGo+pNdG24XUBz1A==", + "bin": { + "stencil": "bin/stencil" + }, + "engines": { + "node": ">=12.10.0", + "npm": ">=6.0.0" + } + }, "node_modules/ip": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", @@ -8153,9 +8054,9 @@ } }, "node_modules/jest-worker": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.6.tgz", - "integrity": "sha512-gHWJF/6Xi5CTG5QCvROr6GcmpIqNYpDJyc8A1h/DyXqH1tD6SnRCM0d3U5msV31D2LB/U+E0M+W4oyvKV44oNw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, "dependencies": { "@types/node": "*", @@ -8434,9 +8335,9 @@ } }, "node_modules/license-webpack-plugin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.0.tgz", - "integrity": "sha512-b9iMrROrw2fTOJBZ57h0xJfT5/1Cxg4ucYbtpWoukv4Awb2TFPfDDFVHNM8w6SYQpVfB13a5tQJxgGamqwrsyw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.1.tgz", + "integrity": "sha512-SQum9mg3BgnY5BK+2KYl4W7pk9b26Q8tW2lTsO6tidD0/Ds9ksdXvp3ip2s9LqDjj5gtBMyWRfOPZptWj4PfCg==", "dev": true, "dependencies": { "webpack-sources": "^3.0.0" @@ -8474,9 +8375,9 @@ "dev": true }, "node_modules/lint-staged": { - "version": "12.3.2", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-12.3.2.tgz", - "integrity": "sha512-gtw4Cbj01SuVSfAOXC6ivd/7VKHTj51yj5xV8TgktFmYNMsZzXuSd5/brqJEA93v63wL7R6iDlunMANOechC0A==", + "version": "12.3.4", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-12.3.4.tgz", + "integrity": "sha512-yv/iK4WwZ7/v0GtVkNb3R82pdL9M+ScpIbJLJNyCXkJ1FGaXvRCOg/SeL59SZtPpqZhE7BD6kPKFLIDUhDx2/w==", "dev": true, "dependencies": { "cli-truncate": "^3.1.0", @@ -8503,12 +8404,6 @@ "url": "https://opencollective.com/lint-staged" } }, - "node_modules/lint-staged/node_modules/colorette": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", - "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", - "dev": true - }, "node_modules/lint-staged/node_modules/supports-color": { "version": "9.2.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.2.1.tgz", @@ -8522,9 +8417,9 @@ } }, "node_modules/listr2": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.1.tgz", - "integrity": "sha512-D65Nl+zyYHL2jQBGmxtH/pU8koPZo5C8iCNE8EoB04RwPgQG1wuaKwVbeZv9LJpiH4Nxs0FCp+nNcG8OqpniiA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.4.tgz", + "integrity": "sha512-vJOm5KD6uZXjSsrwajr+mNacIjf87gWvlBEltPWLbTkslUscWAzquyK4xfe9Zd4RDgO5nnwFyV06FC+uVR+5mg==", "dev": true, "dependencies": { "cli-truncate": "^2.1.0", @@ -8532,7 +8427,7 @@ "log-update": "^4.0.0", "p-map": "^4.0.0", "rfdc": "^1.3.0", - "rxjs": "^7.5.2", + "rxjs": "^7.5.4", "through": "^2.3.8", "wrap-ansi": "^7.0.0" }, @@ -8597,16 +8492,10 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/listr2/node_modules/colorette": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", - "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", - "dev": true - }, "node_modules/listr2/node_modules/rxjs": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.2.tgz", - "integrity": "sha512-PwDt186XaL3QN5qXj/H9DGyHhP3/RYYgZZwqBv9Tv8rsAaiwFH1IsJJlcgD37J7UW5a6O67qX0KWKS3/pu0m4w==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.4.tgz", + "integrity": "sha512-h5M3Hk78r6wAheJF0a5YahB1yRQKCsZ4MsGdZ5O9ETbVtjPcScGfrMmoOq7EBsCRzd4BDkvDJ7ogP8Sz5tTFiQ==", "dev": true, "dependencies": { "tslib": "^2.1.0" @@ -9148,9 +9037,9 @@ } }, "node_modules/mini-css-extract-plugin/node_modules/ajv": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", - "integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz", + "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", @@ -9163,23 +9052,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/mini-css-extract-plugin/node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, "node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", @@ -9354,9 +9226,9 @@ } }, "node_modules/monaco-editor": { - "version": "0.32.0", - "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.32.0.tgz", - "integrity": "sha512-r3xvo6XMA/fg3SuVJb+NMxf+fXHO8GPIOLoPFRO2LIf7GbqfV9W7FdddqT9ze+bCtnLd+s4IScnOGCgDQDg4BQ==" + "version": "0.32.1", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.32.1.tgz", + "integrity": "sha512-LUt2wsUvQmEi2tfTOK+tjAPvt7eQ+K5C4rZPr6SeuyzjAuAHrIvlUloTcOiGjZW3fn3a/jFQCONrEJbNOaCqbA==" }, "node_modules/ms": { "version": "2.1.2", @@ -9398,9 +9270,9 @@ "dev": true }, "node_modules/nanoid": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", - "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.0.tgz", + "integrity": "sha512-JzxqqT5u/x+/KOFSd7JP15DOo9nOoHpx6DYatqIHUW2+flybkm+mdcraotSQR5WcnZr+qhGVh8Ted0KdfSMxlg==", "dev": true, "bin": { "nanoid": "bin/nanoid.cjs" @@ -9469,9 +9341,9 @@ } }, "node_modules/ng-packagr": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/ng-packagr/-/ng-packagr-13.2.0.tgz", - "integrity": "sha512-qfAipG1jQLjQ0+NXUTYyCmi5xSdMYY3LUWc7iXrbPfl8R2b8fLO+abW1zNMxS6TtcBUZMyfYtz2NGcFrh7QteA==", + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/ng-packagr/-/ng-packagr-13.2.1.tgz", + "integrity": "sha512-N0eiTTj5yxOBO7NX8kv+UV08bdLJOBG/ABZkaod9uAwflT6qZG1etX4DHnpfy1I591AZtAJNOnAwdRVoaBIDwQ==", "dev": true, "dependencies": { "@rollup/plugin-json": "^4.1.0", @@ -9515,9 +9387,9 @@ } }, "node_modules/ng-packagr/node_modules/ajv": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", - "integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz", + "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", @@ -9559,9 +9431,9 @@ } }, "node_modules/ng-packagr/node_modules/rxjs": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.2.tgz", - "integrity": "sha512-PwDt186XaL3QN5qXj/H9DGyHhP3/RYYgZZwqBv9Tv8rsAaiwFH1IsJJlcgD37J7UW5a6O67qX0KWKS3/pu0m4w==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.4.tgz", + "integrity": "sha512-h5M3Hk78r6wAheJF0a5YahB1yRQKCsZ4MsGdZ5O9ETbVtjPcScGfrMmoOq7EBsCRzd4BDkvDJ7ogP8Sz5tTFiQ==", "dev": true, "dependencies": { "tslib": "^2.1.0" @@ -9658,9 +9530,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", - "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", + "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", "dev": true }, "node_modules/nopt": { @@ -9768,17 +9640,17 @@ } }, "node_modules/npm-registry-fetch": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-12.0.1.tgz", - "integrity": "sha512-ricy4ezH3Uv0d4am6RSwHjCYTWJI74NJjurIigWMAG7Vs3PFyd0TUlkrez5L0AgaPzDLRsEzqb5cOZ/Ue01bmA==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-12.0.2.tgz", + "integrity": "sha512-Df5QT3RaJnXYuOwtXBXS9BWs+tHH2olvkCLh6jcR/b/u3DvPMlp3J0TvvYwplPKxHMOwfg287PYih9QqaVFoKA==", "dev": true, "dependencies": { - "make-fetch-happen": "^10.0.0", - "minipass": "^3.1.3", - "minipass-fetch": "^1.3.0", + "make-fetch-happen": "^10.0.1", + "minipass": "^3.1.6", + "minipass-fetch": "^1.4.1", "minipass-json-stream": "^1.0.1", - "minizlib": "^2.0.0", - "npm-package-arg": "^8.0.0" + "minizlib": "^2.1.2", + "npm-package-arg": "^8.1.5" }, "engines": { "node": "^12.13.0 || ^14.15.0 || >=16" @@ -9807,28 +9679,37 @@ "node": ">= 6" } }, + "node_modules/npm-registry-fetch/node_modules/lru-cache": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.3.1.tgz", + "integrity": "sha512-nX1x4qUrKqwbIAhv4s9et4FIUVzNOpeY07bsjGUy8gwJrXH/wScImSQqXErmo/b2jZY2r0mohbLA9zVj7u1cNw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/npm-registry-fetch/node_modules/make-fetch-happen": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.0.0.tgz", - "integrity": "sha512-CREcDkbKZZ64g5MN1FT+u58mDHX9FQFFtFyio5HonX44BdQdytqPZBXUz+6ibi2w/6ncji59f2phyXGSMGpgzA==", + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.0.2.tgz", + "integrity": "sha512-JSFLK53NJP22FL/eAGOyKsWbc2G3v+toPMD7Dq9PJKQCvK0i3t8hGkKxe+3YZzwYa+c0kxRHu7uxH3fvO+rsaA==", "dev": true, "dependencies": { - "agentkeepalive": "^4.1.3", - "cacache": "^15.2.0", + "agentkeepalive": "^4.2.0", + "cacache": "^15.3.0", "http-cache-semantics": "^4.1.0", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", "is-lambda": "^1.0.1", - "lru-cache": "^6.0.0", - "minipass": "^3.1.3", + "lru-cache": "^7.3.1", + "minipass": "^3.1.6", "minipass-collect": "^1.0.2", - "minipass-fetch": "^1.3.2", + "minipass-fetch": "^1.4.1", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^0.6.3", "promise-retry": "^2.0.1", - "socks-proxy-agent": "^6.0.0", - "ssri": "^8.0.0" + "socks-proxy-agent": "^6.1.1", + "ssri": "^8.0.1" }, "engines": { "node": "^12.13.0 || ^14.15.0 || >=16" @@ -9847,12 +9728,12 @@ } }, "node_modules/npmlog": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.0.tgz", - "integrity": "sha512-03ppFRGlsyUaQFbGC2C8QWJN/C/K7PsfyD9aQdhVKAQIH4sQBc8WASqFBP7O+Ut4d2oo5LoeoboB3cGdBZSp6Q==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.1.tgz", + "integrity": "sha512-BTHDvY6nrRHuRfyjt1MAufLxYdVXZfd099H4+i1f0lPywNQyI4foeNXJRObB/uy+TYqUW0vAD9gbdSOXPst7Eg==", "dev": true, "dependencies": { - "are-we-there-yet": "^2.0.0", + "are-we-there-yet": "^3.0.0", "console-control-strings": "^1.1.0", "gauge": "^4.0.0", "set-blocking": "^2.0.0" @@ -10578,9 +10459,9 @@ } }, "node_modules/postcss-color-functional-notation": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.1.tgz", - "integrity": "sha512-62OBIXCjRXpQZcFOYIXwXBlpAVWrYk8ek1rcjvMING4Q2cf0ipyN9qT+BhHA6HmftGSEnFQu2qgKO3gMscl3Rw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.2.tgz", + "integrity": "sha512-DXVtwUhIk4f49KK5EGuEdgx4Gnyj6+t2jBSEmxvpIK9QI40tWrpS2Pua8Q7iIZWBrki2QOaeUdEaLPPa91K0RQ==", "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0" @@ -10589,13 +10470,13 @@ "node": "^12 || ^14 || >=16" }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.4" } }, "node_modules/postcss-color-hex-alpha": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.2.tgz", - "integrity": "sha512-gyx8RgqSmGVK156NAdKcsfkY3KPGHhKqvHTL3hhveFrBBToguKFzhyiuk3cljH6L4fJ0Kv+JENuPXs1Wij27Zw==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.3.tgz", + "integrity": "sha512-fESawWJCrBV035DcbKRPAVmy21LpoyiXdPTuHUfWJ14ZRjY7Y7PA6P4g8z6LQGYhU1WAxkTxjIjurXzoe68Glw==", "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0" @@ -10604,7 +10485,7 @@ "node": "^12 || ^14 || >=16" }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.4" } }, "node_modules/postcss-color-rebeccapurple": { @@ -10635,9 +10516,9 @@ } }, "node_modules/postcss-custom-properties": { - "version": "12.1.3", - "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.3.tgz", - "integrity": "sha512-rtu3otIeY532PnEuuBrIIe+N+pcdbX/7JMZfrcL09wc78YayrHw5E8UkDfvnlOhEUrI4ptCuzXQfj+Or6spbGA==", + "version": "12.1.4", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.4.tgz", + "integrity": "sha512-i6AytuTCoDLJkWN/MtAIGriJz3j7UX6bV7Z5t+KgFz+dwZS15/mlTJY1S0kRizlk6ba0V8u8hN50Fz5Nm7tdZw==", "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0" @@ -10646,7 +10527,7 @@ "node": "^12 || ^14 || >=16" }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.4" } }, "node_modules/postcss-custom-selectors": { @@ -10665,24 +10546,24 @@ } }, "node_modules/postcss-dir-pseudo-class": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.3.tgz", - "integrity": "sha512-qiPm+CNAlgXiMf0J5IbBBEXA9l/Q5HGsNGkL3znIwT2ZFRLGY9U2fTUpa4lqCUXQOxaLimpacHeQC80BD2qbDw==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.4.tgz", + "integrity": "sha512-I8epwGy5ftdzNWEYok9VjW9whC4xnelAtbajGv4adql4FIF09rnrxnA9Y8xSHN47y7gqFIv10C5+ImsLeJpKBw==", "dev": true, "dependencies": { - "postcss-selector-parser": "^6.0.8" + "postcss-selector-parser": "^6.0.9" }, "engines": { "node": "^12 || ^14 || >=16" }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.4" } }, "node_modules/postcss-double-position-gradients": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.0.4.tgz", - "integrity": "sha512-qz+s5vhKJlsHw8HjSs+HVk2QGFdRyC68KGRQGX3i+GcnUjhWhXQEmCXW6siOJkZ1giu0ddPwSO6I6JdVVVPoog==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.0.5.tgz", + "integrity": "sha512-XiZzvdxLOWZwtt/1GgHJYGoD9scog/DD/yI5dcvPrXNdNDEv7T53/6tL7ikl+EM3jcerII5/XIQzd1UHOdTi2w==", "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0" @@ -10691,13 +10572,13 @@ "node": "^12 || ^14 || >=16" }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.4" } }, "node_modules/postcss-env-function": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.4.tgz", - "integrity": "sha512-0ltahRTPtXSIlEZFv7zIvdEib7HN0ZbUQxrxIKn8KbiRyhALo854I/CggU5lyZe6ZBvSTJ6Al2vkZecI2OhneQ==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.5.tgz", + "integrity": "sha512-gPUJc71ji9XKyl0WSzAalBeEA/89kU+XpffpPxSaaaZ1c48OL36r1Ep5R6+9XAPkIiDlSvVAwP4io12q/vTcvA==", "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0" @@ -10706,37 +10587,37 @@ "node": "^12 || ^14 || >=16" }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.4" } }, "node_modules/postcss-focus-visible": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.3.tgz", - "integrity": "sha512-ozOsg+L1U8S+rxSHnJJiET6dNLyADcPHhEarhhtCI9DBLGOPG/2i4ddVoFch9LzrBgb8uDaaRI4nuid2OM82ZA==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz", + "integrity": "sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==", "dev": true, "dependencies": { - "postcss-selector-parser": "^6.0.8" + "postcss-selector-parser": "^6.0.9" }, "engines": { "node": "^12 || ^14 || >=16" }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.4" } }, "node_modules/postcss-focus-within": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.3.tgz", - "integrity": "sha512-fk9y2uFS6/Kpp7/A9Hz9Z4rlFQ8+tzgBcQCXAFSrXFGAbKx+4ZZOmmfHuYjCOMegPWoz0pnC6fNzi8j7Xyqp5Q==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz", + "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==", "dev": true, "dependencies": { - "postcss-selector-parser": "^6.0.8" + "postcss-selector-parser": "^6.0.9" }, "engines": { "node": "^12 || ^14 || >=16" }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.4" } }, "node_modules/postcss-font-variant": { @@ -10749,21 +10630,21 @@ } }, "node_modules/postcss-gap-properties": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.2.tgz", - "integrity": "sha512-EaMy/pbxtQnKDsnbEjdqlkCkROTQZzolcLKgIE+3b7EuJfJydH55cZeHfm+MtIezXRqhR80VKgaztO/vHq94Fw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.3.tgz", + "integrity": "sha512-rPPZRLPmEKgLk/KlXMqRaNkYTUpE7YC+bOIQFN5xcu1Vp11Y4faIXv6/Jpft6FMnl6YRxZqDZG0qQOW80stzxQ==", "dev": true, "engines": { "node": "^12 || ^14 || >=16" }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.4" } }, "node_modules/postcss-image-set-function": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.4.tgz", - "integrity": "sha512-BlEo9gSTj66lXjRNByvkMK9dEdEGFXRfGjKRi9fo8s0/P3oEk74cAoonl/utiM50E2OPVb/XSu+lWvdW4KtE/Q==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.6.tgz", + "integrity": "sha512-KfdC6vg53GC+vPd2+HYzsZ6obmPqOk6HY09kttU19+Gj1nC3S3XBVEXDHxkhxTohgZqzbUb94bKXvKDnYWBm/A==", "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0" @@ -10772,7 +10653,7 @@ "node": "^12 || ^14 || >=16" }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.4" } }, "node_modules/postcss-import": { @@ -10802,18 +10683,19 @@ } }, "node_modules/postcss-lab-function": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.0.3.tgz", - "integrity": "sha512-MH4tymWmefdZQ7uVG/4icfLjAQmH6o2NRYyVh2mKoB4RXJp9PjsyhZwhH4ouaCQHvg+qJVj3RzeAR1EQpIlXZA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.1.0.tgz", + "integrity": "sha512-59uHN/2wRaOd7whDyeaJ82E0kncIEeJkwcmvXFPNus8v1YMhtv2IUo9OtOAncn7sifZVMRsyoPlhxwckTjn4cQ==", "dev": true, "dependencies": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", "postcss-value-parser": "^4.2.0" }, "engines": { "node": "^12 || ^14 || >=16" }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.4" } }, "node_modules/postcss-loader": { @@ -10839,15 +10721,15 @@ } }, "node_modules/postcss-logical": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.3.tgz", - "integrity": "sha512-P5NcHWYrif0vK8rgOy/T87vg0WRIj3HSknrvp1wzDbiBeoDPVmiVRmkown2eSQdpPveat/MC1ess5uhzZFVnqQ==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz", + "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==", "dev": true, "engines": { "node": "^12 || ^14 || >=16" }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.4" } }, "node_modules/postcss-media-minmax": { @@ -10937,15 +10819,15 @@ } }, "node_modules/postcss-overflow-shorthand": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.2.tgz", - "integrity": "sha512-odBMVt6PTX7jOE9UNvmnLrFzA9pXS44Jd5shFGGtSHY80QCuJF+14McSy0iavZggRZ9Oj//C9vOKQmexvyEJMg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.3.tgz", + "integrity": "sha512-CxZwoWup9KXzQeeIxtgOciQ00tDtnylYIlJBBODqkgS/PU2jISuWOL/mYLHmZb9ZhZiCaNKsCRiLp22dZUtNsg==", "dev": true, "engines": { "node": "^12 || ^14 || >=16" }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.4" } }, "node_modules/postcss-page-break": { @@ -10958,9 +10840,9 @@ } }, "node_modules/postcss-place": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.3.tgz", - "integrity": "sha512-tDQ3m+GYoOar+KoQgj+pwPAvGHAp/Sby6vrFiyrELrMKQJ4AejL0NcS0mm296OKKYA2SRg9ism/hlT/OLhBrdQ==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.4.tgz", + "integrity": "sha512-MrgKeiiu5OC/TETQO45kV3npRjOFxEHthsqGtkh3I1rPbZSbXGD/lZVi9j13cYh+NA8PIAPyk6sGjT9QbRyvSg==", "dev": true, "dependencies": { "postcss-value-parser": "^4.2.0" @@ -10969,7 +10851,7 @@ "node": "^12 || ^14 || >=16" }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.4" } }, "node_modules/postcss-preset-env": { @@ -11020,18 +10902,18 @@ } }, "node_modules/postcss-pseudo-class-any-link": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.0.2.tgz", - "integrity": "sha512-CG35J1COUH7OOBgpw5O+0koOLUd5N4vUGKUqSAuIe4GiuLHWU96Pqp+UPC8QITTd12zYAFx76pV7qWT/0Aj/TA==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.1.tgz", + "integrity": "sha512-JRoLFvPEX/1YTPxRxp1JO4WxBVXJYrSY7NHeak5LImwJ+VobFMwYDQHvfTXEpcn+7fYIeGkC29zYFhFWIZD8fg==", "dev": true, "dependencies": { - "postcss-selector-parser": "^6.0.8" + "postcss-selector-parser": "^6.0.9" }, "engines": { "node": "^12 || ^14 || >=16" }, "peerDependencies": { - "postcss": "^8.3" + "postcss": "^8.4" } }, "node_modules/postcss-replace-overflow-wrap": { @@ -11425,12 +11307,12 @@ } }, "node_modules/raw-body": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", - "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", + "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", "dev": true, "dependencies": { - "bytes": "3.1.1", + "bytes": "3.1.2", "http-errors": "1.8.1", "iconv-lite": "0.4.24", "unpipe": "1.0.0" @@ -11551,9 +11433,9 @@ "dev": true }, "node_modules/regenerate-unicode-properties": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz", - "integrity": "sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz", + "integrity": "sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw==", "dev": true, "dependencies": { "regenerate": "^1.4.2" @@ -11600,15 +11482,15 @@ } }, "node_modules/regexpu-core": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.8.0.tgz", - "integrity": "sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.0.1.tgz", + "integrity": "sha512-CriEZlrKK9VJw/xQGJpQM5rY88BtuL8DM+AEwvcThHilbxiTAy8vq4iJnd2tqq8wLmjbGZzP7ZcKFjbGkmEFrw==", "dev": true, "dependencies": { "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^9.0.0", - "regjsgen": "^0.5.2", - "regjsparser": "^0.7.0", + "regenerate-unicode-properties": "^10.0.1", + "regjsgen": "^0.6.0", + "regjsparser": "^0.8.2", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.0.0" }, @@ -11617,15 +11499,15 @@ } }, "node_modules/regjsgen": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", - "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.6.0.tgz", + "integrity": "sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA==", "dev": true }, "node_modules/regjsparser": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.7.0.tgz", - "integrity": "sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==", + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.8.4.tgz", + "integrity": "sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA==", "dev": true, "dependencies": { "jsesc": "~0.5.0" @@ -11799,9 +11681,9 @@ } }, "node_modules/rollup": { - "version": "2.66.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.66.1.tgz", - "integrity": "sha512-crSgLhSkLMnKr4s9iZ/1qJCplgAgrRY+igWv8KhG/AjKOJ0YX/WpmANyn8oxrw+zenF3BXWDLa7Xl/QZISH+7w==", + "version": "2.67.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.67.2.tgz", + "integrity": "sha512-hoEiBWwZtf1QdK3jZIq59L0FJj4Fiv4RplCO4pvCRC86qsoFurWB4hKQIjoRf3WvJmk5UZ9b0y5ton+62fC7Tw==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -12207,9 +12089,9 @@ } }, "node_modules/signal-exit": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", - "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, "node_modules/slash": { @@ -12296,13 +12178,13 @@ } }, "node_modules/socks": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.1.tgz", - "integrity": "sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz", + "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==", "dev": true, "dependencies": { "ip": "^1.1.5", - "smart-buffer": "^4.1.0" + "smart-buffer": "^4.2.0" }, "engines": { "node": ">= 10.13.0", @@ -12769,12 +12651,12 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.0.tgz", - "integrity": "sha512-LPIisi3Ol4chwAaPP8toUJ3L4qCM1G0wao7L3qNv57Drezxj6+VEyySpPw4B1HSO2Eg/hDY/MNF5XihCAoqnsQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.1.tgz", + "integrity": "sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g==", "dev": true, "dependencies": { - "jest-worker": "^27.4.1", + "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", "serialize-javascript": "^6.0.0", "source-map": "^0.6.1", @@ -12919,9 +12801,9 @@ } }, "node_modules/ts-node": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", - "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.5.0.tgz", + "integrity": "sha512-6kEJKwVxAJ35W4akuiysfKwKmjkbYxwQMTBaAxo9KKAx/Yd26mPUyhGz3ji+EsJoAgrLqVsYHNuuYwQe22lbtw==", "dev": true, "dependencies": { "@cspotcode/source-map-support": "0.7.0", @@ -12935,6 +12817,7 @@ "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.0", "yn": "3.1.1" }, "bin": { @@ -13257,6 +13140,12 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", + "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==", + "dev": true + }, "node_modules/validate-npm-package-name": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", @@ -13276,10 +13165,14 @@ } }, "node_modules/vm2": { - "version": "3.9.5", - "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.5.tgz", - "integrity": "sha512-LuCAHZN75H9tdrAiLFf030oW7nJV5xwNMuk1ymOZwopmuK3d2H4L1Kv4+GFHgarKiLfXXLFU+7LDABHnwOkWng==", + "version": "3.9.7", + "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.7.tgz", + "integrity": "sha512-g/GZ7V0Mlmch3eDVOATvAXr1GsJNg6kQ5PjvYy3HbJMCRn5slNbo/u73Uy7r5yUej1cRa3ZjtoVwcWSQuQ/fow==", "dev": true, + "dependencies": { + "acorn": "^8.7.0", + "acorn-walk": "^8.2.0" + }, "bin": { "vm2": "bin/vm2" }, @@ -13319,13 +13212,14 @@ } }, "node_modules/webpack": { - "version": "5.67.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.67.0.tgz", - "integrity": "sha512-LjFbfMh89xBDpUMgA1W9Ur6Rn/gnr2Cq1jjHFPo4v6a79/ypznSYbAyPgGhwsxBtMIaEmDD1oJoA7BEYw/Fbrw==", + "version": "5.69.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.69.0.tgz", + "integrity": "sha512-E5Fqu89Gu8fR6vejRqu26h8ld/k6/dCVbeGUcuZjc+goQHDfCPU9rER71JmdtBYGmci7Ec2aFEATQ2IVXKy2wg==", "dev": true, + "peer": true, "dependencies": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.50", + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^0.0.51", "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/wasm-edit": "1.11.1", "@webassemblyjs/wasm-parser": "1.11.1", @@ -13333,7 +13227,7 @@ "acorn-import-assertions": "^1.7.6", "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.3", + "enhanced-resolve": "^5.9.0", "es-module-lexer": "^0.9.0", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -13389,9 +13283,9 @@ } }, "node_modules/webpack-dev-middleware/node_modules/ajv": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", - "integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz", + "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", @@ -13404,23 +13298,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/webpack-dev-middleware/node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", @@ -13433,12 +13310,6 @@ "ajv": "^8.8.2" } }, - "node_modules/webpack-dev-middleware/node_modules/colorette": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", - "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", - "dev": true - }, "node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -13516,9 +13387,9 @@ } }, "node_modules/webpack-dev-server/node_modules/ajv": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", - "integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz", + "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", @@ -13531,23 +13402,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/webpack-dev-server/node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, "node_modules/webpack-dev-server/node_modules/ajv-keywords": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", @@ -13572,12 +13426,6 @@ "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/webpack-dev-server/node_modules/colorette": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", - "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", - "dev": true - }, "node_modules/webpack-dev-server/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -13618,27 +13466,6 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.4.2.tgz", - "integrity": "sha512-Kbk4Nxyq7/ZWqr/tarI9yIt/+iNNFOjBXEWgTb4ydaNHBNGgvf2QHbS9fdfsndfjFlFwEd4Al+mw83YkaD10ZA==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/webpack-merge": { "version": "5.8.0", "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", @@ -13682,11 +13509,19 @@ } } }, + "node_modules/webpack/node_modules/@types/estree": { + "version": "0.0.51", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", + "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", + "dev": true, + "peer": true + }, "node_modules/webpack/node_modules/schema-utils": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", "dev": true, + "peer": true, "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -13903,6 +13738,27 @@ "typedarray-to-buffer": "^3.1.5" } }, + "node_modules/ws": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", + "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/xregexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", @@ -14013,16 +13869,26 @@ "sourcemap-codec": "1.4.8" } }, + "@angular-devkit/architect": { + "version": "0.1302.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1302.3.tgz", + "integrity": "sha512-0m8jMKrFfIqsYt33zTUwSmyekyfuS67hna08RQ6USjzWQSE3z4S8ulCUARSjM6AzdMblX+whfy56nJUpT17NSA==", + "dev": true, + "requires": { + "@angular-devkit/core": "13.2.3", + "rxjs": "6.6.7" + } + }, "@angular-devkit/build-angular": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-13.2.0.tgz", - "integrity": "sha512-cHnm/P7uKJjKh2BCN8gnnd240J5z3IesQyRAx88kFSlL5sKCGyGoAYKAjU585/lllIXjtFXSR/S2d/cHg8ShKw==", + "version": "13.2.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-13.2.3.tgz", + "integrity": "sha512-cZ2gRcMRgW3t1WCeP+2D/wmr2M+BR/RICAh0wL9irIdypWAzIFt3Z2+2R/HmgAAxoEkdUMIfB9AnkYmwRVgFeA==", "dev": true, "requires": { "@ampproject/remapping": "1.1.1", - "@angular-devkit/architect": "0.1302.0", - "@angular-devkit/build-webpack": "0.1302.0", - "@angular-devkit/core": "13.2.0", + "@angular-devkit/architect": "0.1302.3", + "@angular-devkit/build-webpack": "0.1302.3", + "@angular-devkit/core": "13.2.3", "@babel/core": "7.16.12", "@babel/generator": "7.16.8", "@babel/helper-annotate-as-pure": "7.16.7", @@ -14033,7 +13899,7 @@ "@babel/runtime": "7.16.7", "@babel/template": "7.16.7", "@discoveryjs/json-ext": "0.5.6", - "@ngtools/webpack": "13.2.0", + "@ngtools/webpack": "13.2.3", "ansi-colors": "4.1.1", "babel-loader": "8.2.3", "babel-plugin-istanbul": "6.1.1", @@ -14053,7 +13919,7 @@ "karma-source-map-support": "1.4.0", "less": "4.1.2", "less-loader": "10.2.0", - "license-webpack-plugin": "4.0.0", + "license-webpack-plugin": "4.0.1", "loader-utils": "3.2.0", "mini-css-extract-plugin": "2.5.3", "minimatch": "3.0.4", @@ -14086,93 +13952,87 @@ "webpack-subresource-integrity": "5.1.0" }, "dependencies": { - "@angular-devkit/architect": { - "version": "0.1302.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1302.0.tgz", - "integrity": "sha512-1CmVYvxyfvK/khTcDJwwXibm/z4upM2j5SDpwuIdaLx21E4oQPmHn+U/quT/jE5VI1zfZi2vfvIaSXn9XQzMiQ==", - "dev": true, - "requires": { - "@angular-devkit/core": "13.2.0", - "rxjs": "6.6.7" - } - }, - "@angular-devkit/core": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.2.0.tgz", - "integrity": "sha512-5+aV2W2QUazySMKusBuT2pi2qsXWpTHJG2x62mKGAy0lxzwG8l3if+WP3Uh85SQS+zqlHeKxEbmm9zNn8ZrzFg==", - "dev": true, - "requires": { - "ajv": "8.9.0", - "ajv-formats": "2.1.1", - "fast-json-stable-stringify": "2.1.0", - "magic-string": "0.25.7", - "rxjs": "6.6.7", - "source-map": "0.7.3" - } - }, - "ajv": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", - "integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "requires": { - "ajv": "^8.0.0" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "@types/estree": { + "version": "0.0.50", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", + "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", "dev": true + }, + "core-js": { + "version": "3.20.3", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.20.3.tgz", + "integrity": "sha512-vVl8j8ph6tRS3B8qir40H7yw7voy17xL0piAjlbBUsH7WIfzoedL/ZOr1OV9FyZQLWXsayOJyV4tnRyXR85/ag==", + "dev": true + }, + "schema-utils": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "webpack": { + "version": "5.67.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.67.0.tgz", + "integrity": "sha512-LjFbfMh89xBDpUMgA1W9Ur6Rn/gnr2Cq1jjHFPo4v6a79/ypznSYbAyPgGhwsxBtMIaEmDD1oJoA7BEYw/Fbrw==", + "dev": true, + "requires": { + "@types/eslint-scope": "^3.7.0", + "@types/estree": "^0.0.50", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.4.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.8.3", + "es-module-lexer": "^0.9.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.3.1", + "webpack-sources": "^3.2.3" + } } } }, "@angular-devkit/build-webpack": { - "version": "0.1302.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1302.0.tgz", - "integrity": "sha512-x5BLdobF7c7j4W8frJuKM73ZYvPygjPN8vq1iKhsEraClqJG8cLiDwLEEFcrzIfmCHTX1o1o75sWC0FNln2LfQ==", + "version": "0.1302.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1302.3.tgz", + "integrity": "sha512-+JYH1lWU0UOjaWYxpoR2VLsdcb6nG9Gv+M1gH+kT0r2sAKOFaHnrksbOvca3EhDoaMa2b9LSGEE0OcSHWnN+eQ==", "dev": true, "requires": { - "@angular-devkit/architect": "0.1302.0", + "@angular-devkit/architect": "0.1302.3", "rxjs": "6.6.7" + } + }, + "@angular-devkit/core": { + "version": "13.2.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.2.3.tgz", + "integrity": "sha512-/47RA8qmWzeS60xSdaprIn1MiSv0Iw83t0M9/ENH7irFS5vMAq62NCcwiWXH59pZmvvLbF+7xy/RgYUZLr4nHQ==", + "dev": true, + "requires": { + "ajv": "8.9.0", + "ajv-formats": "2.1.1", + "fast-json-stable-stringify": "2.1.0", + "magic-string": "0.25.7", + "rxjs": "6.6.7", + "source-map": "0.7.3" }, "dependencies": { - "@angular-devkit/architect": { - "version": "0.1302.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1302.0.tgz", - "integrity": "sha512-1CmVYvxyfvK/khTcDJwwXibm/z4upM2j5SDpwuIdaLx21E4oQPmHn+U/quT/jE5VI1zfZi2vfvIaSXn9XQzMiQ==", - "dev": true, - "requires": { - "@angular-devkit/core": "13.2.0", - "rxjs": "6.6.7" - } - }, - "@angular-devkit/core": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.2.0.tgz", - "integrity": "sha512-5+aV2W2QUazySMKusBuT2pi2qsXWpTHJG2x62mKGAy0lxzwG8l3if+WP3Uh85SQS+zqlHeKxEbmm9zNn8ZrzFg==", - "dev": true, - "requires": { - "ajv": "8.9.0", - "ajv-formats": "2.1.1", - "fast-json-stable-stringify": "2.1.0", - "magic-string": "0.25.7", - "rxjs": "6.6.7", - "source-map": "0.7.3" - } - }, "ajv": { "version": "8.9.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", @@ -14185,15 +14045,6 @@ "uri-js": "^4.2.2" } }, - "ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "requires": { - "ajv": "^8.0.0" - } - }, "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -14202,24 +14053,37 @@ } } }, + "@angular-devkit/schematics": { + "version": "13.2.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-13.2.3.tgz", + "integrity": "sha512-+dyC4iKV0huvpjiuz4uyjLNK3FsCIp/Ghv5lXvhG6yok/dCAubsJItJOxi6G16aVCzG/E9zbsDfm9fNMyVOkgQ==", + "dev": true, + "requires": { + "@angular-devkit/core": "13.2.3", + "jsonc-parser": "3.0.0", + "magic-string": "0.25.7", + "ora": "5.4.1", + "rxjs": "6.6.7" + } + }, "@angular/animations": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-13.2.0.tgz", - "integrity": "sha512-zLmNxkfxDQShJ97V9gTyQdlEbCD/zDUdpHXKlUViBIbe2M13FLGV3e2D+x9jGr/PRzFe0cukOnYxNEHJqqjqPA==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-13.2.2.tgz", + "integrity": "sha512-qX8LAMuCJaueHBVyuwKtqunx96G0Dr26k7y5Z03VTcscYst4Ib4V2d4i5dwn3HS82DehFdO86cm3Hi2PqE/qww==", "requires": { "tslib": "^2.3.0" } }, "@angular/cli": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-13.2.0.tgz", - "integrity": "sha512-xrtClCucVSBwELG6zgaHrjC71p1rZOkwjF/HewnOFNjyjXSbWIO2y5d/6O2wxmNASoeStpiEU0zPpwDGhXiYpQ==", + "version": "13.2.3", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-13.2.3.tgz", + "integrity": "sha512-QsakxpdQuO67u4fQNuOASqabYUO9gJb/5CpUGpWbuBzru0/9CMEF1CtXoF4EoDiwa5sJMirz3SJMKhtzFlv1cQ==", "dev": true, "requires": { - "@angular-devkit/architect": "0.1302.0", - "@angular-devkit/core": "13.2.0", - "@angular-devkit/schematics": "13.2.0", - "@schematics/angular": "13.2.0", + "@angular-devkit/architect": "0.1302.3", + "@angular-devkit/core": "13.2.3", + "@angular-devkit/schematics": "13.2.3", + "@schematics/angular": "13.2.3", "@yarnpkg/lockfile": "1.1.0", "ansi-colors": "4.1.1", "debug": "4.3.3", @@ -14235,98 +14099,31 @@ "semver": "7.3.5", "symbol-observable": "4.0.0", "uuid": "8.3.2" - }, - "dependencies": { - "@angular-devkit/architect": { - "version": "0.1302.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1302.0.tgz", - "integrity": "sha512-1CmVYvxyfvK/khTcDJwwXibm/z4upM2j5SDpwuIdaLx21E4oQPmHn+U/quT/jE5VI1zfZi2vfvIaSXn9XQzMiQ==", - "dev": true, - "requires": { - "@angular-devkit/core": "13.2.0", - "rxjs": "6.6.7" - } - }, - "@angular-devkit/core": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.2.0.tgz", - "integrity": "sha512-5+aV2W2QUazySMKusBuT2pi2qsXWpTHJG2x62mKGAy0lxzwG8l3if+WP3Uh85SQS+zqlHeKxEbmm9zNn8ZrzFg==", - "dev": true, - "requires": { - "ajv": "8.9.0", - "ajv-formats": "2.1.1", - "fast-json-stable-stringify": "2.1.0", - "magic-string": "0.25.7", - "rxjs": "6.6.7", - "source-map": "0.7.3" - } - }, - "@angular-devkit/schematics": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-13.2.0.tgz", - "integrity": "sha512-EwoqDqLJH5YpWiLuQJwonnJu2bi4xQlyKXyUTuXsQ4gIsAPrg+ijyAe+F/brAtDLBj0sU7JHoC0U1yx2pZ7f1A==", - "dev": true, - "requires": { - "@angular-devkit/core": "13.2.0", - "jsonc-parser": "3.0.0", - "magic-string": "0.25.7", - "ora": "5.4.1", - "rxjs": "6.6.7" - } - }, - "ajv": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", - "integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "requires": { - "ajv": "^8.0.0" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - } } }, "@angular/common": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-13.2.0.tgz", - "integrity": "sha512-zyq3kscl5BoY+xxl4YOfbKP72xwzx/vKLE+2ougjPu2spm5KIllIAo/VrxVqIBrsGWT/4gs9pvIOqOdOfufxUA==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-13.2.2.tgz", + "integrity": "sha512-56C/bheNLKtTCyQUZCiYtKbBIZN9jj6rjFILPtJCGls3cBCxp7t9tIdoLiQG/wVQRmaxdj1ioLT+sCWz7mLtQw==", "requires": { "tslib": "^2.3.0" } }, "@angular/compiler": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-13.2.0.tgz", - "integrity": "sha512-TTA+Mn31vAwI4qiaH0h8DqNV3DWgZF+Q9G8Qqbw17k8Jf+B5CdLkMYBF8wbGegIdsEfo+6DebCp71W+aJxuSlw==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-13.2.2.tgz", + "integrity": "sha512-XXQtB0/e7pR2LPrHmpEiTU72SX4xxHGy91vYWIj1JCjSn0fYF7vtHzSJPXDvkbnkNow/PXXzJJYaU1ctdMZPcA==", "requires": { "tslib": "^2.3.0" } }, "@angular/compiler-cli": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-13.2.0.tgz", - "integrity": "sha512-IDX0X3GXjhUzd/cFyNZBG3eVqh6Y2W7MYvH9tXbZHcJ6vH9RkN2+zh/XQautVWy4EP33oQoDlsydfYKqbHr9TA==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-13.2.2.tgz", + "integrity": "sha512-tuOIcEEKVIht+mKrj0rtX3I8gc+ByPjzpCZhFQRggxM6xbKJIToO1zERbEGKrZ+sUJ6BB5KLvscDy+Pddy3b8w==", "dev": true, "requires": { "@babel/core": "^7.8.6", - "canonical-path": "1.0.0", "chokidar": "^3.0.0", "convert-source-map": "^1.5.1", "dependency-graph": "^0.11.0", @@ -14339,47 +14136,47 @@ } }, "@angular/core": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-13.2.0.tgz", - "integrity": "sha512-mWRWbbZ6k00AicA/GrxmWKaw8upo77sRQz4tSYKpwVKt2TtCeoW8OkdYUpnmuVjxpF0bD6PtVc0e1fD6es/ElA==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-13.2.2.tgz", + "integrity": "sha512-zpctw0BxIVOsRFnckchK15SD1L8tzhf5GzwIDaM6+VylDQj1uYkm8mvAjJTQZyUuApomoFet2Rfj7XQPV+cNSQ==", "requires": { "tslib": "^2.3.0" } }, "@angular/forms": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-13.2.0.tgz", - "integrity": "sha512-aduXLuvqynDRRdb316yY1O5rdMQ2DKeNxu5P2FG1nkLQ3hqZvpiaUMhFyXvKDG3s0rV5e/PZs1cpg0Aqdfwevw==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-13.2.2.tgz", + "integrity": "sha512-T61W4Ay9X9qhxjc6lLqpNFeHrGKwg2mqdsZ3zIm/c7oKo37mgl9TB5kkrtnS+205r3N2hF4ICnGFZ4a/egUP/g==", "requires": { "tslib": "^2.3.0" } }, "@angular/language-service": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-13.2.0.tgz", - "integrity": "sha512-nK40YXy9f2MsrejvTiKMrS7YHNvBxp3QIBU8aJN36LpkTTWC8aVqZ5A3to8JL0U6Anra8mkcC070xoYfh6miwg==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-13.2.2.tgz", + "integrity": "sha512-2P5+wRsbHgpI2rVeFwnsLWxyntUiw8kG9Tqh5BkVDqtQovbYtzFiaMkf5TFz/g938JBBgeRQzvXr1kQhEidAWQ==", "dev": true }, "@angular/platform-browser": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-13.2.0.tgz", - "integrity": "sha512-FB9eKdRqpjopTFbea5JXnqSPFR7DZD4nepOSGnYttV9cVj4pABqx2A6FJCnyvPPUSTamODye/pNkGmzP2P1gcw==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-13.2.2.tgz", + "integrity": "sha512-M7gWC8fFCPc/CRcHCzqe/j7WzwAUMeKt9vwlK633XnesHBoqZdYgbb3YHHc6WPVU0YI09Nb/Hm5sezEKmjUmPg==", "requires": { "tslib": "^2.3.0" } }, "@angular/platform-browser-dynamic": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-13.2.0.tgz", - "integrity": "sha512-VPL0uF/KWk+jBfkZwt60K6YbTFOvQzZbhwE4LttjjejstdvR0IMD3PtVDrdgIUWNfjikcCVN5Ds0GB6zZUb04Q==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-13.2.2.tgz", + "integrity": "sha512-lj6xwat0StLp+ROFqXU62upwHQhlxaQi0djhrS+DGKUK0Xu9bkBeaSCfBFgS78jPm1SwL8Xztu9/vuDAHLRrqw==", "requires": { "tslib": "^2.3.0" } }, "@angular/router": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-13.2.0.tgz", - "integrity": "sha512-8fWxcWT/LpaGhmXJ8xH+E7UObzt5IMGzK1sJGRu508y5tcbuBlTJt3yV97mCeUQ0g/E+2GEv6vuxY7OcfDaZow==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-13.2.2.tgz", + "integrity": "sha512-dt2b9/kGJAkmOqUmUD3aKlp4pGpdqLwB0zmhUYF3ktNEcQaPf4ZjWT/4jhy09gFL+TKOHG5OQW9GxBbhWI4bSg==", "requires": { "tslib": "^2.3.0" } @@ -14400,9 +14197,9 @@ } }, "@babel/compat-data": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.8.tgz", - "integrity": "sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.0.tgz", + "integrity": "sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==", "dev": true }, "@babel/core": { @@ -14501,9 +14298,9 @@ } }, "@babel/helper-create-class-features-plugin": { - "version": "7.16.10", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.10.tgz", - "integrity": "sha512-wDeej0pu3WN/ffTxMNCPW5UCiOav8IcLRxSIyp/9+IF2xJUM9h/OYjg0IJLHaL6F8oU8kqMz9nc1vryXhMsgXg==", + "version": "7.17.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.1.tgz", + "integrity": "sha512-JBdSr/LtyYIno/pNnJ75lBcqc3Z1XXujzPanHqjvvrhOA+DTceTFuJi8XjmWTZh4r3fsdfqaCMN0iZemdkxZHQ==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.16.7", @@ -14516,13 +14313,13 @@ } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.7.tgz", - "integrity": "sha512-fk5A6ymfp+O5+p2yCkXAu5Kyj6v0xh0RBeNcAkYUMDvvAAoxvSKXn+Jb37t/yWFiQVDFK1ELpUTD8/aLhCPu+g==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.0.tgz", + "integrity": "sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.16.7", - "regexpu-core": "^4.7.1" + "regexpu-core": "^5.0.1" } }, "@babel/helper-define-polyfill-provider": { @@ -14721,14 +14518,14 @@ } }, "@babel/helpers": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.7.tgz", - "integrity": "sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw==", + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz", + "integrity": "sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==", "dev": true, "requires": { "@babel/template": "^7.16.7", - "@babel/traverse": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/traverse": "^7.17.0", + "@babel/types": "^7.17.0" } }, "@babel/highlight": { @@ -14743,9 +14540,9 @@ } }, "@babel/parser": { - "version": "7.16.12", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.12.tgz", - "integrity": "sha512-VfaV15po8RiZssrkPweyvbGVSe4x2y+aciFCgn0n0/SJMR22cwofRV1mtnJQYcSB1wUTaA/X1LnA3es66MCO5A==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.0.tgz", + "integrity": "sha512-VKXSCQx5D8S04ej+Dqsr1CzYvvWgf20jIw2D+YhQCrIlr2UZGaDds23Y0xg75/skOxpLCRpUZvk/1EAVkGoDOw==", "dev": true }, "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { @@ -15512,27 +15309,46 @@ } }, "@babel/traverse": { - "version": "7.16.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.10.tgz", - "integrity": "sha512-yzuaYXoRJBGMlBhsMJoUW7G1UmSb/eXr/JHYM/MsOJgavJibLwASijW7oXBdw3NQ6T0bW7Ty5P/VarOs9cHmqw==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.0.tgz", + "integrity": "sha512-fpFIXvqD6kC7c7PUNnZ0Z8cQXlarCLtCUpt2S1Dx7PjoRtCFffvOkHHSom+m5HIxMZn5bIBVb71lhabcmjEsqg==", "dev": true, "requires": { "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.16.8", + "@babel/generator": "^7.17.0", "@babel/helper-environment-visitor": "^7.16.7", "@babel/helper-function-name": "^7.16.7", "@babel/helper-hoist-variables": "^7.16.7", "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.16.10", - "@babel/types": "^7.16.8", + "@babel/parser": "^7.17.0", + "@babel/types": "^7.17.0", "debug": "^4.1.0", "globals": "^11.1.0" + }, + "dependencies": { + "@babel/generator": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.0.tgz", + "integrity": "sha512-I3Omiv6FGOC29dtlZhkfXO6pgkmukJSlT26QjVvS1DGZe/NzSVCPG41X0tS21oZkJYlovfj9qDWgKP+Cn4bXxw==", + "dev": true, + "requires": { + "@babel/types": "^7.17.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } } }, "@babel/types": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.8.tgz", - "integrity": "sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.16.7", @@ -15554,6 +15370,15 @@ "@cspotcode/source-map-consumer": "0.8.0" } }, + "@csstools/postcss-progressive-custom-properties": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.1.0.tgz", + "integrity": "sha512-DO76V3295AqhjJZvgeaDP5GAGAat4g6wYfF8X+1n+76MpJat8ffY5bCJ9eSUqFY71nImxXgaDTRYJcRnA9oo7g==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, "@discoveryjs/json-ext": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz", @@ -15567,11 +15392,11 @@ "dev": true }, "@ionic/angular": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@ionic/angular/-/angular-6.0.4.tgz", - "integrity": "sha512-+xUJFu4kS1cCFNoraIonHv/6Sr3kFX8odowA1c+EcElCKZ6rTD+ZQyawKnOFebyF9WIGeVDD4j2Bw7VujBV0ag==", + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/@ionic/angular/-/angular-6.0.7.tgz", + "integrity": "sha512-/nNuwkt+oqQ44jokT+YKuHqsknGnhkmXn9hcd+RuDVW/Q8mZXK4YQZs8e5Rxs6T2ttkyjUHZg77lF6eS/W76hQ==", "requires": { - "@ionic/core": "^6.0.4", + "@ionic/core": "^6.0.7", "jsonc-parser": "^3.0.0", "tslib": "^2.0.0" } @@ -15841,11 +15666,11 @@ } }, "@ionic/core": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.0.4.tgz", - "integrity": "sha512-s/hJidmB3qtuBE/IY6cfPYJb8U7pWP2c1oUfyZGp9dyqLy9F4fYOKBog6Pzgfs0U50CArCGJfHSp6ufPFA0G2w==", + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.0.7.tgz", + "integrity": "sha512-Yl6itMcddfwfNNa6BjCxXxrIS+vPsrYSTfCmQwVfB4AiuZ5ZgE/jaZ9lMN7b0WIAy56bfX9etRlW+EjnK1znyQ==", "requires": { - "@stencil/core": "~2.12.0", + "@stencil/core": "~2.13.0", "ionicons": "^6.0.0", "tslib": "^2.1.0" } @@ -16012,9 +15837,9 @@ "dev": true }, "@jridgewell/resolve-uri": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.3.tgz", - "integrity": "sha512-fuIOnc81C5iRNevb/XPiM8Khp9bVjreydRQ37rt0C/dY0PAW1DRvEM3WrKX/5rStS5lbgwS0FCgqSndh9tvK5w==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", + "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", "dev": true }, "@materia-ui/ngx-monaco-editor": { @@ -16026,9 +15851,9 @@ } }, "@ngtools/webpack": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-13.2.0.tgz", - "integrity": "sha512-dQKPsEsST/HSBYtC75E0ARI1zVsW65h/NYzcAwtOd8DKFmlj8EZMqKC4KwcJ/EKlwR1PN12nBZhuQ1HUVH8Vtg==", + "version": "13.2.3", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-13.2.3.tgz", + "integrity": "sha512-wooUZiV92QyoeFxkhqIwH/cfiAAAn+l8fEEuaaEIfJtpjpbShvvlboEVsqb28soeGiFJfLcmsZM3mUFgsG4QBQ==", "dev": true, "requires": {} }, @@ -16059,9 +15884,9 @@ } }, "@npmcli/fs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.0.tgz", - "integrity": "sha512-VhP1qZLXcrXRIaPoqb4YA55JQxLNF3jNR4T55IdOJa3+IFJKNYHtPvtXx8slmeMavj37vCzCfrqQM1vWLsYKLA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", + "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", "dev": true, "requires": { "@gar/promisify": "^1.0.1", @@ -16163,81 +15988,17 @@ "@types/estree": "0.0.39", "estree-walker": "^1.0.1", "picomatch": "^2.2.2" - }, - "dependencies": { - "@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", - "dev": true - } } }, "@schematics/angular": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-13.2.0.tgz", - "integrity": "sha512-DlUJ+ix9u/wz7IWc82dix5xsDGu0nztZ6Litrv+EsFDRYc95IFxTWuNwwjL2eRkI2KLIk79wmO7xhlUwrUyNlg==", + "version": "13.2.3", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-13.2.3.tgz", + "integrity": "sha512-jloooGC7eco9AKxlIMMqFRptJYzZ0jNRBStWOp2dCISg6rmOKqpxbsHLtYFQIT1PnlomSxtKDAgYGQMDi9zhXw==", "dev": true, "requires": { - "@angular-devkit/core": "13.2.0", - "@angular-devkit/schematics": "13.2.0", + "@angular-devkit/core": "13.2.3", + "@angular-devkit/schematics": "13.2.3", "jsonc-parser": "3.0.0" - }, - "dependencies": { - "@angular-devkit/core": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-13.2.0.tgz", - "integrity": "sha512-5+aV2W2QUazySMKusBuT2pi2qsXWpTHJG2x62mKGAy0lxzwG8l3if+WP3Uh85SQS+zqlHeKxEbmm9zNn8ZrzFg==", - "dev": true, - "requires": { - "ajv": "8.9.0", - "ajv-formats": "2.1.1", - "fast-json-stable-stringify": "2.1.0", - "magic-string": "0.25.7", - "rxjs": "6.6.7", - "source-map": "0.7.3" - } - }, - "@angular-devkit/schematics": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-13.2.0.tgz", - "integrity": "sha512-EwoqDqLJH5YpWiLuQJwonnJu2bi4xQlyKXyUTuXsQ4gIsAPrg+ijyAe+F/brAtDLBj0sU7JHoC0U1yx2pZ7f1A==", - "dev": true, - "requires": { - "@angular-devkit/core": "13.2.0", - "jsonc-parser": "3.0.0", - "magic-string": "0.25.7", - "ora": "5.4.1", - "rxjs": "6.6.7" - } - }, - "ajv": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", - "integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "requires": { - "ajv": "^8.0.0" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - } } }, "@start9labs/argon2": { @@ -16251,9 +16012,9 @@ "integrity": "sha512-1dhiG03VkfEwSLx/JPKVms6srAbYFQgwfSGhwpUKMDliMXuAHGVaueStmqzVxn3JpH/HEVz0QW8w/PXHqjdiIg==" }, "@stencil/core": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.12.1.tgz", - "integrity": "sha512-u24TZ+FEvjnZt5ZgIkLjLpUNsO6Ml3mUZqwmqk81w6RWWz75hgB5p4RFI5rvuErFeh2xvMIGo+pNdG24XUBz1A==" + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.13.0.tgz", + "integrity": "sha512-EEKHOHgYpg3/iFUKMXTZJjUayRul7sXDwNw0OGgkEOe4t7JWiibDkzUHuruvpbqEydX+z1+ez5K2bMMY76c2wA==" }, "@tootallnate/once": { "version": "1.1.2", @@ -16359,9 +16120,9 @@ } }, "@types/estree": { - "version": "0.0.50", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", - "integrity": "sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==", + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", "dev": true }, "@types/express": { @@ -16427,9 +16188,9 @@ "dev": true }, "@types/node": { - "version": "16.11.21", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.21.tgz", - "integrity": "sha512-Pf8M1XD9i1ksZEcCP8vuSNwooJ/bZapNmIzpmsMaL+jMI+8mEYU3PKvs+xDNuQcJWF/x24WzY4qxLtB0zNow9A==", + "version": "16.11.25", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.25.tgz", + "integrity": "sha512-NrTwfD7L1RTc2qrHQD4RTTy4p0CO2LatKBEKEds3CaVuhoM/+DJzmWZl5f+ikR8cm8F5mfJxK+9rQq07gRiSjQ==", "dev": true }, "@types/parse-json": { @@ -16700,21 +16461,13 @@ "dev": true }, "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - }, - "dependencies": { - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "dev": true - } + "mime-types": "~2.1.34", + "negotiator": "0.6.3" } }, "acorn": { @@ -16805,6 +16558,35 @@ "uri-js": "^4.2.2" } }, + "ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "requires": { + "ajv": "^8.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz", + "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + } + } + }, "ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", @@ -16872,9 +16654,9 @@ "dev": true }, "are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.0.tgz", + "integrity": "sha512-0GWpv50YSOcLXaN6/FAKY3vfRbllXWV2xvfA/oKJF8pzFhWXPV+yjhJXDBbjscDYowv7Yw1A3uigpzn5iEGTyw==", "dev": true, "requires": { "delegates": "^1.0.0", @@ -17036,13 +16818,13 @@ } }, "babel-plugin-polyfill-corejs3": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.1.tgz", - "integrity": "sha512-TihqEe4sQcb/QcPJvxe94/9RZuLQuF1+To4WqQcRvc+3J3gLCPIPgDKzGLG6zmQLfH3nn25heRuDNkS2KR4I8A==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz", + "integrity": "sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ==", "dev": true, "requires": { "@babel/helper-define-polyfill-provider": "^0.3.1", - "core-js-compat": "^3.20.0" + "core-js-compat": "^3.21.0" } }, "babel-plugin-polyfill-regenerator": { @@ -17113,6 +16895,12 @@ "type-is": "~1.6.18" }, "dependencies": { + "bytes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", + "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==", + "dev": true + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -17133,6 +16921,18 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==", "dev": true + }, + "raw-body": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", + "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", + "dev": true, + "requires": { + "bytes": "3.1.1", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } } } }, @@ -17223,9 +17023,9 @@ "dev": true }, "bytes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", - "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true }, "cacache": { @@ -17276,15 +17076,9 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "caniuse-lite": { - "version": "1.0.30001303", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001303.tgz", - "integrity": "sha512-/Mqc1oESndUNszJP0kx0UaQU9kEv9nNtJ7Kn8AdA0mNnH8eR1cj0kG+NbNuC1Wq/b21eA8prhKRA3bbkjONegQ==", - "dev": true - }, - "canonical-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/canonical-path/-/canonical-path-1.0.0.tgz", - "integrity": "sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg==", + "version": "1.0.30001312", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz", + "integrity": "sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==", "dev": true }, "chalk": { @@ -17496,6 +17290,12 @@ "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "dev": true }, + "colorette": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", + "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", + "dev": true + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -17668,9 +17468,9 @@ }, "dependencies": { "ajv": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", - "integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz", + "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -17679,15 +17479,6 @@ "uri-js": "^4.2.2" } }, - "ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "requires": { - "ajv": "^8.0.0" - } - }, "ajv-keywords": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", @@ -17727,14 +17518,14 @@ } }, "core-js": { - "version": "3.20.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.20.3.tgz", - "integrity": "sha512-vVl8j8ph6tRS3B8qir40H7yw7voy17xL0piAjlbBUsH7WIfzoedL/ZOr1OV9FyZQLWXsayOJyV4tnRyXR85/ag==" + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.21.0.tgz", + "integrity": "sha512-YUdI3fFu4TF/2WykQ2xzSiTQdldLB4KVuL9WeAy5XONZYt5Cun/fpQvctoKbCgvPhmzADeesTk/j2Rdx77AcKQ==" }, "core-js-compat": { - "version": "3.20.3", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.20.3.tgz", - "integrity": "sha512-c8M5h0IkNZ+I92QhIpuSijOxGAcj3lgpsWdkCqmUTZNwidujF4r3pi6x1DCN+Vcs5qTS2XWWMfWSuCqyupX8gw==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.21.0.tgz", + "integrity": "sha512-OSXseNPSK2OPJa6GdtkMz/XxeXx8/CJvfhQWTqd6neuUraujcL4jVsjkLQz1OWnax8xVQJnRPe0V2jqNWORA+A==", "dev": true, "requires": { "browserslist": "^4.19.1", @@ -17895,21 +17686,21 @@ } }, "css-blank-pseudo": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.2.tgz", - "integrity": "sha512-hOb1LFjRR+8ocA071xUSmg5VslJ8NGo/I2qpUpdeAYyBVCgupS5O8SEVo4SxEMYyFBNodBkzG3T1iqW9HCXxew==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz", + "integrity": "sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ==", "dev": true, "requires": { - "postcss-selector-parser": "^6.0.8" + "postcss-selector-parser": "^6.0.9" } }, "css-has-pseudo": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.3.tgz", - "integrity": "sha512-0gDYWEKaGacwxCqvQ3Ypg6wGdD1AztbMm5h1JsactG2hP2eiflj808QITmuWBpE7sjSEVrAlZhPTVd/nNMj/hQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz", + "integrity": "sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==", "dev": true, "requires": { - "postcss-selector-parser": "^6.0.8" + "postcss-selector-parser": "^6.0.9" } }, "css-loader": { @@ -17929,9 +17720,9 @@ } }, "css-prefers-color-scheme": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.2.tgz", - "integrity": "sha512-gv0KQBEM+q/XdoKyznovq3KW7ocO7k+FhPP+hQR1MenJdu0uPGS6IZa9PzlbqBeS6XcZJNAoqoFxlAUW461CrA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", + "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==", "dev": true, "requires": {} }, @@ -18284,9 +18075,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.4.57", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.57.tgz", - "integrity": "sha512-FNC+P5K1n6pF+M0zIK+gFCoXcJhhzDViL3DRIGy2Fv5PohuSES1JHR7T+GlwxSxlzx4yYbsuzCZvHxcBSRCIOw==", + "version": "1.4.71", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.71.tgz", + "integrity": "sha512-Hk61vXXKRb2cd3znPE9F+2pLWdIOmP7GjiTj45y6L3W/lO+hSnUSUhq+6lEaERWBdZOHbk2s3YV5c9xVl3boVw==", "dev": true }, "elementtree": { @@ -18352,9 +18143,9 @@ } }, "enhanced-resolve": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", - "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.0.tgz", + "integrity": "sha512-weDYmzbBygL7HzGGS26M3hGQx68vehdEg6VUmqSOaFzXExFqlnKuSvsEJCVGQHScS8CQMbrAqftT+AzzHNt/YA==", "dev": true, "requires": { "graceful-fs": "^4.2.4", @@ -18922,9 +18713,9 @@ } }, "follow-redirects": { - "version": "1.14.7", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz", - "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==", + "version": "1.14.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz", + "integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==", "dev": true }, "form-data": { @@ -18951,9 +18742,9 @@ "dev": true }, "fraction.js": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.1.2.tgz", - "integrity": "sha512-o2RiJQ6DZaR/5+Si0qJUIy637QMRudSi9kU/FFzx9EZazrIdnBgpU+3sEWCxAVhH2RtxW2Oz+T4p2o8uOPVcgA==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.1.3.tgz", + "integrity": "sha512-pUHWWt6vHzZZiQJcM6S/0PXfS+g6FM4BF5rj9wZyreivhQPdsh5PpE25VtSNxq80wHS5RfY51Ii+8Z0Zl/pmzg==", "dev": true }, "fresh": { @@ -19386,9 +19177,9 @@ } }, "http-proxy-middleware": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.2.tgz", - "integrity": "sha512-XtmDN5w+vdFTBZaYhdJAbMqn0DP/EhkUaAeo963mojwpKMMbw6nivtFKw07D7DDOH745L5k0VL0P8KRYNEVF/g==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.3.tgz", + "integrity": "sha512-1bloEwnrHMnCoO/Gcwbz7eSVvW50KPES01PecpagI+YLNLci4AcuKJrujW4Mc3sBLpFxMSlsLNHS5Nl/lvrTPA==", "dev": true, "requires": { "@types/http-proxy": "^1.17.8", @@ -19728,9 +19519,9 @@ "dev": true }, "rxjs": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.2.tgz", - "integrity": "sha512-PwDt186XaL3QN5qXj/H9DGyHhP3/RYYgZZwqBv9Tv8rsAaiwFH1IsJJlcgD37J7UW5a6O67qX0KWKS3/pu0m4w==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.4.tgz", + "integrity": "sha512-h5M3Hk78r6wAheJF0a5YahB1yRQKCsZ4MsGdZ5O9ETbVtjPcScGfrMmoOq7EBsCRzd4BDkvDJ7ogP8Sz5tTFiQ==", "dev": true, "requires": { "tslib": "^2.1.0" @@ -19753,6 +19544,13 @@ "integrity": "sha512-xQekOJsxH82O7oB+3F60zeRggCdND9pJ/k0E6IJDVUGGlCj5mlyFqNgxUimytKgstPGv3S+3EmCxjefvtGgWUg==", "requires": { "@stencil/core": "~2.12.0" + }, + "dependencies": { + "@stencil/core": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-2.12.1.tgz", + "integrity": "sha512-u24TZ+FEvjnZt5ZgIkLjLpUNsO6Ml3mUZqwmqk81w6RWWz75hgB5p4RFI5rvuErFeh2xvMIGo+pNdG24XUBz1A==" + } } }, "ip": { @@ -19976,9 +19774,9 @@ } }, "jest-worker": { - "version": "27.4.6", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.6.tgz", - "integrity": "sha512-gHWJF/6Xi5CTG5QCvROr6GcmpIqNYpDJyc8A1h/DyXqH1tD6SnRCM0d3U5msV31D2LB/U+E0M+W4oyvKV44oNw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, "requires": { "@types/node": "*", @@ -20191,9 +19989,9 @@ } }, "license-webpack-plugin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.0.tgz", - "integrity": "sha512-b9iMrROrw2fTOJBZ57h0xJfT5/1Cxg4ucYbtpWoukv4Awb2TFPfDDFVHNM8w6SYQpVfB13a5tQJxgGamqwrsyw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.1.tgz", + "integrity": "sha512-SQum9mg3BgnY5BK+2KYl4W7pk9b26Q8tW2lTsO6tidD0/Ds9ksdXvp3ip2s9LqDjj5gtBMyWRfOPZptWj4PfCg==", "dev": true, "requires": { "webpack-sources": "^3.0.0" @@ -20220,9 +20018,9 @@ "dev": true }, "lint-staged": { - "version": "12.3.2", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-12.3.2.tgz", - "integrity": "sha512-gtw4Cbj01SuVSfAOXC6ivd/7VKHTj51yj5xV8TgktFmYNMsZzXuSd5/brqJEA93v63wL7R6iDlunMANOechC0A==", + "version": "12.3.4", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-12.3.4.tgz", + "integrity": "sha512-yv/iK4WwZ7/v0GtVkNb3R82pdL9M+ScpIbJLJNyCXkJ1FGaXvRCOg/SeL59SZtPpqZhE7BD6kPKFLIDUhDx2/w==", "dev": true, "requires": { "cli-truncate": "^3.1.0", @@ -20240,12 +20038,6 @@ "yaml": "^1.10.2" }, "dependencies": { - "colorette": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", - "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", - "dev": true - }, "supports-color": { "version": "9.2.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.2.1.tgz", @@ -20255,9 +20047,9 @@ } }, "listr2": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.1.tgz", - "integrity": "sha512-D65Nl+zyYHL2jQBGmxtH/pU8koPZo5C8iCNE8EoB04RwPgQG1wuaKwVbeZv9LJpiH4Nxs0FCp+nNcG8OqpniiA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.4.tgz", + "integrity": "sha512-vJOm5KD6uZXjSsrwajr+mNacIjf87gWvlBEltPWLbTkslUscWAzquyK4xfe9Zd4RDgO5nnwFyV06FC+uVR+5mg==", "dev": true, "requires": { "cli-truncate": "^2.1.0", @@ -20265,7 +20057,7 @@ "log-update": "^4.0.0", "p-map": "^4.0.0", "rfdc": "^1.3.0", - "rxjs": "^7.5.2", + "rxjs": "^7.5.4", "through": "^2.3.8", "wrap-ansi": "^7.0.0" }, @@ -20304,16 +20096,10 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "colorette": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", - "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", - "dev": true - }, "rxjs": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.2.tgz", - "integrity": "sha512-PwDt186XaL3QN5qXj/H9DGyHhP3/RYYgZZwqBv9Tv8rsAaiwFH1IsJJlcgD37J7UW5a6O67qX0KWKS3/pu0m4w==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.4.tgz", + "integrity": "sha512-h5M3Hk78r6wAheJF0a5YahB1yRQKCsZ4MsGdZ5O9ETbVtjPcScGfrMmoOq7EBsCRzd4BDkvDJ7ogP8Sz5tTFiQ==", "dev": true, "requires": { "tslib": "^2.1.0" @@ -20739,9 +20525,9 @@ }, "dependencies": { "ajv": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", - "integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz", + "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -20750,15 +20536,6 @@ "uri-js": "^4.2.2" } }, - "ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "requires": { - "ajv": "^8.0.0" - } - }, "ajv-keywords": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", @@ -20893,9 +20670,9 @@ "dev": true }, "monaco-editor": { - "version": "0.32.0", - "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.32.0.tgz", - "integrity": "sha512-r3xvo6XMA/fg3SuVJb+NMxf+fXHO8GPIOLoPFRO2LIf7GbqfV9W7FdddqT9ze+bCtnLd+s4IScnOGCgDQDg4BQ==" + "version": "0.32.1", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.32.1.tgz", + "integrity": "sha512-LUt2wsUvQmEi2tfTOK+tjAPvt7eQ+K5C4rZPr6SeuyzjAuAHrIvlUloTcOiGjZW3fn3a/jFQCONrEJbNOaCqbA==" }, "ms": { "version": "2.1.2", @@ -20931,9 +20708,9 @@ "dev": true }, "nanoid": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", - "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.0.tgz", + "integrity": "sha512-JzxqqT5u/x+/KOFSd7JP15DOo9nOoHpx6DYatqIHUW2+flybkm+mdcraotSQR5WcnZr+qhGVh8Ted0KdfSMxlg==", "dev": true }, "needle": { @@ -20986,9 +20763,9 @@ "dev": true }, "ng-packagr": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/ng-packagr/-/ng-packagr-13.2.0.tgz", - "integrity": "sha512-qfAipG1jQLjQ0+NXUTYyCmi5xSdMYY3LUWc7iXrbPfl8R2b8fLO+abW1zNMxS6TtcBUZMyfYtz2NGcFrh7QteA==", + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/ng-packagr/-/ng-packagr-13.2.1.tgz", + "integrity": "sha512-N0eiTTj5yxOBO7NX8kv+UV08bdLJOBG/ABZkaod9uAwflT6qZG1etX4DHnpfy1I591AZtAJNOnAwdRVoaBIDwQ==", "dev": true, "requires": { "@rollup/plugin-json": "^4.1.0", @@ -21019,9 +20796,9 @@ }, "dependencies": { "ajv": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", - "integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz", + "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -21047,9 +20824,9 @@ } }, "rxjs": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.2.tgz", - "integrity": "sha512-PwDt186XaL3QN5qXj/H9DGyHhP3/RYYgZZwqBv9Tv8rsAaiwFH1IsJJlcgD37J7UW5a6O67qX0KWKS3/pu0m4w==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.4.tgz", + "integrity": "sha512-h5M3Hk78r6wAheJF0a5YahB1yRQKCsZ4MsGdZ5O9ETbVtjPcScGfrMmoOq7EBsCRzd4BDkvDJ7ogP8Sz5tTFiQ==", "dev": true, "requires": { "tslib": "^2.1.0" @@ -21126,9 +20903,9 @@ } }, "node-releases": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", - "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", + "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", "dev": true }, "nopt": { @@ -21212,17 +20989,17 @@ } }, "npm-registry-fetch": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-12.0.1.tgz", - "integrity": "sha512-ricy4ezH3Uv0d4am6RSwHjCYTWJI74NJjurIigWMAG7Vs3PFyd0TUlkrez5L0AgaPzDLRsEzqb5cOZ/Ue01bmA==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-12.0.2.tgz", + "integrity": "sha512-Df5QT3RaJnXYuOwtXBXS9BWs+tHH2olvkCLh6jcR/b/u3DvPMlp3J0TvvYwplPKxHMOwfg287PYih9QqaVFoKA==", "dev": true, "requires": { - "make-fetch-happen": "^10.0.0", - "minipass": "^3.1.3", - "minipass-fetch": "^1.3.0", + "make-fetch-happen": "^10.0.1", + "minipass": "^3.1.6", + "minipass-fetch": "^1.4.1", "minipass-json-stream": "^1.0.1", - "minizlib": "^2.0.0", - "npm-package-arg": "^8.0.0" + "minizlib": "^2.1.2", + "npm-package-arg": "^8.1.5" }, "dependencies": { "@tootallnate/once": { @@ -21242,28 +21019,34 @@ "debug": "4" } }, + "lru-cache": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.3.1.tgz", + "integrity": "sha512-nX1x4qUrKqwbIAhv4s9et4FIUVzNOpeY07bsjGUy8gwJrXH/wScImSQqXErmo/b2jZY2r0mohbLA9zVj7u1cNw==", + "dev": true + }, "make-fetch-happen": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.0.0.tgz", - "integrity": "sha512-CREcDkbKZZ64g5MN1FT+u58mDHX9FQFFtFyio5HonX44BdQdytqPZBXUz+6ibi2w/6ncji59f2phyXGSMGpgzA==", + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.0.2.tgz", + "integrity": "sha512-JSFLK53NJP22FL/eAGOyKsWbc2G3v+toPMD7Dq9PJKQCvK0i3t8hGkKxe+3YZzwYa+c0kxRHu7uxH3fvO+rsaA==", "dev": true, "requires": { - "agentkeepalive": "^4.1.3", - "cacache": "^15.2.0", + "agentkeepalive": "^4.2.0", + "cacache": "^15.3.0", "http-cache-semantics": "^4.1.0", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", "is-lambda": "^1.0.1", - "lru-cache": "^6.0.0", - "minipass": "^3.1.3", + "lru-cache": "^7.3.1", + "minipass": "^3.1.6", "minipass-collect": "^1.0.2", - "minipass-fetch": "^1.3.2", + "minipass-fetch": "^1.4.1", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^0.6.3", "promise-retry": "^2.0.1", - "socks-proxy-agent": "^6.0.0", - "ssri": "^8.0.0" + "socks-proxy-agent": "^6.1.1", + "ssri": "^8.0.1" } } } @@ -21278,12 +21061,12 @@ } }, "npmlog": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.0.tgz", - "integrity": "sha512-03ppFRGlsyUaQFbGC2C8QWJN/C/K7PsfyD9aQdhVKAQIH4sQBc8WASqFBP7O+Ut4d2oo5LoeoboB3cGdBZSp6Q==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.1.tgz", + "integrity": "sha512-BTHDvY6nrRHuRfyjt1MAufLxYdVXZfd099H4+i1f0lPywNQyI4foeNXJRObB/uy+TYqUW0vAD9gbdSOXPst7Eg==", "dev": true, "requires": { - "are-we-there-yet": "^2.0.0", + "are-we-there-yet": "^3.0.0", "console-control-strings": "^1.1.0", "gauge": "^4.0.0", "set-blocking": "^2.0.0" @@ -21840,18 +21623,18 @@ } }, "postcss-color-functional-notation": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.1.tgz", - "integrity": "sha512-62OBIXCjRXpQZcFOYIXwXBlpAVWrYk8ek1rcjvMING4Q2cf0ipyN9qT+BhHA6HmftGSEnFQu2qgKO3gMscl3Rw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.2.tgz", + "integrity": "sha512-DXVtwUhIk4f49KK5EGuEdgx4Gnyj6+t2jBSEmxvpIK9QI40tWrpS2Pua8Q7iIZWBrki2QOaeUdEaLPPa91K0RQ==", "dev": true, "requires": { "postcss-value-parser": "^4.2.0" } }, "postcss-color-hex-alpha": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.2.tgz", - "integrity": "sha512-gyx8RgqSmGVK156NAdKcsfkY3KPGHhKqvHTL3hhveFrBBToguKFzhyiuk3cljH6L4fJ0Kv+JENuPXs1Wij27Zw==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.3.tgz", + "integrity": "sha512-fESawWJCrBV035DcbKRPAVmy21LpoyiXdPTuHUfWJ14ZRjY7Y7PA6P4g8z6LQGYhU1WAxkTxjIjurXzoe68Glw==", "dev": true, "requires": { "postcss-value-parser": "^4.2.0" @@ -21874,9 +21657,9 @@ "requires": {} }, "postcss-custom-properties": { - "version": "12.1.3", - "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.3.tgz", - "integrity": "sha512-rtu3otIeY532PnEuuBrIIe+N+pcdbX/7JMZfrcL09wc78YayrHw5E8UkDfvnlOhEUrI4ptCuzXQfj+Or6spbGA==", + "version": "12.1.4", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.4.tgz", + "integrity": "sha512-i6AytuTCoDLJkWN/MtAIGriJz3j7UX6bV7Z5t+KgFz+dwZS15/mlTJY1S0kRizlk6ba0V8u8hN50Fz5Nm7tdZw==", "dev": true, "requires": { "postcss-value-parser": "^4.2.0" @@ -21892,48 +21675,48 @@ } }, "postcss-dir-pseudo-class": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.3.tgz", - "integrity": "sha512-qiPm+CNAlgXiMf0J5IbBBEXA9l/Q5HGsNGkL3znIwT2ZFRLGY9U2fTUpa4lqCUXQOxaLimpacHeQC80BD2qbDw==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.4.tgz", + "integrity": "sha512-I8epwGy5ftdzNWEYok9VjW9whC4xnelAtbajGv4adql4FIF09rnrxnA9Y8xSHN47y7gqFIv10C5+ImsLeJpKBw==", "dev": true, "requires": { - "postcss-selector-parser": "^6.0.8" + "postcss-selector-parser": "^6.0.9" } }, "postcss-double-position-gradients": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.0.4.tgz", - "integrity": "sha512-qz+s5vhKJlsHw8HjSs+HVk2QGFdRyC68KGRQGX3i+GcnUjhWhXQEmCXW6siOJkZ1giu0ddPwSO6I6JdVVVPoog==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.0.5.tgz", + "integrity": "sha512-XiZzvdxLOWZwtt/1GgHJYGoD9scog/DD/yI5dcvPrXNdNDEv7T53/6tL7ikl+EM3jcerII5/XIQzd1UHOdTi2w==", "dev": true, "requires": { "postcss-value-parser": "^4.2.0" } }, "postcss-env-function": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.4.tgz", - "integrity": "sha512-0ltahRTPtXSIlEZFv7zIvdEib7HN0ZbUQxrxIKn8KbiRyhALo854I/CggU5lyZe6ZBvSTJ6Al2vkZecI2OhneQ==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.5.tgz", + "integrity": "sha512-gPUJc71ji9XKyl0WSzAalBeEA/89kU+XpffpPxSaaaZ1c48OL36r1Ep5R6+9XAPkIiDlSvVAwP4io12q/vTcvA==", "dev": true, "requires": { "postcss-value-parser": "^4.2.0" } }, "postcss-focus-visible": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.3.tgz", - "integrity": "sha512-ozOsg+L1U8S+rxSHnJJiET6dNLyADcPHhEarhhtCI9DBLGOPG/2i4ddVoFch9LzrBgb8uDaaRI4nuid2OM82ZA==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz", + "integrity": "sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==", "dev": true, "requires": { - "postcss-selector-parser": "^6.0.8" + "postcss-selector-parser": "^6.0.9" } }, "postcss-focus-within": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.3.tgz", - "integrity": "sha512-fk9y2uFS6/Kpp7/A9Hz9Z4rlFQ8+tzgBcQCXAFSrXFGAbKx+4ZZOmmfHuYjCOMegPWoz0pnC6fNzi8j7Xyqp5Q==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz", + "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==", "dev": true, "requires": { - "postcss-selector-parser": "^6.0.8" + "postcss-selector-parser": "^6.0.9" } }, "postcss-font-variant": { @@ -21944,16 +21727,16 @@ "requires": {} }, "postcss-gap-properties": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.2.tgz", - "integrity": "sha512-EaMy/pbxtQnKDsnbEjdqlkCkROTQZzolcLKgIE+3b7EuJfJydH55cZeHfm+MtIezXRqhR80VKgaztO/vHq94Fw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.3.tgz", + "integrity": "sha512-rPPZRLPmEKgLk/KlXMqRaNkYTUpE7YC+bOIQFN5xcu1Vp11Y4faIXv6/Jpft6FMnl6YRxZqDZG0qQOW80stzxQ==", "dev": true, "requires": {} }, "postcss-image-set-function": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.4.tgz", - "integrity": "sha512-BlEo9gSTj66lXjRNByvkMK9dEdEGFXRfGjKRi9fo8s0/P3oEk74cAoonl/utiM50E2OPVb/XSu+lWvdW4KtE/Q==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.6.tgz", + "integrity": "sha512-KfdC6vg53GC+vPd2+HYzsZ6obmPqOk6HY09kttU19+Gj1nC3S3XBVEXDHxkhxTohgZqzbUb94bKXvKDnYWBm/A==", "dev": true, "requires": { "postcss-value-parser": "^4.2.0" @@ -21978,11 +21761,12 @@ "requires": {} }, "postcss-lab-function": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.0.3.tgz", - "integrity": "sha512-MH4tymWmefdZQ7uVG/4icfLjAQmH6o2NRYyVh2mKoB4RXJp9PjsyhZwhH4ouaCQHvg+qJVj3RzeAR1EQpIlXZA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.1.0.tgz", + "integrity": "sha512-59uHN/2wRaOd7whDyeaJ82E0kncIEeJkwcmvXFPNus8v1YMhtv2IUo9OtOAncn7sifZVMRsyoPlhxwckTjn4cQ==", "dev": true, "requires": { + "@csstools/postcss-progressive-custom-properties": "^1.1.0", "postcss-value-parser": "^4.2.0" } }, @@ -21998,9 +21782,9 @@ } }, "postcss-logical": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.3.tgz", - "integrity": "sha512-P5NcHWYrif0vK8rgOy/T87vg0WRIj3HSknrvp1wzDbiBeoDPVmiVRmkown2eSQdpPveat/MC1ess5uhzZFVnqQ==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz", + "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==", "dev": true, "requires": {} }, @@ -22057,9 +21841,9 @@ } }, "postcss-overflow-shorthand": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.2.tgz", - "integrity": "sha512-odBMVt6PTX7jOE9UNvmnLrFzA9pXS44Jd5shFGGtSHY80QCuJF+14McSy0iavZggRZ9Oj//C9vOKQmexvyEJMg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.3.tgz", + "integrity": "sha512-CxZwoWup9KXzQeeIxtgOciQ00tDtnylYIlJBBODqkgS/PU2jISuWOL/mYLHmZb9ZhZiCaNKsCRiLp22dZUtNsg==", "dev": true, "requires": {} }, @@ -22071,9 +21855,9 @@ "requires": {} }, "postcss-place": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.3.tgz", - "integrity": "sha512-tDQ3m+GYoOar+KoQgj+pwPAvGHAp/Sby6vrFiyrELrMKQJ4AejL0NcS0mm296OKKYA2SRg9ism/hlT/OLhBrdQ==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.4.tgz", + "integrity": "sha512-MrgKeiiu5OC/TETQO45kV3npRjOFxEHthsqGtkh3I1rPbZSbXGD/lZVi9j13cYh+NA8PIAPyk6sGjT9QbRyvSg==", "dev": true, "requires": { "postcss-value-parser": "^4.2.0" @@ -22121,12 +21905,12 @@ } }, "postcss-pseudo-class-any-link": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.0.2.tgz", - "integrity": "sha512-CG35J1COUH7OOBgpw5O+0koOLUd5N4vUGKUqSAuIe4GiuLHWU96Pqp+UPC8QITTd12zYAFx76pV7qWT/0Aj/TA==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.1.tgz", + "integrity": "sha512-JRoLFvPEX/1YTPxRxp1JO4WxBVXJYrSY7NHeak5LImwJ+VobFMwYDQHvfTXEpcn+7fYIeGkC29zYFhFWIZD8fg==", "dev": true, "requires": { - "postcss-selector-parser": "^6.0.8" + "postcss-selector-parser": "^6.0.9" } }, "postcss-replace-overflow-wrap": { @@ -22428,12 +22212,12 @@ "dev": true }, "raw-body": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", - "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", + "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", "dev": true, "requires": { - "bytes": "3.1.1", + "bytes": "3.1.2", "http-errors": "1.8.1", "iconv-lite": "0.4.24", "unpipe": "1.0.0" @@ -22524,9 +22308,9 @@ "dev": true }, "regenerate-unicode-properties": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz", - "integrity": "sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz", + "integrity": "sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw==", "dev": true, "requires": { "regenerate": "^1.4.2" @@ -22564,29 +22348,29 @@ } }, "regexpu-core": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.8.0.tgz", - "integrity": "sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.0.1.tgz", + "integrity": "sha512-CriEZlrKK9VJw/xQGJpQM5rY88BtuL8DM+AEwvcThHilbxiTAy8vq4iJnd2tqq8wLmjbGZzP7ZcKFjbGkmEFrw==", "dev": true, "requires": { "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^9.0.0", - "regjsgen": "^0.5.2", - "regjsparser": "^0.7.0", + "regenerate-unicode-properties": "^10.0.1", + "regjsgen": "^0.6.0", + "regjsparser": "^0.8.2", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.0.0" } }, "regjsgen": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", - "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.6.0.tgz", + "integrity": "sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA==", "dev": true }, "regjsparser": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.7.0.tgz", - "integrity": "sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==", + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.8.4.tgz", + "integrity": "sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA==", "dev": true, "requires": { "jsesc": "~0.5.0" @@ -22718,9 +22502,9 @@ } }, "rollup": { - "version": "2.66.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.66.1.tgz", - "integrity": "sha512-crSgLhSkLMnKr4s9iZ/1qJCplgAgrRY+igWv8KhG/AjKOJ0YX/WpmANyn8oxrw+zenF3BXWDLa7Xl/QZISH+7w==", + "version": "2.67.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.67.2.tgz", + "integrity": "sha512-hoEiBWwZtf1QdK3jZIq59L0FJj4Fiv4RplCO4pvCRC86qsoFurWB4hKQIjoRf3WvJmk5UZ9b0y5ton+62fC7Tw==", "dev": true, "requires": { "fsevents": "~2.3.2" @@ -23026,9 +22810,9 @@ } }, "signal-exit": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", - "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, "slash": { @@ -23092,13 +22876,13 @@ } }, "socks": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.1.tgz", - "integrity": "sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz", + "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==", "dev": true, "requires": { "ip": "^1.1.5", - "smart-buffer": "^4.1.0" + "smart-buffer": "^4.2.0" } }, "socks-proxy-agent": { @@ -23455,12 +23239,12 @@ } }, "terser-webpack-plugin": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.0.tgz", - "integrity": "sha512-LPIisi3Ol4chwAaPP8toUJ3L4qCM1G0wao7L3qNv57Drezxj6+VEyySpPw4B1HSO2Eg/hDY/MNF5XihCAoqnsQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.1.tgz", + "integrity": "sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g==", "dev": true, "requires": { - "jest-worker": "^27.4.1", + "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", "serialize-javascript": "^6.0.0", "source-map": "^0.6.1", @@ -23552,9 +23336,9 @@ "dev": true }, "ts-node": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", - "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.5.0.tgz", + "integrity": "sha512-6kEJKwVxAJ35W4akuiysfKwKmjkbYxwQMTBaAxo9KKAx/Yd26mPUyhGz3ji+EsJoAgrLqVsYHNuuYwQe22lbtw==", "dev": true, "requires": { "@cspotcode/source-map-support": "0.7.0", @@ -23568,6 +23352,7 @@ "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.0", "yn": "3.1.1" } }, @@ -23802,6 +23587,12 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, + "v8-compile-cache-lib": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", + "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==", + "dev": true + }, "validate-npm-package-name": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", @@ -23818,10 +23609,14 @@ "dev": true }, "vm2": { - "version": "3.9.5", - "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.5.tgz", - "integrity": "sha512-LuCAHZN75H9tdrAiLFf030oW7nJV5xwNMuk1ymOZwopmuK3d2H4L1Kv4+GFHgarKiLfXXLFU+7LDABHnwOkWng==", - "dev": true + "version": "3.9.7", + "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.7.tgz", + "integrity": "sha512-g/GZ7V0Mlmch3eDVOATvAXr1GsJNg6kQ5PjvYy3HbJMCRn5slNbo/u73Uy7r5yUej1cRa3ZjtoVwcWSQuQ/fow==", + "dev": true, + "requires": { + "acorn": "^8.7.0", + "acorn-walk": "^8.2.0" + } }, "watchpack": { "version": "2.3.1", @@ -23852,13 +23647,14 @@ } }, "webpack": { - "version": "5.67.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.67.0.tgz", - "integrity": "sha512-LjFbfMh89xBDpUMgA1W9Ur6Rn/gnr2Cq1jjHFPo4v6a79/ypznSYbAyPgGhwsxBtMIaEmDD1oJoA7BEYw/Fbrw==", + "version": "5.69.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.69.0.tgz", + "integrity": "sha512-E5Fqu89Gu8fR6vejRqu26h8ld/k6/dCVbeGUcuZjc+goQHDfCPU9rER71JmdtBYGmci7Ec2aFEATQ2IVXKy2wg==", "dev": true, + "peer": true, "requires": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.50", + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^0.0.51", "@webassemblyjs/ast": "1.11.1", "@webassemblyjs/wasm-edit": "1.11.1", "@webassemblyjs/wasm-parser": "1.11.1", @@ -23866,7 +23662,7 @@ "acorn-import-assertions": "^1.7.6", "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.3", + "enhanced-resolve": "^5.9.0", "es-module-lexer": "^0.9.0", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -23883,11 +23679,19 @@ "webpack-sources": "^3.2.3" }, "dependencies": { + "@types/estree": { + "version": "0.0.51", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", + "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", + "dev": true, + "peer": true + }, "schema-utils": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", "dev": true, + "peer": true, "requires": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -23910,9 +23714,9 @@ }, "dependencies": { "ajv": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", - "integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz", + "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -23921,15 +23725,6 @@ "uri-js": "^4.2.2" } }, - "ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "requires": { - "ajv": "^8.0.0" - } - }, "ajv-keywords": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", @@ -23939,12 +23734,6 @@ "fast-deep-equal": "^3.1.3" } }, - "colorette": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", - "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", - "dev": true - }, "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -24003,9 +23792,9 @@ }, "dependencies": { "ajv": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.9.0.tgz", - "integrity": "sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz", + "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -24014,15 +23803,6 @@ "uri-js": "^4.2.2" } }, - "ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "requires": { - "ajv": "^8.0.0" - } - }, "ajv-keywords": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", @@ -24038,12 +23818,6 @@ "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true }, - "colorette": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", - "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", - "dev": true - }, "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -24070,13 +23844,6 @@ "requires": { "ansi-regex": "^6.0.1" } - }, - "ws": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.4.2.tgz", - "integrity": "sha512-Kbk4Nxyq7/ZWqr/tarI9yIt/+iNNFOjBXEWgTb4ydaNHBNGgvf2QHbS9fdfsndfjFlFwEd4Al+mw83YkaD10ZA==", - "dev": true, - "requires": {} } } }, @@ -24261,6 +24028,13 @@ "typedarray-to-buffer": "^3.1.5" } }, + "ws": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", + "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "dev": true, + "requires": {} + }, "xregexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index f272dfb05..5c3d2daf3 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -6,7 +6,7 @@ "scripts": { "ng": "ng", "check": "npm run check:shared && npm run check:ui && npm run check:setup-wizard && npm run check:diagnostic-ui", - "check:shared": "tsc --project projects/shared/tsconfig.lib.json --noEmit --skipLibCheck", + "check:shared": "tsc --project projects/shared/tsconfig.json --noEmit --skipLibCheck", "check:diagnostic-ui": "tsc --project projects/diagnostic-ui/tsconfig.json --noEmit --skipLibCheck", "check:setup-wizard": "tsc --project projects/setup-wizard/tsconfig.json --noEmit --skipLibCheck", "check:ui": "tsc --project projects/ui/tsconfig.json --noEmit --skipLibCheck", diff --git a/frontend/projects/diagnostic-ui/src/app/app.module.ts b/frontend/projects/diagnostic-ui/src/app/app.module.ts index ca131a84a..53a13cc74 100644 --- a/frontend/projects/diagnostic-ui/src/app/app.module.ts +++ b/frontend/projects/diagnostic-ui/src/app/app.module.ts @@ -10,7 +10,7 @@ import { MockApiService } from './services/api/mock-api.service' import { LiveApiService } from './services/api/live-api.service' import { HttpService } from './services/http.service' import { GlobalErrorHandler } from './services/global-error-handler.service' -import { WorkspaceConfig } from '@shared' +import { WorkspaceConfig } from '@start9labs/shared' const { useMocks } = require('../../../../config.json') as WorkspaceConfig diff --git a/frontend/projects/diagnostic-ui/src/app/services/api/mock-api.service.ts b/frontend/projects/diagnostic-ui/src/app/services/api/mock-api.service.ts index f7b3efd6d..959a2493d 100644 --- a/frontend/projects/diagnostic-ui/src/app/services/api/mock-api.service.ts +++ b/frontend/projects/diagnostic-ui/src/app/services/api/mock-api.service.ts @@ -1,39 +1,50 @@ -import { Injectable } from "@angular/core" -import { pauseFor } from "../../util/misc.util" -import { ApiService, GetErrorRes, GetLogsReq, GetLogsRes, Log } from "./api.service" +import { Injectable } from '@angular/core' +import { pauseFor } from '@start9labs/shared' +import { + ApiService, + GetErrorRes, + GetLogsReq, + GetLogsRes, + Log, +} from './api.service' @Injectable() export class MockApiService extends ApiService { + constructor() { + super() + } - constructor () { super() } - - async getError (): Promise { + async getError(): Promise { await pauseFor(1000) return { code: 15, message: 'Unknown Embassy', - data: { details: 'Some details about the error here' } + data: { details: 'Some details about the error here' }, } } - async restart (): Promise { + async restart(): Promise { await pauseFor(1000) return null } - async forgetDrive (): Promise { + async forgetDrive(): Promise { await pauseFor(1000) return null } - async getLogs (params: GetLogsReq): Promise { + async getLogs(params: GetLogsReq): Promise { await pauseFor(1000) let entries: Log[] - if (Math.random() < .2) { + if (Math.random() < 0.2) { entries = packageLogs } else { - const arrLength = params.limit ? Math.ceil(params.limit / packageLogs.length) : 10 - entries = new Array(arrLength).fill(packageLogs).reduce((acc, val) => acc.concat(val), []) + const arrLength = params.limit + ? Math.ceil(params.limit / packageLogs.length) + : 10 + entries = new Array(arrLength) + .fill(packageLogs) + .reduce((acc, val) => acc.concat(val), []) } return { entries, @@ -56,4 +67,4 @@ const packageLogs = [ timestamp: '2019-12-26T14:22:30.872Z', message: '****** FINISH *****', }, -] \ No newline at end of file +] diff --git a/frontend/projects/diagnostic-ui/src/app/util/misc.util.ts b/frontend/projects/diagnostic-ui/src/app/util/misc.util.ts deleted file mode 100644 index f898a9339..000000000 --- a/frontend/projects/diagnostic-ui/src/app/util/misc.util.ts +++ /dev/null @@ -1,3 +0,0 @@ -export function pauseFor (ms: number): Promise { - return new Promise(resolve => setTimeout(resolve, ms)) -} \ No newline at end of file diff --git a/frontend/projects/setup-wizard/src/app/app.module.ts b/frontend/projects/setup-wizard/src/app/app.module.ts index fed9d0f6c..fef910d76 100644 --- a/frontend/projects/setup-wizard/src/app/app.module.ts +++ b/frontend/projects/setup-wizard/src/app/app.module.ts @@ -21,7 +21,7 @@ import { LoadingPageModule } from './pages/loading/loading.module' import { ProdKeyModalModule } from './modals/prod-key-modal/prod-key-modal.module' import { ProductKeyPageModule } from './pages/product-key/product-key.module' import { RecoverPageModule } from './pages/recover/recover.module' -import { WorkspaceConfig } from '@shared' +import { WorkspaceConfig } from '@start9labs/shared' const { useMocks } = require('../../../../config.json') as WorkspaceConfig diff --git a/frontend/projects/setup-wizard/src/app/pages/embassy/embassy.module.ts b/frontend/projects/setup-wizard/src/app/pages/embassy/embassy.module.ts index 45c3e2ead..a49e06c9c 100644 --- a/frontend/projects/setup-wizard/src/app/pages/embassy/embassy.module.ts +++ b/frontend/projects/setup-wizard/src/app/pages/embassy/embassy.module.ts @@ -2,10 +2,10 @@ import { NgModule } from '@angular/core' import { CommonModule } from '@angular/common' import { IonicModule } from '@ionic/angular' import { FormsModule } from '@angular/forms' +import { UnitConversionPipesModule } from '@start9labs/shared' import { EmbassyPage } from './embassy.page' import { PasswordPageModule } from '../../modals/password/password.module' import { EmbassyPageRoutingModule } from './embassy-routing.module' -import { PipesModule } from 'src/app/pipes/pipe.module' @NgModule({ imports: [ @@ -14,8 +14,8 @@ import { PipesModule } from 'src/app/pipes/pipe.module' IonicModule, EmbassyPageRoutingModule, PasswordPageModule, - PipesModule, + UnitConversionPipesModule, ], declarations: [EmbassyPage], }) -export class EmbassyPageModule { } +export class EmbassyPageModule {} diff --git a/frontend/projects/setup-wizard/src/app/pages/recover/recover.module.ts b/frontend/projects/setup-wizard/src/app/pages/recover/recover.module.ts index a1f46afd8..eee8c35d1 100644 --- a/frontend/projects/setup-wizard/src/app/pages/recover/recover.module.ts +++ b/frontend/projects/setup-wizard/src/app/pages/recover/recover.module.ts @@ -2,11 +2,11 @@ import { NgModule } from '@angular/core' import { CommonModule } from '@angular/common' import { IonicModule } from '@ionic/angular' import { FormsModule } from '@angular/forms' +import { UnitConversionPipesModule } from '@start9labs/shared' import { DriveStatusComponent, RecoverPage } from './recover.page' import { PasswordPageModule } from '../../modals/password/password.module' import { ProdKeyModalModule } from '../../modals/prod-key-modal/prod-key-modal.module' import { RecoverPageRoutingModule } from './recover-routing.module' -import { PipesModule } from 'src/app/pipes/pipe.module' import { CifsModalModule } from 'src/app/modals/cifs-modal/cifs-modal.module' @NgModule({ @@ -18,8 +18,8 @@ import { CifsModalModule } from 'src/app/modals/cifs-modal/cifs-modal.module' RecoverPageRoutingModule, PasswordPageModule, ProdKeyModalModule, - PipesModule, + UnitConversionPipesModule, CifsModalModule, ], }) -export class RecoverPageModule { } +export class RecoverPageModule {} diff --git a/frontend/projects/setup-wizard/src/app/pipes/convert-bytes.pipe.ts b/frontend/projects/setup-wizard/src/app/pipes/convert-bytes.pipe.ts deleted file mode 100644 index d60a59722..000000000 --- a/frontend/projects/setup-wizard/src/app/pipes/convert-bytes.pipe.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Pipe, PipeTransform } from '@angular/core' - -// converts bytes to gigabytes -@Pipe({ - name: 'convertBytes', -}) -export class ConvertBytesPipe implements PipeTransform { - transform (bytes: number): string { - if (bytes === 0) return '0 Bytes' - - const k = 1024 - const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] - - const i = Math.floor(Math.log(bytes) / Math.log(k)) - - return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i] - } -} diff --git a/frontend/projects/setup-wizard/src/app/pipes/pipe.module.ts b/frontend/projects/setup-wizard/src/app/pipes/pipe.module.ts deleted file mode 100644 index ce34fc0b9..000000000 --- a/frontend/projects/setup-wizard/src/app/pipes/pipe.module.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { NgModule } from '@angular/core' -import { ConvertBytesPipe } from './convert-bytes.pipe' - -@NgModule({ -declarations: [ConvertBytesPipe], -imports: [], -exports: [ConvertBytesPipe], -}) - -export class PipesModule { } \ No newline at end of file diff --git a/frontend/projects/setup-wizard/src/app/services/api/mock-api.service.ts b/frontend/projects/setup-wizard/src/app/services/api/mock-api.service.ts index 78a216a64..6ed817d87 100644 --- a/frontend/projects/setup-wizard/src/app/services/api/mock-api.service.ts +++ b/frontend/projects/setup-wizard/src/app/services/api/mock-api.service.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core' -import { pauseFor } from 'src/app/util/misc.util' +import { pauseFor } from '@start9labs/shared' import { ApiService, CifsRecoverySource, SetupEmbassyReq } from './api.service' let tries = 0 diff --git a/frontend/projects/setup-wizard/src/app/services/state.service.ts b/frontend/projects/setup-wizard/src/app/services/state.service.ts index 6a5037b2c..dcfa99917 100644 --- a/frontend/projects/setup-wizard/src/app/services/state.service.ts +++ b/frontend/projects/setup-wizard/src/app/services/state.service.ts @@ -1,8 +1,12 @@ import { Injectable } from '@angular/core' import { BehaviorSubject } from 'rxjs' -import { ApiService, CifsRecoverySource, DiskRecoverySource } from './api/api.service' +import { + ApiService, + CifsRecoverySource, + DiskRecoverySource, +} from './api/api.service' import { ErrorToastService } from './error-toast.service' -import { pauseFor } from '../util/misc.util' +import { pauseFor } from '@start9labs/shared' @Injectable({ providedIn: 'root', @@ -17,7 +21,11 @@ export class StateService { recoverySource: CifsRecoverySource | DiskRecoverySource recoveryPassword: string - dataTransferProgress: { bytesTransferred: number, totalBytes: number, complete: boolean } | null + dataTransferProgress: { + bytesTransferred: number + totalBytes: number + complete: boolean + } | null dataProgress = 0 dataCompletionSubject = new BehaviorSubject(false) @@ -25,28 +33,27 @@ export class StateService { lanAddress: string cert: string - constructor ( + constructor( private readonly apiService: ApiService, private readonly errorToastService: ErrorToastService, - ) { } + ) {} - async pollDataTransferProgress () { + async pollDataTransferProgress() { this.polling = true await pauseFor(500) - if ( - this.dataTransferProgress?.complete - ) { + if (this.dataTransferProgress?.complete) { this.dataCompletionSubject.next(true) return } - let progress try { progress = await this.apiService.getRecoveryStatus() } catch (e) { - this.errorToastService.present(`${e.message}: ${e.details}.\nRestart Embassy to try again.`) + this.errorToastService.present( + `${e.message}: ${e.details}.\nRestart Embassy to try again.`, + ) } if (progress) { this.dataTransferProgress = { @@ -55,20 +62,25 @@ export class StateService { complete: progress.complete, } if (this.dataTransferProgress.totalBytes) { - this.dataProgress = this.dataTransferProgress.bytesTransferred / this.dataTransferProgress.totalBytes + this.dataProgress = + this.dataTransferProgress.bytesTransferred / + this.dataTransferProgress.totalBytes } } setTimeout(() => this.pollDataTransferProgress(), 0) // prevent call stack from growing } - async importDrive (guid: string): Promise { + async importDrive(guid: string): Promise { const ret = await this.apiService.importDrive(guid) this.torAddress = ret['tor-address'] this.lanAddress = ret['lan-address'] this.cert = ret['root-ca'] } - async setupEmbassy (storageLogicalname: string, password: string): Promise { + async setupEmbassy( + storageLogicalname: string, + password: string, + ): Promise { const ret = await this.apiService.setupEmbassy({ 'embassy-logicalname': storageLogicalname, 'embassy-password': password, diff --git a/frontend/projects/setup-wizard/src/app/util/misc.util.ts b/frontend/projects/setup-wizard/src/app/util/misc.util.ts deleted file mode 100644 index 1a21a3ab1..000000000 --- a/frontend/projects/setup-wizard/src/app/util/misc.util.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const pauseFor = (ms: number) => { - return new Promise(resolve => setTimeout(resolve, ms)) -} \ No newline at end of file diff --git a/frontend/projects/shared/package.json b/frontend/projects/shared/package.json index 28c4ba5c2..aa0b3923a 100644 --- a/frontend/projects/shared/package.json +++ b/frontend/projects/shared/package.json @@ -1,9 +1,10 @@ { - "name": "shared", + "name": "@start9labs/shared", "version": "0.0.1", "peerDependencies": { "@angular/common": "^13.2.0", - "@angular/core": "^13.2.0" + "@angular/core": "^13.2.0", + "@start9labs/emver": "^0.1.5" }, "dependencies": { "tslib": "^2.3.0" diff --git a/frontend/projects/ui/src/app/components/text-spinner/text-spinner.component.html b/frontend/projects/shared/src/components/text-spinner/text-spinner.component.html similarity index 50% rename from frontend/projects/ui/src/app/components/text-spinner/text-spinner.component.html rename to frontend/projects/shared/src/components/text-spinner/text-spinner.component.html index f5d5ec6dd..65019bceb 100644 --- a/frontend/projects/ui/src/app/components/text-spinner/text-spinner.component.html +++ b/frontend/projects/shared/src/components/text-spinner/text-spinner.component.html @@ -1,8 +1,8 @@ - - + +

{{ text }}

-
\ No newline at end of file +
diff --git a/frontend/projects/ui/src/app/components/text-spinner/text-spinner.component.module.ts b/frontend/projects/shared/src/components/text-spinner/text-spinner.component.module.ts similarity index 52% rename from frontend/projects/ui/src/app/components/text-spinner/text-spinner.component.module.ts rename to frontend/projects/shared/src/components/text-spinner/text-spinner.component.module.ts index fefc966ff..dacc85ffa 100644 --- a/frontend/projects/ui/src/app/components/text-spinner/text-spinner.component.module.ts +++ b/frontend/projects/shared/src/components/text-spinner/text-spinner.component.module.ts @@ -1,18 +1,11 @@ import { NgModule } from '@angular/core' import { CommonModule } from '@angular/common' -import { TextSpinnerComponent } from './text-spinner.component' import { IonicModule } from '@ionic/angular' -import { RouterModule } from '@angular/router' +import { TextSpinnerComponent } from './text-spinner.component' @NgModule({ - declarations: [ - TextSpinnerComponent, - ], - imports: [ - CommonModule, - IonicModule, - RouterModule.forChild([]), - ], + declarations: [TextSpinnerComponent], + imports: [CommonModule, IonicModule], exports: [TextSpinnerComponent], }) -export class TextSpinnerComponentModule { } +export class TextSpinnerComponentModule {} diff --git a/frontend/projects/shared/src/components/text-spinner/text-spinner.component.scss b/frontend/projects/shared/src/components/text-spinner/text-spinner.component.scss new file mode 100644 index 000000000..56fec7993 --- /dev/null +++ b/frontend/projects/shared/src/components/text-spinner/text-spinner.component.scss @@ -0,0 +1,3 @@ +.full-height { + height: 100%; +} diff --git a/frontend/projects/ui/src/app/components/text-spinner/text-spinner.component.ts b/frontend/projects/shared/src/components/text-spinner/text-spinner.component.ts similarity index 90% rename from frontend/projects/ui/src/app/components/text-spinner/text-spinner.component.ts rename to frontend/projects/shared/src/components/text-spinner/text-spinner.component.ts index a092860e5..f43b451ad 100644 --- a/frontend/projects/ui/src/app/components/text-spinner/text-spinner.component.ts +++ b/frontend/projects/shared/src/components/text-spinner/text-spinner.component.ts @@ -6,5 +6,5 @@ import { Component, Input } from '@angular/core' styleUrls: ['./text-spinner.component.scss'], }) export class TextSpinnerComponent { - @Input() text: string + @Input() text = '' } diff --git a/frontend/projects/shared/src/pipes/emver/emver.module.ts b/frontend/projects/shared/src/pipes/emver/emver.module.ts new file mode 100644 index 000000000..87b86e8cb --- /dev/null +++ b/frontend/projects/shared/src/pipes/emver/emver.module.ts @@ -0,0 +1,12 @@ +import { NgModule } from '@angular/core' +import { + EmverComparesPipe, + EmverDisplayPipe, + EmverSatisfiesPipe, +} from './emver.pipe' + +@NgModule({ + declarations: [EmverComparesPipe, EmverDisplayPipe, EmverSatisfiesPipe], + exports: [EmverComparesPipe, EmverDisplayPipe, EmverSatisfiesPipe], +}) +export class EmverPipesModule {} diff --git a/frontend/projects/ui/src/app/pipes/emver.pipe.ts b/frontend/projects/shared/src/pipes/emver/emver.pipe.ts similarity index 61% rename from frontend/projects/ui/src/app/pipes/emver.pipe.ts rename to frontend/projects/shared/src/pipes/emver/emver.pipe.ts index e220f351d..d16302736 100644 --- a/frontend/projects/ui/src/app/pipes/emver.pipe.ts +++ b/frontend/projects/shared/src/pipes/emver/emver.pipe.ts @@ -1,23 +1,24 @@ import { Pipe, PipeTransform } from '@angular/core' -import { Emver } from '../services/emver.service' +import { Emver } from '../../services/emver.service' + @Pipe({ - name: 'satisfiesEmver', + name: 'satisfiesEmver', }) export class EmverSatisfiesPipe implements PipeTransform { - constructor (private readonly emver: Emver) { } + constructor(private readonly emver: Emver) {} - transform (versionUnderTest: string, range: string): boolean { + transform(versionUnderTest: string, range: string): boolean { return this.emver.satisfies(versionUnderTest, range) } } @Pipe({ - name: 'compareEmver', + name: 'compareEmver', }) export class EmverComparesPipe implements PipeTransform { - constructor (private readonly emver: Emver) { } + constructor(private readonly emver: Emver) {} - transform (first: string, second: string): SemverResult { + transform(first: string, second: string): SemverResult { try { return this.emver.compare(first, second) as SemverResult } catch (e) { @@ -29,18 +30,18 @@ export class EmverComparesPipe implements PipeTransform { type SemverResult = 0 | 1 | -1 | 'comparison-impossible' @Pipe({ - name: 'displayEmver', + name: 'displayEmver', }) export class EmverDisplayPipe implements PipeTransform { - constructor () { } + constructor() {} - transform (version: string): string { + transform(version: string): string { return displayEmver(version) } } -export function displayEmver (version: string): string { +export function displayEmver(version: string): string { const vs = version.split('.') if (vs.length === 4) return `${vs[0]}.${vs[1]}.${vs[2]}~${vs[3]}` return version -} \ No newline at end of file +} diff --git a/frontend/projects/shared/src/pipes/markdown/markdown.module.ts b/frontend/projects/shared/src/pipes/markdown/markdown.module.ts new file mode 100644 index 000000000..ca39a43a5 --- /dev/null +++ b/frontend/projects/shared/src/pipes/markdown/markdown.module.ts @@ -0,0 +1,8 @@ +import { NgModule } from '@angular/core' +import { MarkdownPipe } from './markdown.pipe' + +@NgModule({ + declarations: [MarkdownPipe], + exports: [MarkdownPipe], +}) +export class MarkdownPipeModule {} diff --git a/frontend/projects/ui/src/app/pipes/markdown.pipe.ts b/frontend/projects/shared/src/pipes/markdown/markdown.pipe.ts similarity index 100% rename from frontend/projects/ui/src/app/pipes/markdown.pipe.ts rename to frontend/projects/shared/src/pipes/markdown/markdown.pipe.ts diff --git a/frontend/projects/ui/src/app/pipes/empty.pipe.ts b/frontend/projects/shared/src/pipes/shared/empty.pipe.ts similarity index 67% rename from frontend/projects/ui/src/app/pipes/empty.pipe.ts rename to frontend/projects/shared/src/pipes/shared/empty.pipe.ts index bc72cf602..7ba730c8b 100644 --- a/frontend/projects/ui/src/app/pipes/empty.pipe.ts +++ b/frontend/projects/shared/src/pipes/shared/empty.pipe.ts @@ -1,12 +1,12 @@ import { Pipe, PipeTransform } from '@angular/core' -import { isEmptyObject } from '../util/misc.util' +import { isEmptyObject } from '../../util/misc.util' @Pipe({ name: 'empty', }) export class EmptyPipe implements PipeTransform { - transform (val: object | [] = { }): boolean { + transform(val: object | [] = {}): boolean { if (Array.isArray(val)) return !val.length return isEmptyObject(val) } -} \ No newline at end of file +} diff --git a/frontend/projects/ui/src/app/pipes/includes.pipe.ts b/frontend/projects/shared/src/pipes/shared/includes.pipe.ts similarity index 68% rename from frontend/projects/ui/src/app/pipes/includes.pipe.ts rename to frontend/projects/shared/src/pipes/shared/includes.pipe.ts index 01182283c..df7a1e1da 100644 --- a/frontend/projects/ui/src/app/pipes/includes.pipe.ts +++ b/frontend/projects/shared/src/pipes/shared/includes.pipe.ts @@ -1,10 +1,10 @@ import { Pipe, PipeTransform } from '@angular/core' @Pipe({ - name: 'includes', + name: 'includes', }) export class IncludesPipe implements PipeTransform { - transform (list: T[], val: T): boolean { + transform(list: T[], val: T): boolean { return list.includes(val) } -} \ No newline at end of file +} diff --git a/frontend/projects/shared/src/pipes/shared/shared.module.ts b/frontend/projects/shared/src/pipes/shared/shared.module.ts new file mode 100644 index 000000000..1f3004e4b --- /dev/null +++ b/frontend/projects/shared/src/pipes/shared/shared.module.ts @@ -0,0 +1,9 @@ +import { NgModule } from '@angular/core' +import { IncludesPipe } from './includes.pipe' +import { EmptyPipe } from './empty.pipe' + +@NgModule({ + declarations: [IncludesPipe, EmptyPipe], + exports: [IncludesPipe, EmptyPipe], +}) +export class SharedPipesModule {} diff --git a/frontend/projects/shared/src/pipes/unit-conversion/unit-conversion.module.ts b/frontend/projects/shared/src/pipes/unit-conversion/unit-conversion.module.ts new file mode 100644 index 000000000..c66535bdd --- /dev/null +++ b/frontend/projects/shared/src/pipes/unit-conversion/unit-conversion.module.ts @@ -0,0 +1,8 @@ +import { NgModule } from '@angular/core' +import { ConvertBytesPipe, DurationToSecondsPipe } from './unit-conversion.pipe' + +@NgModule({ + declarations: [ConvertBytesPipe, DurationToSecondsPipe], + exports: [ConvertBytesPipe, DurationToSecondsPipe], +}) +export class UnitConversionPipesModule {} diff --git a/frontend/projects/shared/src/pipes/unit-conversion/unit-conversion.pipe.ts b/frontend/projects/shared/src/pipes/unit-conversion/unit-conversion.pipe.ts new file mode 100644 index 000000000..fb40958e8 --- /dev/null +++ b/frontend/projects/shared/src/pipes/unit-conversion/unit-conversion.pipe.ts @@ -0,0 +1,41 @@ +import { Pipe, PipeTransform } from '@angular/core' + +// converts bytes to gigabytes +@Pipe({ + name: 'convertBytes', +}) +export class ConvertBytesPipe implements PipeTransform { + transform(bytes: number): string { + if (bytes === 0) return '0 Bytes' + + const k = 1024 + const i = Math.floor(Math.log(bytes) / Math.log(k)) + + return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i] + } +} + +@Pipe({ + name: 'durationToSeconds', +}) +export class DurationToSecondsPipe implements PipeTransform { + transform(duration: string | null): number { + if (!duration) return 0 + const splitUnit = duration.match(/^([0-9]*(\.[0-9]+)?)(ns|µs|ms|s|m|d)$/) + const unit = splitUnit[3] + const num = splitUnit[1] + return Number(num) * unitsToSeconds[unit] + } +} + +const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] + +const unitsToSeconds = { + ns: 1e-9, + µs: 1e-6, + ms: 0.001, + s: 1, + m: 60, + h: 3600, + d: 86400, +} diff --git a/frontend/projects/shared/src/public-api.ts b/frontend/projects/shared/src/public-api.ts index 5012b5df2..dcb00fae0 100644 --- a/frontend/projects/shared/src/public-api.ts +++ b/frontend/projects/shared/src/public-api.ts @@ -1,5 +1,28 @@ /* - * Public API Surface of shared + * Public API Surface of @start9labs/shared */ +export * from './components/text-spinner/text-spinner.component.module' +export * from './components/text-spinner/text-spinner.component' + +export * from './pipes/emver/emver.module' +export * from './pipes/emver/emver.pipe' +export * from './pipes/markdown/markdown.module' +export * from './pipes/markdown/markdown.pipe' +export * from './pipes/shared/shared.module' +export * from './pipes/shared/empty.pipe' +export * from './pipes/shared/includes.pipe' +export * from './pipes/unit-conversion/unit-conversion.module' +export * from './pipes/unit-conversion/unit-conversion.pipe' + +export * from './services/destroy.service' +export * from './services/emver.service' + +export * from './types/dependent-info' +export * from './types/install-progress' +export * from './types/package-state' +export * from './types/progress-data' export * from './types/workspace-config' + +export * from './util/misc.util' +export * from './util/package-loading-progress' diff --git a/frontend/projects/ui/src/app/services/destroy.service.ts b/frontend/projects/shared/src/services/destroy.service.ts similarity index 59% rename from frontend/projects/ui/src/app/services/destroy.service.ts rename to frontend/projects/shared/src/services/destroy.service.ts index 1f808ab32..d27120f43 100644 --- a/frontend/projects/ui/src/app/services/destroy.service.ts +++ b/frontend/projects/shared/src/services/destroy.service.ts @@ -1,5 +1,5 @@ -import { Injectable, OnDestroy } from "@angular/core"; -import { ReplaySubject } from "rxjs"; +import { Injectable, OnDestroy } from '@angular/core' +import { ReplaySubject } from 'rxjs' /** * Observable abstraction over ngOnDestroy to use with takeUntil @@ -7,7 +7,7 @@ import { ReplaySubject } from "rxjs"; @Injectable() export class DestroyService extends ReplaySubject implements OnDestroy { ngOnDestroy() { - this.next(); - this.complete(); + this.next() + this.complete() } } diff --git a/frontend/projects/ui/src/app/services/emver.service.ts b/frontend/projects/shared/src/services/emver.service.ts similarity index 68% rename from frontend/projects/ui/src/app/services/emver.service.ts rename to frontend/projects/shared/src/services/emver.service.ts index 84fb48c51..c8a0f308d 100644 --- a/frontend/projects/ui/src/app/services/emver.service.ts +++ b/frontend/projects/shared/src/services/emver.service.ts @@ -1,19 +1,18 @@ import { Injectable } from '@angular/core' import * as emver from '@start9labs/emver' - @Injectable({ providedIn: 'root', }) export class Emver { - constructor () { } + constructor() {} - compare (lhs: string, rhs: string): number { + compare(lhs: string, rhs: string): number { if (!lhs || !rhs) return null return emver.compare(lhs, rhs) } - satisfies (version: string, range: string): boolean { + satisfies(version: string, range: string): boolean { return emver.satisfies(version, range) } -} \ No newline at end of file +} diff --git a/frontend/projects/shared/src/types/dependent-info.ts b/frontend/projects/shared/src/types/dependent-info.ts new file mode 100644 index 000000000..a02233bef --- /dev/null +++ b/frontend/projects/shared/src/types/dependent-info.ts @@ -0,0 +1,5 @@ +export interface DependentInfo { + id: string + title: string + version?: string +} diff --git a/frontend/projects/shared/src/types/install-progress.ts b/frontend/projects/shared/src/types/install-progress.ts new file mode 100644 index 000000000..432d63de9 --- /dev/null +++ b/frontend/projects/shared/src/types/install-progress.ts @@ -0,0 +1,9 @@ +export interface InstallProgress { + size: number | null + downloaded: number + 'download-complete': boolean + validated: number + 'validation-complete': boolean + unpacked: number + 'unpack-complete': boolean +} diff --git a/frontend/projects/shared/src/types/package-state.ts b/frontend/projects/shared/src/types/package-state.ts new file mode 100644 index 000000000..e5bad9c2e --- /dev/null +++ b/frontend/projects/shared/src/types/package-state.ts @@ -0,0 +1,7 @@ +export enum PackageState { + Installing = 'installing', + Installed = 'installed', + Updating = 'updating', + Removing = 'removing', + Restoring = 'restoring', +} diff --git a/frontend/projects/shared/src/types/progress-data.ts b/frontend/projects/shared/src/types/progress-data.ts new file mode 100644 index 000000000..a05e475a1 --- /dev/null +++ b/frontend/projects/shared/src/types/progress-data.ts @@ -0,0 +1,7 @@ +export interface ProgressData { + totalProgress: number + downloadProgress: number + validateProgress: number + unpackProgress: number + isComplete: boolean +} diff --git a/frontend/projects/shared/src/util/misc.util.ts b/frontend/projects/shared/src/util/misc.util.ts new file mode 100644 index 000000000..94ac4b934 --- /dev/null +++ b/frontend/projects/shared/src/util/misc.util.ts @@ -0,0 +1,165 @@ +import { OperatorFunction } from 'rxjs' +import { map } from 'rxjs/operators' + +export function trace(t: T): T { + console.log(`TRACE`, t) + return t +} + +// curried description. This allows e.g somePromise.thentraceDesc('my result')) +export function traceDesc(description: string): (t: T) => T { + return t => { + console.log(`TRACE`, description, t) + return t + } +} + +// for use in observables. This allows e.g. someObservable.pipe(traceM('my result')) +// the practical equivalent of `tap(t => console.log(t, description))` +export function traceWheel(description?: string): OperatorFunction { + return description ? map(traceDesc(description)) : map(trace) +} + +export function traceThrowDesc(description: string, t: T | undefined): T { + if (!t) throw new Error(description) + return t +} + +export function inMs( + count: number, + unit: 'days' | 'hours' | 'minutes' | 'seconds', +) { + switch (unit) { + case 'seconds': + return count * 1000 + case 'minutes': + return inMs(count * 60, 'seconds') + case 'hours': + return inMs(count * 60, 'minutes') + case 'days': + return inMs(count * 24, 'hours') + } +} + +// arr1 - arr2 +export function diff(arr1: T[], arr2: T[]): T[] { + return arr1.filter(x => !arr2.includes(x)) +} + +// arr1 & arr2 +export function both(arr1: T[], arr2: T[]): T[] { + return arr1.filter(x => arr2.includes(x)) +} + +export function isObject(val: any): boolean { + return val && typeof val === 'object' && !Array.isArray(val) +} + +export function isEmptyObject(obj: object): boolean { + if (obj === undefined) return true + return !Object.keys(obj).length +} + +export function pauseFor(ms: number): Promise { + return new Promise(resolve => setTimeout(resolve, ms)) +} + +export function toObject(t: T[], map: (t0: T) => string): Record { + return t.reduce((acc, next) => { + acc[map(next)] = next + return acc + }, {} as Record) +} + +export function update( + t: Record, + u: Record, +): Record { + return { ...t, ...u } +} + +export function deepCloneUnknown(value: T): T { + if (typeof value !== 'object' || value === null) { + return value + } + if (Array.isArray(value)) { + return deepCloneArray(value) + } + return deepCloneObject(value) +} + +export function deepCloneObject(source: T) { + const result = {} + Object.keys(source).forEach(key => { + const value = source[key] + result[key] = deepCloneUnknown(value) + }, {}) + return result as T +} + +export function deepCloneArray(collection: any) { + return collection.map(value => { + return deepCloneUnknown(value) + }) +} + +export function partitionArray( + ts: T[], + condition: (t: T) => boolean, +): [T[], T[]] { + const yes = [] as T[] + const no = [] as T[] + ts.forEach(t => { + if (condition(t)) { + yes.push(t) + } else { + no.push(t) + } + }) + return [yes, no] +} + +export function uniqueBy( + ts: T[], + uniqueBy: (t: T) => string, + prioritize: (t1: T, t2: T) => T, +) { + return Object.values( + ts.reduce((acc, next) => { + const previousValue = acc[uniqueBy(next)] + if (previousValue) { + acc[uniqueBy(next)] = prioritize(acc[uniqueBy(next)], previousValue) + } else { + acc[uniqueBy(next)] = previousValue + } + return acc + }, {}), + ) +} + +export function capitalizeFirstLetter(string: string): string { + return string.charAt(0).toUpperCase() + string.slice(1) +} + +export const exists = (t: any) => { + return t !== undefined +} + +export function debounce(delay: number = 300): MethodDecorator { + return function ( + target: any, + propertyKey: string, + descriptor: PropertyDescriptor, + ) { + const timeoutKey = Symbol() + + const original = descriptor.value + + descriptor.value = function (...args) { + clearTimeout(this[timeoutKey]) + this[timeoutKey] = setTimeout(() => original.apply(this, args), delay) + } + + return descriptor + } +} diff --git a/frontend/projects/ui/src/app/util/package-loading-progress.ts b/frontend/projects/shared/src/util/package-loading-progress.ts similarity index 85% rename from frontend/projects/ui/src/app/util/package-loading-progress.ts rename to frontend/projects/shared/src/util/package-loading-progress.ts index 229bfed1f..a1e276324 100644 --- a/frontend/projects/ui/src/app/util/package-loading-progress.ts +++ b/frontend/projects/shared/src/util/package-loading-progress.ts @@ -1,5 +1,6 @@ -import { InstallProgress } from 'src/app/services/patch-db/data-model' import { isEmptyObject } from './misc.util' +import { InstallProgress } from '../types/install-progress' +import { ProgressData } from '../types/progress-data' export function packageLoadingProgress( loadData: InstallProgress, @@ -46,11 +47,3 @@ export function packageLoadingProgress( isComplete: downloadComplete && validationComplete && unpackComplete, } } - -export interface ProgressData { - totalProgress: number - downloadProgress: number - validateProgress: number - unpackProgress: number - isComplete: boolean -} diff --git a/frontend/projects/shared/tsconfig.lib.json b/frontend/projects/shared/tsconfig.json similarity index 93% rename from frontend/projects/shared/tsconfig.lib.json rename to frontend/projects/shared/tsconfig.json index 305b0b9bf..e3a6b521c 100644 --- a/frontend/projects/shared/tsconfig.lib.json +++ b/frontend/projects/shared/tsconfig.json @@ -2,6 +2,7 @@ { "extends": "../../tsconfig.json", "compilerOptions": { + "baseUrl": "./", "outDir": "../../out-tsc/lib", "declaration": true, "declarationMap": true, diff --git a/frontend/projects/shared/tsconfig.lib.prod.json b/frontend/projects/shared/tsconfig.prod.json similarity index 100% rename from frontend/projects/shared/tsconfig.lib.prod.json rename to frontend/projects/shared/tsconfig.prod.json diff --git a/frontend/projects/ui/src/app/app.component.ts b/frontend/projects/ui/src/app/app.component.ts index d57618727..419622c8e 100644 --- a/frontend/projects/ui/src/app/app.component.ts +++ b/frontend/projects/ui/src/app/app.component.ts @@ -16,17 +16,16 @@ import { ModalController, ToastController, } from '@ionic/angular' -import { Emver } from './services/emver.service' import { SplitPaneTracker } from './services/split-pane.service' import { ToastButton } from '@ionic/core' import { PatchDbService } from './services/patch-db/patch-db.service' -import { ServerStatus, UIData } from './services/patch-db/data-model' import { ConnectionFailure, ConnectionService, } from './services/connection.service' import { ConfigService } from './services/config.service' -import { debounce, isEmptyObject } from './util/misc.util' +import { debounce, isEmptyObject, Emver } from '@start9labs/shared' +import { ServerStatus, UIData } from 'src/app/services/patch-db/data-model' import { ErrorToastService } from './services/error-toast.service' import { Subscription } from 'rxjs' import { LocalStorageService } from './services/local-storage.service' @@ -42,7 +41,7 @@ import { OSWelcomePage } from './modals/os-welcome/os-welcome.page' export class AppComponent { @HostListener('document:keydown.enter', ['$event']) @debounce() - handleKeyboardEvent () { + handleKeyboardEvent() { const elems = document.getElementsByClassName('enter-click') const elem = elems[elems.length - 1] as HTMLButtonElement if (!elem || elem.classList.contains('no-click') || elem.disabled) return @@ -87,7 +86,7 @@ export class AppComponent { }, ] - constructor ( + constructor( private readonly storage: Storage, private readonly authService: AuthService, private readonly router: Router, @@ -110,7 +109,7 @@ export class AppComponent { this.init() } - async init () { + async init() { await this.storage.create() await this.authService.init() await this.localStorageService.init() @@ -181,7 +180,7 @@ export class AppComponent { }) } - async goToWebsite (): Promise { + async goToWebsite(): Promise { let url: string if (this.config.isTor()) { url = @@ -192,7 +191,7 @@ export class AppComponent { window.open(url, '_blank', 'noreferrer') } - async presentAlertLogout () { + async presentAlertLogout() { const alert = await this.alertCtrl.create({ header: 'Caution', message: @@ -215,13 +214,13 @@ export class AppComponent { await alert.present() } - private checkForEosUpdate (ui: UIData): void { + private checkForEosUpdate(ui: UIData): void { if (ui['auto-check-updates']) { this.eosService.getEOS() } } - private async showEosWelcome (ackVersion: string): Promise { + private async showEosWelcome(ackVersion: string): Promise { if (!this.config.skipStartupAlerts && ackVersion !== this.config.version) { const modal = await this.modalCtrl.create({ component: OSWelcomePage, @@ -240,12 +239,12 @@ export class AppComponent { } // should wipe cache independant of actual BE logout - private async logout () { + private async logout() { this.embassyApi.logout({}) this.authService.setUnverified() } - private watchConnection (): Subscription { + private watchConnection(): Subscription { return this.connectionService .watchFailure$() .pipe(distinctUntilChanged(), debounceTime(500)) @@ -278,7 +277,7 @@ export class AppComponent { }) } - private watchRouter (): Subscription { + private watchRouter(): Subscription { return this.router.events .pipe(filter((e: RoutesRecognized) => !!e.urlAfterRedirects)) .subscribe(e => { @@ -289,7 +288,7 @@ export class AppComponent { }) } - private watchStatus (): Subscription { + private watchStatus(): Subscription { return this.patch .watch$('server-info', 'status-info', 'updated') .subscribe(isUpdated => { @@ -300,7 +299,7 @@ export class AppComponent { } m - private watchUpdateProgress (): Subscription { + private watchUpdateProgress(): Subscription { return this.patch .watch$('server-info', 'status-info', 'update-progress') .subscribe(progress => { @@ -308,7 +307,7 @@ export class AppComponent { }) } - private watchVersion (): Subscription { + private watchVersion(): Subscription { return this.patch.watch$('server-info', 'version').subscribe(version => { if (this.emver.compare(this.config.version, version) !== 0) { this.presentAlertRefreshNeeded() @@ -316,7 +315,7 @@ export class AppComponent { }) } - private watchNotifications (): Subscription { + private watchNotifications(): Subscription { let previous: number return this.patch .watch$('server-info', 'unread-notification-count') @@ -328,7 +327,7 @@ export class AppComponent { }) } - private async presentAlertRefreshNeeded () { + private async presentAlertRefreshNeeded() { const alert = await this.alertCtrl.create({ backdropDismiss: false, header: 'Refresh Needed', @@ -347,7 +346,7 @@ export class AppComponent { await alert.present() } - private async presentToastUpdated () { + private async presentToastUpdated() { if (this.updateToast) return this.updateToast = await this.toastCtrl.create({ @@ -377,7 +376,7 @@ export class AppComponent { await this.updateToast.present() } - private async presentToastNotifications () { + private async presentToastNotifications() { if (this.notificationToast) return this.notificationToast = await this.toastCtrl.create({ @@ -407,7 +406,7 @@ export class AppComponent { await this.notificationToast.present() } - private async presentToastOffline ( + private async presentToastOffline( message: string | IonicSafeString, link?: string, ) { @@ -448,7 +447,7 @@ export class AppComponent { await this.offlineToast.present() } - private async restart (): Promise { + private async restart(): Promise { const loader = await this.loadingCtrl.create({ spinner: 'lines', message: 'Restarting...', @@ -465,7 +464,7 @@ export class AppComponent { } } - splitPaneVisible (e: any) { + splitPaneVisible(e: any) { this.splitPane.sidebarOpen$.next(e.detail.visible) } } diff --git a/frontend/projects/ui/src/app/app.module.ts b/frontend/projects/ui/src/app/app.module.ts index 63ddb11b4..1924b041f 100644 --- a/frontend/projects/ui/src/app/app.module.ts +++ b/frontend/projects/ui/src/app/app.module.ts @@ -15,15 +15,14 @@ import { OSWelcomePageModule } from './modals/os-welcome/os-welcome.module' import { MarkdownPageModule } from './modals/markdown/markdown.module' import { PatchDbService } from './services/patch-db/patch-db.service' import { LocalStorageBootstrap } from './services/patch-db/local-storage-bootstrap' -import { SharingModule } from './modules/sharing.module' import { FormBuilder } from '@angular/forms' import { GenericInputComponentModule } from './modals/generic-input/generic-input.component.module' import { AuthService } from './services/auth.service' import { GlobalErrorHandler } from './services/global-error-handler.service' import { MockApiService } from './services/api/embassy-mock-api.service' import { LiveApiService } from './services/api/embassy-live-api.service' -import { WorkspaceConfig } from '@shared' import { MonacoEditorModule } from '@materia-ui/ngx-monaco-editor' +import { SharedPipesModule, WorkspaceConfig } from '@start9labs/shared' const { useMocks } = require('../../../../config.json') as WorkspaceConfig @@ -47,8 +46,8 @@ const { useMocks } = require('../../../../config.json') as WorkspaceConfig OSWelcomePageModule, MarkdownPageModule, GenericInputComponentModule, - SharingModule, MonacoEditorModule, + SharedPipesModule, ], providers: [ FormBuilder, @@ -80,4 +79,4 @@ const { useMocks } = require('../../../../config.json') as WorkspaceConfig bootstrap: [AppComponent], schemas: [CUSTOM_ELEMENTS_SCHEMA], }) -export class AppModule {} +export class AppModule { } diff --git a/frontend/projects/ui/src/app/components/backup-drives/backup-drives.component.module.ts b/frontend/projects/ui/src/app/components/backup-drives/backup-drives.component.module.ts index d3bc6419c..bf7f844e3 100644 --- a/frontend/projects/ui/src/app/components/backup-drives/backup-drives.component.module.ts +++ b/frontend/projects/ui/src/app/components/backup-drives/backup-drives.component.module.ts @@ -1,8 +1,15 @@ import { NgModule } from '@angular/core' import { CommonModule } from '@angular/common' import { IonicModule } from '@ionic/angular' -import { BackupDrivesComponent, BackupDrivesHeaderComponent, BackupDrivesStatusComponent } from './backup-drives.component' -import { SharingModule } from '../../modules/sharing.module' +import { + BackupDrivesComponent, + BackupDrivesHeaderComponent, + BackupDrivesStatusComponent, +} from './backup-drives.component' +import { + UnitConversionPipesModule, + TextSpinnerComponentModule, +} from '@start9labs/shared' import { GenericFormPageModule } from 'src/app/modals/generic-form/generic-form.module' @NgModule({ @@ -14,7 +21,8 @@ import { GenericFormPageModule } from 'src/app/modals/generic-form/generic-form. imports: [ CommonModule, IonicModule, - SharingModule, + UnitConversionPipesModule, + TextSpinnerComponentModule, GenericFormPageModule, ], exports: [ @@ -23,4 +31,4 @@ import { GenericFormPageModule } from 'src/app/modals/generic-form/generic-form. BackupDrivesStatusComponent, ], }) -export class BackupDrivesComponentModule { } +export class BackupDrivesComponentModule {} diff --git a/frontend/projects/ui/src/app/components/backup-drives/backup-drives.component.ts b/frontend/projects/ui/src/app/components/backup-drives/backup-drives.component.ts index 09e1a9d41..242e60267 100644 --- a/frontend/projects/ui/src/app/components/backup-drives/backup-drives.component.ts +++ b/frontend/projects/ui/src/app/components/backup-drives/backup-drives.component.ts @@ -1,12 +1,21 @@ import { Component, EventEmitter, Input, Output } from '@angular/core' import { BackupService } from './backup.service' -import { CifsBackupTarget, DiskBackupTarget, RR } from 'src/app/services/api/api.types' -import { ActionSheetController, AlertController, LoadingController, ModalController } from '@ionic/angular' +import { + CifsBackupTarget, + DiskBackupTarget, + RR, +} from 'src/app/services/api/api.types' +import { + ActionSheetController, + AlertController, + LoadingController, + ModalController, +} from '@ionic/angular' import { GenericFormPage } from 'src/app/modals/generic-form/generic-form.page' import { ConfigSpec } from 'src/app/pkg-config/config-types' import { ApiService } from 'src/app/services/api/embassy-api.service' import { ErrorToastService } from 'src/app/services/error-toast.service' -import { MappedBackupTarget } from 'src/app/util/misc.util' +import { MappedBackupTarget } from 'src/app/types/mapped-backup-target' @Component({ selector: 'backup-drives', @@ -15,10 +24,12 @@ import { MappedBackupTarget } from 'src/app/util/misc.util' }) export class BackupDrivesComponent { @Input() type: 'create' | 'restore' - @Output() onSelect: EventEmitter> = new EventEmitter() + @Output() onSelect: EventEmitter< + MappedBackupTarget + > = new EventEmitter() loadingText: string - constructor ( + constructor( private readonly loadingCtrl: LoadingController, private readonly actionCtrl: ActionSheetController, private readonly alertCtrl: AlertController, @@ -26,22 +37,30 @@ export class BackupDrivesComponent { private readonly embassyApi: ApiService, private readonly errToast: ErrorToastService, public readonly backupService: BackupService, - ) { } + ) {} - ngOnInit () { - this.loadingText = this.type === 'create' ? 'Fetching Backup Targets' : 'Fetching Backup Sources' + ngOnInit() { + this.loadingText = + this.type === 'create' + ? 'Fetching Backup Targets' + : 'Fetching Backup Sources' this.backupService.getBackupTargets() } - select (target: MappedBackupTarget): void { + select( + target: MappedBackupTarget, + ): void { if (target.entry.type === 'cifs' && !target.entry.mountable) { - const message = 'Unable to connect to shared folder. Ensure (1) target computer is connected to LAN, (2) target folder is being shared, and (3) hostname, path, and credentials are accurate.' + const message = + 'Unable to connect to shared folder. Ensure (1) target computer is connected to LAN, (2) target folder is being shared, and (3) hostname, path, and credentials are accurate.' this.presentAlertError(message) return } if (this.type === 'restore' && !target.hasValidBackup) { - const message = `${target.entry.type === 'cifs' ? 'Shared folder' : 'Drive partition'} does not contain a valid Embassy backup.` + const message = `${ + target.entry.type === 'cifs' ? 'Shared folder' : 'Drive partition' + } does not contain a valid Embassy backup.` this.presentAlertError(message) return } @@ -49,7 +68,7 @@ export class BackupDrivesComponent { this.onSelect.emit(target) } - async presentModalAddCifs (): Promise { + async presentModalAddCifs(): Promise { const modal = await this.modalCtrl.create({ component: GenericFormPage, componentProps: { @@ -69,7 +88,10 @@ export class BackupDrivesComponent { await modal.present() } - async presentActionCifs (target: MappedBackupTarget, index: number): Promise { + async presentActionCifs( + target: MappedBackupTarget, + index: number, + ): Promise { const entry = target.entry as CifsBackupTarget const action = await this.actionCtrl.create({ @@ -93,8 +115,12 @@ export class BackupDrivesComponent { }, }, { - text: this.type === 'create' ? 'Create Backup' : 'Restore From Backup', - icon: this.type === 'create' ? 'cloud-upload-outline' : 'cloud-download-outline', + text: + this.type === 'create' ? 'Create Backup' : 'Restore From Backup', + icon: + this.type === 'create' + ? 'cloud-upload-outline' + : 'cloud-download-outline', handler: () => { this.select(target) }, @@ -105,7 +131,7 @@ export class BackupDrivesComponent { await action.present() } - private async presentAlertError (message: string): Promise { + private async presentAlertError(message: string): Promise { const alert = await this.alertCtrl.create({ header: 'Error', message, @@ -114,7 +140,7 @@ export class BackupDrivesComponent { await alert.present() } - private async addCifs (value: RR.AddBackupTargetReq): Promise { + private async addCifs(value: RR.AddBackupTargetReq): Promise { const loader = await this.loadingCtrl.create({ spinner: 'lines', message: 'Testing connectivity to shared folder...', @@ -139,7 +165,11 @@ export class BackupDrivesComponent { } } - private async presentModalEditCifs (id: string, entry: CifsBackupTarget, index: number): Promise { + private async presentModalEditCifs( + id: string, + entry: CifsBackupTarget, + index: number, + ): Promise { const { hostname, path, username } = entry const modal = await this.modalCtrl.create({ @@ -166,7 +196,10 @@ export class BackupDrivesComponent { await modal.present() } - private async editCifs (value: RR.UpdateBackupTargetReq, index: number): Promise { + private async editCifs( + value: RR.UpdateBackupTargetReq, + index: number, + ): Promise { const loader = await this.loadingCtrl.create({ spinner: 'lines', message: 'Testing connectivity to shared folder...', @@ -185,7 +218,7 @@ export class BackupDrivesComponent { } } - private async deleteCifs (id: string, index: number): Promise { + private async deleteCifs(id: string, index: number): Promise { const loader = await this.loadingCtrl.create({ spinner: 'lines', message: 'Removing...', @@ -204,7 +237,6 @@ export class BackupDrivesComponent { } } - @Component({ selector: 'backup-drives-header', templateUrl: './backup-drives-header.component.html', @@ -214,16 +246,13 @@ export class BackupDrivesHeaderComponent { @Input() title: string @Output() onClose: EventEmitter = new EventEmitter() - constructor ( - public readonly backupService: BackupService, - ) { } + constructor(public readonly backupService: BackupService) {} - refresh () { + refresh() { this.backupService.getBackupTargets() } } - @Component({ selector: 'backup-drives-status', templateUrl: './backup-drives-status.component.html', @@ -238,7 +267,8 @@ const CifsSpec: ConfigSpec = { hostname: { type: 'string', name: 'Hostname', - description: 'The hostname of your target device on the Local Area Network.', + description: + 'The hostname of your target device on the Local Area Network.', placeholder: `e.g. 'My Computer' OR 'my-computer.local'`, pattern: '^[a-zA-Z0-9._-]+( [a-zA-Z0-9]+)*$', 'pattern-description': `Must be a valid hostname. e.g. 'My Computer' OR 'my-computer.local'`, @@ -249,7 +279,8 @@ const CifsSpec: ConfigSpec = { path: { type: 'string', name: 'Path', - description: 'The directory path to the shared folder on your target device.', + description: + 'The directory path to the shared folder on your target device.', placeholder: 'e.g. /Desktop/my-folder', nullable: false, masked: false, diff --git a/frontend/projects/ui/src/app/components/backup-drives/backup.service.ts b/frontend/projects/ui/src/app/components/backup-drives/backup.service.ts index bddc30b96..3fde8693d 100644 --- a/frontend/projects/ui/src/app/components/backup-drives/backup.service.ts +++ b/frontend/projects/ui/src/app/components/backup-drives/backup.service.ts @@ -2,9 +2,13 @@ import { Injectable } from '@angular/core' import { IonicSafeString } from '@ionic/core' import { ApiService } from 'src/app/services/api/embassy-api.service' import { getErrorMessage } from 'src/app/services/error-toast.service' -import { BackupTarget, CifsBackupTarget, DiskBackupTarget } from 'src/app/services/api/api.types' -import { Emver } from 'src/app/services/emver.service' -import { MappedBackupTarget } from 'src/app/util/misc.util' +import { + BackupTarget, + CifsBackupTarget, + DiskBackupTarget, +} from 'src/app/services/api/api.types' +import { MappedBackupTarget } from 'src/app/types/mapped-backup-target' +import { Emver } from '@start9labs/shared' @Injectable({ providedIn: 'root', @@ -15,36 +19,36 @@ export class BackupService { loading = true loadingError: string | IonicSafeString - constructor ( + constructor( private readonly embassyApi: ApiService, private readonly emver: Emver, - ) { } + ) {} - async getBackupTargets (): Promise { + async getBackupTargets(): Promise { this.loading = true try { - const targets = await this.embassyApi.getBackupTargets({ }) + const targets = await this.embassyApi.getBackupTargets({}) // cifs this.cifs = Object.entries(targets) - .filter(([_, target]) => target.type === 'cifs') - .map(([id, cifs]) => { - return { - id, - hasValidBackup: this.hasValidBackup(cifs), - entry: cifs as CifsBackupTarget, - } - }) + .filter(([_, target]) => target.type === 'cifs') + .map(([id, cifs]) => { + return { + id, + hasValidBackup: this.hasValidBackup(cifs), + entry: cifs as CifsBackupTarget, + } + }) // drives this.drives = Object.entries(targets) - .filter(([_, target]) => target.type === 'disk') - .map(([id, drive]) => { - return { - id, - hasValidBackup: this.hasValidBackup(drive), - entry: drive as DiskBackupTarget, - } - }) + .filter(([_, target]) => target.type === 'disk') + .map(([id, drive]) => { + return { + id, + hasValidBackup: this.hasValidBackup(drive), + entry: drive as DiskBackupTarget, + } + }) } catch (e) { this.loadingError = getErrorMessage(e) } finally { @@ -52,7 +56,9 @@ export class BackupService { } } - hasValidBackup (target: BackupTarget): boolean { - return [0, 1].includes(this.emver.compare(target['embassy-os']?.version, '0.3.0')) + hasValidBackup(target: BackupTarget): boolean { + return [0, 1].includes( + this.emver.compare(target['embassy-os']?.version, '0.3.0'), + ) } } diff --git a/frontend/projects/ui/src/app/components/badge-menu-button/badge-menu.component.html b/frontend/projects/ui/src/app/components/badge-menu-button/badge-menu.component.html index a07dec233..f209c3605 100644 --- a/frontend/projects/ui/src/app/components/badge-menu-button/badge-menu.component.html +++ b/frontend/projects/ui/src/app/components/badge-menu-button/badge-menu.component.html @@ -1,4 +1,11 @@ -
- {{ unreadCount }} +
+ + {{ unreadCount }} +
diff --git a/frontend/projects/ui/src/app/components/badge-menu-button/badge-menu.component.module.ts b/frontend/projects/ui/src/app/components/badge-menu-button/badge-menu.component.module.ts index d417a457f..b09ad93f7 100644 --- a/frontend/projects/ui/src/app/components/badge-menu-button/badge-menu.component.module.ts +++ b/frontend/projects/ui/src/app/components/badge-menu-button/badge-menu.component.module.ts @@ -1,18 +1,11 @@ import { NgModule } from '@angular/core' import { CommonModule } from '@angular/common' -import { BadgeMenuComponent } from './badge-menu.component' import { IonicModule } from '@ionic/angular' -import { SharingModule } from 'src/app/modules/sharing.module' +import { BadgeMenuComponent } from './badge-menu.component' @NgModule({ - declarations: [ - BadgeMenuComponent, - ], - imports: [ - CommonModule, - IonicModule, - SharingModule, - ], + declarations: [BadgeMenuComponent], + imports: [CommonModule, IonicModule], exports: [BadgeMenuComponent], }) -export class BadgeMenuComponentModule { } +export class BadgeMenuComponentModule {} diff --git a/frontend/projects/ui/src/app/components/badge-menu-button/badge-menu.component.scss b/frontend/projects/ui/src/app/components/badge-menu-button/badge-menu.component.scss index 93412ce23..80d397db1 100644 --- a/frontend/projects/ui/src/app/components/badge-menu-button/badge-menu.component.scss +++ b/frontend/projects/ui/src/app/components/badge-menu-button/badge-menu.component.scss @@ -1,3 +1,8 @@ +.wrapper { + position: relative; + margin-right: 1vh; +} + .md-badge { background-color: var(--ion-color-danger); position: absolute; diff --git a/frontend/projects/ui/src/app/components/form-object/form-object.component.module.ts b/frontend/projects/ui/src/app/components/form-object/form-object.component.module.ts index c42265c63..fde102b3d 100644 --- a/frontend/projects/ui/src/app/components/form-object/form-object.component.module.ts +++ b/frontend/projects/ui/src/app/components/form-object/form-object.component.module.ts @@ -1,29 +1,25 @@ import { NgModule } from '@angular/core' import { CommonModule } from '@angular/common' -import { FormObjectComponent, FormLabelComponent, FormErrorComponent } from './form-object.component' +import { + FormObjectComponent, + FormLabelComponent, + FormErrorComponent, +} from './form-object.component' import { IonicModule } from '@ionic/angular' import { FormsModule, ReactiveFormsModule } from '@angular/forms' -import { SharingModule } from 'src/app/modules/sharing.module' +import { SharedPipesModule } from '@start9labs/shared' import { EnumListPageModule } from 'src/app/modals/enum-list/enum-list.module' @NgModule({ - declarations: [ - FormObjectComponent, - FormLabelComponent, - FormErrorComponent, - ], + declarations: [FormObjectComponent, FormLabelComponent, FormErrorComponent], imports: [ CommonModule, IonicModule, FormsModule, ReactiveFormsModule, - SharingModule, + SharedPipesModule, EnumListPageModule, ], - exports: [ - FormObjectComponent, - FormLabelComponent, - FormErrorComponent, - ], + exports: [FormObjectComponent, FormLabelComponent, FormErrorComponent], }) -export class FormObjectComponentModule { } +export class FormObjectComponentModule {} diff --git a/frontend/projects/ui/src/app/components/form-object/form-object.component.ts b/frontend/projects/ui/src/app/components/form-object/form-object.component.ts index 5c85610c9..2518e98e0 100644 --- a/frontend/projects/ui/src/app/components/form-object/form-object.component.ts +++ b/frontend/projects/ui/src/app/components/form-object/form-object.component.ts @@ -1,11 +1,28 @@ import { Component, Input, Output, EventEmitter } from '@angular/core' -import { AbstractFormGroupDirective, FormArray, FormGroup } from '@angular/forms' -import { AlertButton, AlertController, IonicSafeString, ModalController } from '@ionic/angular' -import { ConfigSpec, ListValueSpecOf, ValueSpec, ValueSpecBoolean, ValueSpecList, ValueSpecListOf, ValueSpecUnion } from 'src/app/pkg-config/config-types' +import { + AbstractFormGroupDirective, + FormArray, + FormGroup, +} from '@angular/forms' +import { + AlertButton, + AlertController, + IonicSafeString, + ModalController, +} from '@ionic/angular' +import { + ConfigSpec, + ListValueSpecOf, + ValueSpec, + ValueSpecBoolean, + ValueSpecList, + ValueSpecListOf, + ValueSpecUnion, +} from 'src/app/pkg-config/config-types' import { FormService } from 'src/app/services/form.service' import { Range } from 'src/app/pkg-config/config-utilities' import { EnumListPage } from 'src/app/modals/enum-list/enum-list.page' -import { pauseFor } from 'src/app/util/misc.util' +import { pauseFor } from '@start9labs/shared' import { v4 } from 'uuid' const Mustache = require('mustache') @@ -22,31 +39,38 @@ export class FormObjectComponent { @Input() showEdited: boolean = false @Output() onInputChange = new EventEmitter() @Output() onExpand = new EventEmitter() - warningAck: { [key: string]: boolean } = { } - unmasked: { [key: string]: boolean } = { } - objectDisplay: { [key: string]: { expanded: boolean, height: string } } = { } - objectListDisplay: { [key: string]: { expanded: boolean, height: string, displayAs: string }[] } = { } + warningAck: { [key: string]: boolean } = {} + unmasked: { [key: string]: boolean } = {} + objectDisplay: { [key: string]: { expanded: boolean; height: string } } = {} + objectListDisplay: { + [key: string]: { expanded: boolean; height: string; displayAs: string }[] + } = {} private objectId = v4() Object = Object - constructor ( + constructor( private readonly alertCtrl: AlertController, private readonly modalCtrl: ModalController, private readonly formService: FormService, - ) { } + ) {} - ngOnInit () { + ngOnInit() { Object.keys(this.objectSpec).forEach(key => { const spec = this.objectSpec[key] + if (spec.type === 'list' && ['object', 'union'].includes(spec.subtype)) { - this.objectListDisplay[key] = []; - (this.formGroup.get(key).value as any[]).forEach((obj, index) => { - const displayAs = (spec.spec as ListValueSpecOf<'object'>)['display-as'] + this.objectListDisplay[key] = [] + this.formGroup.get(key).value.forEach((obj, index) => { + const displayAs = (spec.spec as ListValueSpecOf<'object'>)[ + 'display-as' + ] this.objectListDisplay[key][index] = { expanded: false, height: '0px', - displayAs: displayAs ? (Mustache as any).render(displayAs, obj) : '', + displayAs: displayAs + ? (Mustache as any).render(displayAs, obj) + : '', } }) } else if (['object', 'union'].includes(spec.type)) { @@ -58,11 +82,11 @@ export class FormObjectComponent { }) } - getEnumListDisplay (arr: string[], spec: ListValueSpecOf<'enum'>): string { + getEnumListDisplay(arr: string[], spec: ListValueSpecOf<'enum'>): string { return arr.map((v: string) => spec['value-names'][v]).join(', ') } - updateUnion (e: any): void { + updateUnion(e: any): void { const primary = this.unionSpec.tag.id Object.keys(this.formGroup.controls).forEach(control => { @@ -70,26 +94,31 @@ export class FormObjectComponent { this.formGroup.removeControl(control) }) - const unionGroup = this.formService.getUnionObject(this.unionSpec as ValueSpecUnion, e.detail.value) + const unionGroup = this.formService.getUnionObject( + this.unionSpec as ValueSpecUnion, + e.detail.value, + ) Object.keys(unionGroup.controls).forEach(control => { if (control === primary) return this.formGroup.addControl(control, unionGroup.controls[control]) }) - Object.entries(this.unionSpec.variants[e.detail.value]).forEach(([key, value]) => { - if (['object', 'union'].includes(value.type)) { - this.objectDisplay[key] = { - expanded: false, - height: '0px', + Object.entries(this.unionSpec.variants[e.detail.value]).forEach( + ([key, value]) => { + if (['object', 'union'].includes(value.type)) { + this.objectDisplay[key] = { + expanded: false, + height: '0px', + } } - } - }) + }, + ) this.onExpand.emit() } - resize (key: string, i?: number): void { + resize(key: string, i?: number): void { setTimeout(() => { if (i !== undefined) { this.objectListDisplay[key][i].height = this.getDocSize(key, i) @@ -100,11 +129,11 @@ export class FormObjectComponent { }, 250) // 250 to match transition-duration, defined in html } - addListItemWrapper (key: string, spec: ValueSpec) { + addListItemWrapper(key: string, spec: ValueSpec) { this.presentAlertChangeWarning(key, spec, () => this.addListItem(key)) } - addListItem (key: string, markDirty = true, val?: string): void { + addListItem(key: string, markDirty = true, val?: string): void { const arr = this.formGroup.get(key) as FormArray if (markDirty) arr.markAsDirty() const listSpec = this.objectSpec[key] as ValueSpecList @@ -112,7 +141,9 @@ export class FormObjectComponent { newItem.markAllAsTouched() arr.insert(0, newItem) if (['object', 'union'].includes(listSpec.subtype)) { - const displayAs = (listSpec.spec as ListValueSpecOf<'object'>)['display-as'] + const displayAs = (listSpec.spec as ListValueSpecOf<'object'>)[ + 'display-as' + ] this.objectListDisplay[key].unshift({ height: '0px', expanded: true, @@ -125,30 +156,39 @@ export class FormObjectComponent { } } - toggleExpandObject (key: string) { + toggleExpandObject(key: string) { this.objectDisplay[key].expanded = !this.objectDisplay[key].expanded - this.objectDisplay[key].height = this.objectDisplay[key].expanded ? this.getDocSize(key) : '0px' + this.objectDisplay[key].height = this.objectDisplay[key].expanded + ? this.getDocSize(key) + : '0px' this.onExpand.emit() } - toggleExpandListObject (key: string, i: number) { - this.objectListDisplay[key][i].expanded = !this.objectListDisplay[key][i].expanded - this.objectListDisplay[key][i].height = this.objectListDisplay[key][i].expanded ? this.getDocSize(key, i) : '0px' + toggleExpandListObject(key: string, i: number) { + this.objectListDisplay[key][i].expanded = + !this.objectListDisplay[key][i].expanded + this.objectListDisplay[key][i].height = this.objectListDisplay[key][i] + .expanded + ? this.getDocSize(key, i) + : '0px' } - updateLabel (key: string, i: number, displayAs: string) { - this.objectListDisplay[key][i].displayAs = displayAs ? Mustache.render(displayAs, this.formGroup.get(key).value[i]) : '' + updateLabel(key: string, i: number, displayAs: string) { + this.objectListDisplay[key][i].displayAs = displayAs + ? Mustache.render(displayAs, this.formGroup.get(key).value[i]) + : '' } - getWarningText (text: string): IonicSafeString { - if (text) return new IonicSafeString(`${text}`) + getWarningText(text: string): IonicSafeString { + if (text) + return new IonicSafeString(`${text}`) } - handleInputChange () { + handleInputChange() { this.onInputChange.emit() } - handleBooleanChange (key: string, spec: ValueSpecBoolean) { + handleBooleanChange(key: string, spec: ValueSpecBoolean) { if (spec.warning) { const current = this.formGroup.get(key).value const cancelFn = () => this.formGroup.get(key).setValue(!current) @@ -156,7 +196,11 @@ export class FormObjectComponent { } } - async presentModalEnumList (key: string, spec: ValueSpecListOf<'enum'>, current: string[]) { + async presentModalEnumList( + key: string, + spec: ValueSpecListOf<'enum'>, + current: string[], + ) { const modal = await this.modalCtrl.create({ componentProps: { key, @@ -175,7 +219,12 @@ export class FormObjectComponent { await modal.present() } - async presentAlertChangeWarning (key: string, spec: ValueSpec, okFn?: Function, cancelFn?: Function) { + async presentAlertChangeWarning( + key: string, + spec: ValueSpec, + okFn?: Function, + cancelFn?: Function, + ) { if (!spec.warning || this.warningAck[key]) return okFn ? okFn() : null this.warningAck[key] = true @@ -207,7 +256,7 @@ export class FormObjectComponent { await alert.present() } - async presentAlertDelete (key: string, index: number) { + async presentAlertDelete(key: string, index: number) { const alert = await this.alertCtrl.create({ header: 'Confirm', message: 'Are you sure you want to delete this entry?', @@ -228,17 +277,19 @@ export class FormObjectComponent { await alert.present() } - private deleteListItem (key: string, index: number, markDirty = true): void { - if (this.objectListDisplay[key]) this.objectListDisplay[key][index].height = '0px' + private deleteListItem(key: string, index: number, markDirty = true): void { + if (this.objectListDisplay[key]) + this.objectListDisplay[key][index].height = '0px' const arr = this.formGroup.get(key) as FormArray if (markDirty) arr.markAsDirty() pauseFor(250).then(() => { - if (this.objectListDisplay[key]) this.objectListDisplay[key].splice(index, 1) + if (this.objectListDisplay[key]) + this.objectListDisplay[key].splice(index, 1) arr.removeAt(index) }) } - private updateEnumList (key: string, current: string[], updated: string[]) { + private updateEnumList(key: string, current: string[], updated: string[]) { this.formGroup.get(key).markAsDirty() for (let i = current.length - 1; i >= 0; i--) { @@ -254,17 +305,16 @@ export class FormObjectComponent { }) } - private getDocSize (key: string, index = 0) { + private getDocSize(key: string, index = 0) { const element = document.getElementById(this.getElementId(key, index)) return `${element.scrollHeight}px` } - getElementId (key: string, index = 0): string { + getElementId(key: string, index = 0): string { return `${key}-${index}-${this.objectId}` } - async presentUnionTagDescription (name: string, description: string) { - + async presentUnionTagDescription(name: string, description: string) { const alert = await this.alertCtrl.create({ header: name, message: description, @@ -272,7 +322,7 @@ export class FormObjectComponent { await alert.present() } - asIsOrder () { + asIsOrder() { return 0 } } @@ -293,11 +343,9 @@ export class FormLabelComponent { Range = Range @Input() data: HeaderData - constructor ( - private readonly alertCtrl: AlertController, - ) { } + constructor(private readonly alertCtrl: AlertController) {} - async presentAlertDescription () { + async presentAlertDescription() { const { name, description } = this.data.spec const alert = await this.alertCtrl.create({ @@ -308,7 +356,6 @@ export class FormLabelComponent { } } - @Component({ selector: 'form-error', templateUrl: './form-error.component.html', diff --git a/frontend/projects/ui/src/app/components/install-wizard/alert/alert.component.module.ts b/frontend/projects/ui/src/app/components/install-wizard/alert/alert.component.module.ts index aa94a390d..efed93a4d 100644 --- a/frontend/projects/ui/src/app/components/install-wizard/alert/alert.component.module.ts +++ b/frontend/projects/ui/src/app/components/install-wizard/alert/alert.component.module.ts @@ -3,18 +3,16 @@ import { CommonModule } from '@angular/common' import { AlertComponent } from './alert.component' import { IonicModule } from '@ionic/angular' import { RouterModule } from '@angular/router' -import { SharingModule } from 'src/app/modules/sharing.module' +import { MarkdownPipeModule } from '@start9labs/shared' @NgModule({ - declarations: [ - AlertComponent, - ], + declarations: [AlertComponent], imports: [ CommonModule, IonicModule, RouterModule.forChild([]), - SharingModule, + MarkdownPipeModule, ], exports: [AlertComponent], }) -export class AlertComponentModule { } +export class AlertComponentModule {} diff --git a/frontend/projects/ui/src/app/components/install-wizard/complete/complete.component.ts b/frontend/projects/ui/src/app/components/install-wizard/complete/complete.component.ts index 721d05f19..d88b53465 100644 --- a/frontend/projects/ui/src/app/components/install-wizard/complete/complete.component.ts +++ b/frontend/projects/ui/src/app/components/install-wizard/complete/complete.component.ts @@ -1,7 +1,7 @@ import { Component, Input } from '@angular/core' import { BehaviorSubject, from, Subject } from 'rxjs' import { takeUntil } from 'rxjs/operators' -import { capitalizeFirstLetter } from 'src/app/util/misc.util' +import { capitalizeFirstLetter } from '@start9labs/shared' import { markAsLoadingDuring$ } from '../loadable' import { WizardAction } from '../wizard-types' @@ -30,16 +30,21 @@ export class CompleteComponent { message: string - load () { - markAsLoadingDuring$(this.loading$, from(this.params.executeAction())).pipe(takeUntil(this.cancel$)).subscribe( - { - error: e => this.transitions.error(new Error(`${this.params.action} failed: ${e.message || e}`)), + load() { + markAsLoadingDuring$(this.loading$, from(this.params.executeAction())) + .pipe(takeUntil(this.cancel$)) + .subscribe({ + error: e => + this.transitions.error( + new Error(`${this.params.action} failed: ${e.message || e}`), + ), complete: () => this.transitions.final(), - }, - ) + }) } - ngOnInit () { - this.message = `${capitalizeFirstLetter(this.params.verb)} ${this.params.title}...` + ngOnInit() { + this.message = `${capitalizeFirstLetter(this.params.verb)} ${ + this.params.title + }...` } } diff --git a/frontend/projects/ui/src/app/components/install-wizard/dependents/dependents.component.module.ts b/frontend/projects/ui/src/app/components/install-wizard/dependents/dependents.component.module.ts index ded0ae5f3..9a1ae0efc 100644 --- a/frontend/projects/ui/src/app/components/install-wizard/dependents/dependents.component.module.ts +++ b/frontend/projects/ui/src/app/components/install-wizard/dependents/dependents.component.module.ts @@ -3,18 +3,16 @@ import { CommonModule } from '@angular/common' import { DependentsComponent } from './dependents.component' import { IonicModule } from '@ionic/angular' import { RouterModule } from '@angular/router' -import { SharingModule } from 'src/app/modules/sharing.module' +import { SharedPipesModule } from '@start9labs/shared' @NgModule({ - declarations: [ - DependentsComponent, - ], + declarations: [DependentsComponent], imports: [ CommonModule, IonicModule, RouterModule.forChild([]), - SharingModule, + SharedPipesModule, ], exports: [DependentsComponent], }) -export class DependentsComponentModule { } +export class DependentsComponentModule {} diff --git a/frontend/projects/ui/src/app/components/install-wizard/dependents/dependents.component.ts b/frontend/projects/ui/src/app/components/install-wizard/dependents/dependents.component.ts index 7f3d92bdf..0c781ac5d 100644 --- a/frontend/projects/ui/src/app/components/install-wizard/dependents/dependents.component.ts +++ b/frontend/projects/ui/src/app/components/install-wizard/dependents/dependents.component.ts @@ -3,7 +3,7 @@ import { BehaviorSubject, from, Subject } from 'rxjs' import { takeUntil, tap } from 'rxjs/operators' import { Breakages } from 'src/app/services/api/api.types' import { PatchDbService } from 'src/app/services/patch-db/patch-db.service' -import { capitalizeFirstLetter, isEmptyObject } from 'src/app/util/misc.util' +import { capitalizeFirstLetter, isEmptyObject } from '@start9labs/shared' import { markAsLoadingDuring$ } from '../loadable' import { WizardAction } from '../wizard-types' @@ -14,9 +14,9 @@ import { WizardAction } from '../wizard-types' }) export class DependentsComponent { @Input() params: { - title: string, - action: WizardAction, //Are you sure you want to *uninstall*..., - verb: string, // *Uninstalling* will cause problems... + title: string + action: WizardAction //Are you sure you want to *uninstall*..., + verb: string // *Uninstalling* will cause problems... fetchBreakages: () => Promise } @Input() transitions: { @@ -32,27 +32,37 @@ export class DependentsComponent { loading$ = new BehaviorSubject(false) cancel$ = new Subject() - constructor ( - public readonly patch: PatchDbService, - ) { } + constructor(public readonly patch: PatchDbService) {} - load () { + load() { markAsLoadingDuring$(this.loading$, from(this.params.fetchBreakages())) - .pipe( - takeUntil(this.cancel$), - tap(breakages => this.dependentBreakages = breakages), - ) - .subscribe( - { + .pipe( + takeUntil(this.cancel$), + tap(breakages => (this.dependentBreakages = breakages)), + ) + .subscribe({ complete: () => { - if (this.dependentBreakages && !isEmptyObject(this.dependentBreakages)) { - this.dependentViolation = `${capitalizeFirstLetter(this.params.verb)} ${this.params.title} will prohibit the following services from functioning properly and may cause them to stop if they are currently running.` + if ( + this.dependentBreakages && + !isEmptyObject(this.dependentBreakages) + ) { + this.dependentViolation = `${capitalizeFirstLetter( + this.params.verb, + )} ${ + this.params.title + } will prohibit the following services from functioning properly and may cause them to stop if they are currently running.` } else { this.transitions.next() } }, - error: (e: Error) => this.transitions.error(new Error(`Fetching dependent service information failed: ${e.message || e}`)), - }, - ) + error: (e: Error) => + this.transitions.error( + new Error( + `Fetching dependent service information failed: ${ + e.message || e + }`, + ), + ), + }) } } diff --git a/frontend/projects/ui/src/app/components/install-wizard/install-wizard.component.module.ts b/frontend/projects/ui/src/app/components/install-wizard/install-wizard.component.module.ts index 7d5c7d67c..a40e85c66 100644 --- a/frontend/projects/ui/src/app/components/install-wizard/install-wizard.component.module.ts +++ b/frontend/projects/ui/src/app/components/install-wizard/install-wizard.component.module.ts @@ -3,21 +3,19 @@ import { CommonModule } from '@angular/common' import { InstallWizardComponent } from './install-wizard.component' import { IonicModule } from '@ionic/angular' import { RouterModule } from '@angular/router' -import { SharingModule } from 'src/app/modules/sharing.module' +import { EmverPipesModule } from '@start9labs/shared' import { DependentsComponentModule } from './dependents/dependents.component.module' import { CompleteComponentModule } from './complete/complete.component.module' import { NotesComponentModule } from './notes/notes.component.module' import { AlertComponentModule } from './alert/alert.component.module' @NgModule({ - declarations: [ - InstallWizardComponent, - ], + declarations: [InstallWizardComponent], imports: [ CommonModule, IonicModule, RouterModule.forChild([]), - SharingModule, + EmverPipesModule, DependentsComponentModule, CompleteComponentModule, NotesComponentModule, @@ -25,4 +23,4 @@ import { AlertComponentModule } from './alert/alert.component.module' ], exports: [InstallWizardComponent], }) -export class InstallWizardComponentModule { } +export class InstallWizardComponentModule {} diff --git a/frontend/projects/ui/src/app/components/install-wizard/install-wizard.component.ts b/frontend/projects/ui/src/app/components/install-wizard/install-wizard.component.ts index fb85d9033..94e74c8c0 100644 --- a/frontend/projects/ui/src/app/components/install-wizard/install-wizard.component.ts +++ b/frontend/projects/ui/src/app/components/install-wizard/install-wizard.component.ts @@ -1,6 +1,13 @@ -import { Component, Input, NgZone, QueryList, ViewChild, ViewChildren } from '@angular/core' +import { + Component, + Input, + NgZone, + QueryList, + ViewChild, + ViewChildren, +} from '@angular/core' import { IonContent, IonSlides, ModalController } from '@ionic/angular' -import { capitalizeFirstLetter, pauseFor } from 'src/app/util/misc.util' +import { capitalizeFirstLetter, pauseFor } from '@start9labs/shared' import { CompleteComponent } from './complete/complete.component' import { DependentsComponent } from './dependents/dependents.component' import { AlertComponent } from './alert/alert.component' @@ -30,54 +37,70 @@ export class InstallWizardComponent { //a slide component gives us hook into a slide. Allows us to call load when slide comes into view @ViewChildren('components') slideComponentsQL: QueryList - get slideComponents (): Loadable[] { return this.slideComponentsQL.toArray() } + get slideComponents(): Loadable[] { + return this.slideComponentsQL.toArray() + } private slideIndex = 0 - get currentSlide (): Loadable { + get currentSlide(): Loadable { return this.slideComponents[this.slideIndex] } - get currentBottomBar (): SlideDefinition['bottomBar'] { + get currentBottomBar(): SlideDefinition['bottomBar'] { return this.params.slideDefinitions[this.slideIndex].bottomBar } initializing = true error = '' - constructor ( + constructor( private readonly modalController: ModalController, private readonly zone: NgZone, - ) { } + ) {} - ngAfterViewInit () { + ngAfterViewInit() { this.currentSlide.load() this.slideContainer.update() this.slideContainer.lockSwipes(true) } - ionViewDidEnter () { + ionViewDidEnter() { this.initializing = false } // process bottom bar buttons - private transition = (info: { next: any } | { error: Error } | { cancelled: true } | { final: true }) => { - const i = info as { next?: any, error?: Error, cancelled?: true, final?: true } + private transition = ( + info: + | { next: any } + | { error: Error } + | { cancelled: true } + | { final: true }, + ) => { + const i = info as { + next?: any + error?: Error + cancelled?: true + final?: true + } if (i.cancelled) this.currentSlide.cancel$.next() if (i.final || i.cancelled) return this.modalController.dismiss(i) - if (i.error) return this.error = capitalizeFirstLetter(i.error.message) + if (i.error) return (this.error = capitalizeFirstLetter(i.error.message)) this.moveToNextSlide(i.next) } // bottom bar button callbacks. Pass this into components if they need to trigger slide transitions independent of the bottom bar clicks transitions = { - next: (prevResult: any) => this.transition({ next: prevResult || this.currentSlide.result }), + next: (prevResult: any) => + this.transition({ next: prevResult || this.currentSlide.result }), cancel: () => this.transition({ cancelled: true }), final: () => this.transition({ final: true }), error: (e: Error) => this.transition({ error: e }), } - private async moveToNextSlide (prevResult?: any) { - if (this.slideComponents[this.slideIndex + 1] === undefined) { return this.transition({ final: true }) } + private async moveToNextSlide(prevResult?: any) { + if (this.slideComponents[this.slideIndex + 1] === undefined) { + return this.transition({ final: true }) + } this.zone.run(async () => { this.slideComponents[this.slideIndex + 1].load(prevResult) await pauseFor(50) // give the load ^ opportunity to propogate into slide before sliding it into view @@ -89,7 +112,7 @@ export class InstallWizardComponent { }) } - async callTransition (transition: Function) { + async callTransition(transition: Function) { this.transitioning = true await transition() this.transitioning = false @@ -98,14 +121,14 @@ export class InstallWizardComponent { export interface SlideDefinition { slide: - { selector: 'dependents', params: DependentsComponent['params'] } | - { selector: 'complete', params: CompleteComponent['params'] } | - { selector: 'alert', params: AlertComponent['params'] } | - { selector: 'notes', params: NotesComponent['params'] } + | { selector: 'dependents'; params: DependentsComponent['params'] } + | { selector: 'complete'; params: CompleteComponent['params'] } + | { selector: 'alert'; params: AlertComponent['params'] } + | { selector: 'notes'; params: NotesComponent['params'] } bottomBar: { cancel: { // indicates the existence of a cancel button, and whether to have text or an icon 'x' by default. - afterLoading?: { text?: string }, + afterLoading?: { text?: string } whileLoading?: { text?: string } } // indicates the existence of next or finish buttons (should only have one) @@ -114,11 +137,16 @@ export interface SlideDefinition { } } -export type TopbarParams = { action: WizardAction, title: string, version: string } +export type TopbarParams = { + action: WizardAction + title: string + version: string +} -export async function wizardModal ( - modalController: ModalController, params: InstallWizardComponent['params'], -): Promise<{ cancelled?: true, final?: true, modal: HTMLIonModalElement }> { +export async function wizardModal( + modalController: ModalController, + params: InstallWizardComponent['params'], +): Promise<{ cancelled?: true; final?: true; modal: HTMLIonModalElement }> { const modal = await modalController.create({ backdropDismiss: false, cssClass: 'wizard-modal', diff --git a/frontend/projects/ui/src/app/components/install-wizard/notes/notes.component.module.ts b/frontend/projects/ui/src/app/components/install-wizard/notes/notes.component.module.ts index bb5e36bf7..5257edbdc 100644 --- a/frontend/projects/ui/src/app/components/install-wizard/notes/notes.component.module.ts +++ b/frontend/projects/ui/src/app/components/install-wizard/notes/notes.component.module.ts @@ -3,18 +3,16 @@ import { CommonModule } from '@angular/common' import { NotesComponent } from './notes.component' import { IonicModule } from '@ionic/angular' import { RouterModule } from '@angular/router' -import { SharingModule } from 'src/app/modules/sharing.module' +import { MarkdownPipeModule } from '@start9labs/shared' @NgModule({ - declarations: [ - NotesComponent, - ], + declarations: [NotesComponent], imports: [ CommonModule, IonicModule, RouterModule.forChild([]), - SharingModule, + MarkdownPipeModule, ], exports: [NotesComponent], }) -export class NotesComponentModule { } +export class NotesComponentModule {} diff --git a/frontend/projects/ui/src/app/components/install-wizard/prebaked-wizards.ts b/frontend/projects/ui/src/app/components/install-wizard/prebaked-wizards.ts index 65492a85f..8256a1d53 100644 --- a/frontend/projects/ui/src/app/components/install-wizard/prebaked-wizards.ts +++ b/frontend/projects/ui/src/app/components/install-wizard/prebaked-wizards.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core' import { PackageDataEntry } from 'src/app/services/patch-db/data-model' import { Breakages } from 'src/app/services/api/api.types' -import { exists } from 'src/app/util/misc.util' +import { exists } from '@start9labs/shared' import { ApiService } from '../../services/api/embassy-api.service' import { InstallWizardComponent, diff --git a/frontend/projects/ui/src/app/components/logs/logs.module.ts b/frontend/projects/ui/src/app/components/logs/logs.module.ts index d68a287ce..1ee7bcca7 100644 --- a/frontend/projects/ui/src/app/components/logs/logs.module.ts +++ b/frontend/projects/ui/src/app/components/logs/logs.module.ts @@ -2,15 +2,11 @@ import { NgModule } from '@angular/core' import { CommonModule } from '@angular/common' import { IonicModule } from '@ionic/angular' import { LogsPage } from './logs.page' -import { SharingModule } from 'src/app/modules/sharing.module' +import { TextSpinnerComponentModule } from '@start9labs/shared' @NgModule({ declarations: [LogsPage], - imports: [ - CommonModule, - IonicModule, - SharingModule, - ], + imports: [CommonModule, IonicModule, TextSpinnerComponentModule], exports: [LogsPage], }) -export class LogsPageModule { } +export class LogsPageModule {} diff --git a/frontend/projects/ui/src/app/components/status/status.component.html b/frontend/projects/ui/src/app/components/status/status.component.html index facbb64a9..53bc8ef14 100644 --- a/frontend/projects/ui/src/app/components/status/status.component.html +++ b/frontend/projects/ui/src/app/components/status/status.component.html @@ -1,13 +1,21 @@

- + {{ disconnected ? 'Unknown' : rendering.display }} - This may take a while. + This may take a while. @@ -19,5 +27,4 @@ -

diff --git a/frontend/projects/ui/src/app/components/status/status.component.module.ts b/frontend/projects/ui/src/app/components/status/status.component.module.ts index 2843cd574..349e5e1fb 100644 --- a/frontend/projects/ui/src/app/components/status/status.component.module.ts +++ b/frontend/projects/ui/src/app/components/status/status.component.module.ts @@ -1,18 +1,12 @@ import { NgModule } from '@angular/core' import { CommonModule } from '@angular/common' -import { StatusComponent } from './status.component' import { IonicModule } from '@ionic/angular' -import { SharingModule } from 'src/app/modules/sharing.module' +import { UnitConversionPipesModule } from '@start9labs/shared' +import { StatusComponent } from './status.component' @NgModule({ - declarations: [ - StatusComponent, - ], - imports: [ - CommonModule, - IonicModule, - SharingModule, - ], + declarations: [StatusComponent], + imports: [CommonModule, IonicModule, UnitConversionPipesModule], exports: [StatusComponent], }) -export class StatusComponentModule { } +export class StatusComponentModule {} diff --git a/frontend/projects/ui/src/app/components/status/status.component.ts b/frontend/projects/ui/src/app/components/status/status.component.ts index 4c96cbbf6..bff9823ad 100644 --- a/frontend/projects/ui/src/app/components/status/status.component.ts +++ b/frontend/projects/ui/src/app/components/status/status.component.ts @@ -1,5 +1,9 @@ import { Component, Input } from '@angular/core' -import { PrimaryRendering, PrimaryStatus, StatusRendering } from 'src/app/services/pkg-status-rendering.service' +import { + PrimaryRendering, + PrimaryStatus, + StatusRendering, +} from 'src/app/services/pkg-status-rendering.service' @Component({ selector: 'status', @@ -18,4 +22,3 @@ export class StatusComponent { @Input() installProgress?: number @Input() sigtermTimeout?: string } - diff --git a/frontend/projects/ui/src/app/components/text-spinner/text-spinner.component.scss b/frontend/projects/ui/src/app/components/text-spinner/text-spinner.component.scss deleted file mode 100644 index e69de29bb..000000000 diff --git a/frontend/projects/ui/src/app/modals/app-config/app-config.module.ts b/frontend/projects/ui/src/app/modals/app-config/app-config.module.ts index 59a23157d..fde422826 100644 --- a/frontend/projects/ui/src/app/modals/app-config/app-config.module.ts +++ b/frontend/projects/ui/src/app/modals/app-config/app-config.module.ts @@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common' import { FormsModule, ReactiveFormsModule } from '@angular/forms' import { IonicModule } from '@ionic/angular' import { AppConfigPage } from './app-config.page' -import { SharingModule } from 'src/app/modules/sharing.module' +import { TextSpinnerComponentModule } from '@start9labs/shared' import { FormObjectComponentModule } from 'src/app/components/form-object/form-object.component.module' @NgModule({ @@ -12,10 +12,10 @@ import { FormObjectComponentModule } from 'src/app/components/form-object/form-o CommonModule, FormsModule, IonicModule, - SharingModule, + TextSpinnerComponentModule, FormObjectComponentModule, ReactiveFormsModule, ], exports: [AppConfigPage], }) -export class AppConfigPageModule { } +export class AppConfigPageModule {} diff --git a/frontend/projects/ui/src/app/modals/app-config/app-config.page.ts b/frontend/projects/ui/src/app/modals/app-config/app-config.page.ts index 692ac7d33..609acc4ac 100644 --- a/frontend/projects/ui/src/app/modals/app-config/app-config.page.ts +++ b/frontend/projects/ui/src/app/modals/app-config/app-config.page.ts @@ -7,7 +7,7 @@ import { IonicSafeString, } from '@ionic/angular' import { ApiService } from 'src/app/services/api/embassy-api.service' -import { DependentInfo, isEmptyObject, isObject } from 'src/app/util/misc.util' +import { DependentInfo, isEmptyObject, isObject } from '@start9labs/shared' import { wizardModal } from 'src/app/components/install-wizard/install-wizard.component' import { WizardBaker } from 'src/app/components/install-wizard/prebaked-wizards' import { ConfigSpec } from 'src/app/pkg-config/config-types' diff --git a/frontend/projects/ui/src/app/modals/app-recover-select/app-recover-select.page.ts b/frontend/projects/ui/src/app/modals/app-recover-select/app-recover-select.page.ts index 4c3dba33b..73b7fa7ad 100644 --- a/frontend/projects/ui/src/app/modals/app-recover-select/app-recover-select.page.ts +++ b/frontend/projects/ui/src/app/modals/app-recover-select/app-recover-select.page.ts @@ -1,9 +1,13 @@ import { Component, Input } from '@angular/core' -import { LoadingController, ModalController, IonicSafeString } from '@ionic/angular' +import { + LoadingController, + ModalController, + IonicSafeString, +} from '@ionic/angular' import { BackupInfo, PackageBackupInfo } from 'src/app/services/api/api.types' import { ApiService } from 'src/app/services/api/embassy-api.service' import { ConfigService } from 'src/app/services/config.service' -import { Emver } from 'src/app/services/emver.service' +import { Emver } from '@start9labs/shared' import { getErrorMessage } from 'src/app/services/error-toast.service' import { PatchDbService } from 'src/app/services/patch-db/patch-db.service' @@ -26,39 +30,43 @@ export class AppRecoverSelectPage { hasSelection = false error: string | IonicSafeString - constructor ( + constructor( private readonly modalCtrl: ModalController, private readonly loadingCtrl: LoadingController, private readonly embassyApi: ApiService, private readonly config: ConfigService, private readonly emver: Emver, private readonly patch: PatchDbService, - ) { } + ) {} - ngOnInit () { + ngOnInit() { this.options = Object.keys(this.backupInfo['package-backups']).map(id => { return { ...this.backupInfo['package-backups'][id], id, checked: false, installed: !!this.patch.getData()['package-data'][id], - 'newer-eos': this.emver.compare(this.backupInfo['package-backups'][id]['os-version'], this.config.version) === 1, + 'newer-eos': + this.emver.compare( + this.backupInfo['package-backups'][id]['os-version'], + this.config.version, + ) === 1, } }) } - dismiss () { + dismiss() { this.modalCtrl.dismiss() } - handleChange () { + handleChange() { this.hasSelection = this.options.some(o => o.checked) } - async restore (): Promise { + async restore(): Promise { const ids = this.options - .filter(option => !!option.checked) - .map(option => option.id) + .filter(option => !!option.checked) + .map(option => option.id) const loader = await this.loadingCtrl.create({ spinner: 'lines', diff --git a/frontend/projects/ui/src/app/modals/backup-report/backup-report.page.ts b/frontend/projects/ui/src/app/modals/backup-report/backup-report.page.ts index 26c6db1e5..0e0c3afa8 100644 --- a/frontend/projects/ui/src/app/modals/backup-report/backup-report.page.ts +++ b/frontend/projects/ui/src/app/modals/backup-report/backup-report.page.ts @@ -16,11 +16,9 @@ export class BackupReportPage { color: 'dark' | 'danger' | 'success' } - constructor ( - private readonly modalCtrl: ModalController, - ) { } + constructor(private readonly modalCtrl: ModalController) {} - ngOnInit () { + ngOnInit() { if (!this.report.server.attempted) { this.system = { result: 'Not Attempted', @@ -42,7 +40,7 @@ export class BackupReportPage { } } - async dismiss () { + async dismiss() { return this.modalCtrl.dismiss(true) } } diff --git a/frontend/projects/ui/src/app/modals/enum-list/enum-list.page.ts b/frontend/projects/ui/src/app/modals/enum-list/enum-list.page.ts index 7437efd6c..a9eba7074 100644 --- a/frontend/projects/ui/src/app/modals/enum-list/enum-list.page.ts +++ b/frontend/projects/ui/src/app/modals/enum-list/enum-list.page.ts @@ -1,6 +1,6 @@ import { Component, Input } from '@angular/core' import { ModalController } from '@ionic/angular' -import { ValueSpecListOf } from '../../pkg-config/config-types' +import { ValueSpecListOf } from 'src/app/pkg-config/config-types' @Component({ selector: 'enum-list', @@ -11,37 +11,37 @@ export class EnumListPage { @Input() key: string @Input() spec: ValueSpecListOf<'enum'> @Input() current: string[] - options: { [option: string]: boolean } = { } + options: { [option: string]: boolean } = {} selectAll = true - constructor ( - private readonly modalCtrl: ModalController, - ) { } + constructor(private readonly modalCtrl: ModalController) {} - ngOnInit () { + ngOnInit() { for (let val of this.spec.spec.values) { this.options[val] = this.current.includes(val) } } - dismiss () { + dismiss() { this.modalCtrl.dismiss() } - save () { - this.modalCtrl.dismiss(Object.keys(this.options).filter(key => this.options[key])) + save() { + this.modalCtrl.dismiss( + Object.keys(this.options).filter(key => this.options[key]), + ) } - toggleSelectAll () { - Object.keys(this.options).forEach(k => this.options[k] = this.selectAll) + toggleSelectAll() { + Object.keys(this.options).forEach(k => (this.options[k] = this.selectAll)) this.selectAll = !this.selectAll } - toggleSelected (key: string) { + toggleSelected(key: string) { this.options[key] = !this.options[key] } - asIsOrder () { + asIsOrder() { return 0 } } diff --git a/frontend/projects/ui/src/app/modals/generic-form/generic-form.page.ts b/frontend/projects/ui/src/app/modals/generic-form/generic-form.page.ts index 54c66d825..47db0dc9f 100644 --- a/frontend/projects/ui/src/app/modals/generic-form/generic-form.page.ts +++ b/frontend/projects/ui/src/app/modals/generic-form/generic-form.page.ts @@ -1,7 +1,10 @@ import { Component, Input } from '@angular/core' import { FormGroup } from '@angular/forms' import { ModalController } from '@ionic/angular' -import { convertValuesRecursive, FormService } from 'src/app/services/form.service' +import { + convertValuesRecursive, + FormService, +} from 'src/app/services/form.service' import { ConfigSpec } from 'src/app/pkg-config/config-types' export interface ActionButton { @@ -19,16 +22,16 @@ export class GenericFormPage { @Input() title: string @Input() spec: ConfigSpec @Input() buttons: ActionButton[] - @Input() initialValue: object = { } + @Input() initialValue: object = {} submitBtn: ActionButton formGroup: FormGroup - constructor ( + constructor( private readonly modalCtrl: ModalController, private readonly formService: FormService, - ) { } + ) {} - ngOnInit () { + ngOnInit() { this.formGroup = this.formService.createForm(this.spec, this.initialValue) this.submitBtn = this.buttons.find(btn => btn.isSubmit) || { text: '', @@ -36,16 +39,18 @@ export class GenericFormPage { } } - async dismiss (): Promise { + async dismiss(): Promise { this.modalCtrl.dismiss() } - async handleClick (handler: ActionButton['handler']): Promise { + async handleClick(handler: ActionButton['handler']): Promise { convertValuesRecursive(this.spec, this.formGroup) if (this.formGroup.invalid) { this.formGroup.markAllAsTouched() - document.getElementsByClassName('validation-error')[0].parentElement.parentElement.scrollIntoView({ behavior: 'smooth' }) + document + .getElementsByClassName('validation-error')[0] + .parentElement.parentElement.scrollIntoView({ behavior: 'smooth' }) return } diff --git a/frontend/projects/ui/src/app/modals/generic-input/generic-input.component.module.ts b/frontend/projects/ui/src/app/modals/generic-input/generic-input.component.module.ts index 4f4d73e69..d2b1faab4 100644 --- a/frontend/projects/ui/src/app/modals/generic-input/generic-input.component.module.ts +++ b/frontend/projects/ui/src/app/modals/generic-input/generic-input.component.module.ts @@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common' import { GenericInputComponent } from './generic-input.component' import { IonicModule } from '@ionic/angular' import { RouterModule } from '@angular/router' -import { SharingModule } from 'src/app/modules/sharing.module' +import { SharedPipesModule } from '@start9labs/shared' import { FormsModule } from '@angular/forms' @NgModule({ @@ -13,8 +13,8 @@ import { FormsModule } from '@angular/forms' IonicModule, FormsModule, RouterModule.forChild([]), - SharingModule, + SharedPipesModule, ], exports: [GenericInputComponent], }) -export class GenericInputComponentModule { } +export class GenericInputComponentModule {} diff --git a/frontend/projects/ui/src/app/modals/markdown/markdown.module.ts b/frontend/projects/ui/src/app/modals/markdown/markdown.module.ts index 4cc640011..867bdd017 100644 --- a/frontend/projects/ui/src/app/modals/markdown/markdown.module.ts +++ b/frontend/projects/ui/src/app/modals/markdown/markdown.module.ts @@ -2,15 +2,19 @@ import { NgModule } from '@angular/core' import { CommonModule } from '@angular/common' import { IonicModule } from '@ionic/angular' import { MarkdownPage } from './markdown.page' -import { SharingModule } from 'src/app/modules/sharing.module' +import { + MarkdownPipeModule, + TextSpinnerComponentModule, +} from '@start9labs/shared' @NgModule({ declarations: [MarkdownPage], imports: [ CommonModule, IonicModule, - SharingModule, + MarkdownPipeModule, + TextSpinnerComponentModule, ], exports: [MarkdownPage], }) -export class MarkdownPageModule { } +export class MarkdownPageModule {} diff --git a/frontend/projects/ui/src/app/modals/os-welcome/os-welcome.module.ts b/frontend/projects/ui/src/app/modals/os-welcome/os-welcome.module.ts index 74ea3cfbf..3e910403e 100644 --- a/frontend/projects/ui/src/app/modals/os-welcome/os-welcome.module.ts +++ b/frontend/projects/ui/src/app/modals/os-welcome/os-welcome.module.ts @@ -2,17 +2,12 @@ import { NgModule } from '@angular/core' import { CommonModule } from '@angular/common' import { IonicModule } from '@ionic/angular' import { OSWelcomePage } from './os-welcome.page' -import { SharingModule } from 'src/app/modules/sharing.module' +import { SharedPipesModule } from '@start9labs/shared' import { FormsModule } from '@angular/forms' @NgModule({ declarations: [OSWelcomePage], - imports: [ - CommonModule, - IonicModule, - FormsModule, - SharingModule, - ], + imports: [CommonModule, IonicModule, FormsModule, SharedPipesModule], exports: [OSWelcomePage], }) -export class OSWelcomePageModule { } +export class OSWelcomePageModule {} diff --git a/frontend/projects/ui/src/app/modules/sharing.module.ts b/frontend/projects/ui/src/app/modules/sharing.module.ts deleted file mode 100644 index c783c9cc2..000000000 --- a/frontend/projects/ui/src/app/modules/sharing.module.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { NgModule } from '@angular/core' -import { - EmverComparesPipe, - EmverSatisfiesPipe, - EmverDisplayPipe, -} from '../pipes/emver.pipe' -import { IncludesPipe } from '../pipes/includes.pipe' -import { TypeofPipe } from '../pipes/typeof.pipe' -import { MarkdownPipe } from '../pipes/markdown.pipe' -import { - TruncateCenterPipe, - TruncateEndPipe, - TruncateTailPipe, -} from '../pipes/truncate.pipe' -import { MaskPipe } from '../pipes/mask.pipe' -import { HasUiPipe, LaunchablePipe, SanitizePipe } from '../pipes/ui.pipe' -import { EmptyPipe } from '../pipes/empty.pipe' -import { NotificationColorPipe } from '../pipes/notification-color.pipe' -import { InstallState } from '../pipes/install-state.pipe' -import { TextSpinnerComponentModule } from '../components/text-spinner/text-spinner.component.module' -import { ConvertBytesPipe } from '../pipes/convert-bytes.pipe' -import { DurationToSecondsPipe } from '../pipes/unit-conversion.pipe' -import { InstallProgressPipe } from '../pipes/install-progress.pipe' - -@NgModule({ - declarations: [ - EmverComparesPipe, - EmverSatisfiesPipe, - TypeofPipe, - IncludesPipe, - InstallProgressPipe, - InstallState, - MarkdownPipe, - TruncateCenterPipe, - TruncateEndPipe, - TruncateTailPipe, - MaskPipe, - EmverDisplayPipe, - HasUiPipe, - LaunchablePipe, - EmptyPipe, - NotificationColorPipe, - ConvertBytesPipe, - DurationToSecondsPipe, - SanitizePipe, - ], - imports: [TextSpinnerComponentModule], - exports: [ - EmverComparesPipe, - EmverSatisfiesPipe, - TypeofPipe, - IncludesPipe, - MarkdownPipe, - TruncateEndPipe, - TruncateCenterPipe, - TruncateTailPipe, - MaskPipe, - EmverDisplayPipe, - HasUiPipe, - InstallProgressPipe, - InstallState, - LaunchablePipe, - EmptyPipe, - NotificationColorPipe, - ConvertBytesPipe, - DurationToSecondsPipe, - // components - TextSpinnerComponentModule, - SanitizePipe, - ], -}) -export class SharingModule {} diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-actions/app-actions.module.ts b/frontend/projects/ui/src/app/pages/apps-routes/app-actions/app-actions.module.ts index 06e20ef09..5f30abc0e 100644 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-actions/app-actions.module.ts +++ b/frontend/projects/ui/src/app/pages/apps-routes/app-actions/app-actions.module.ts @@ -4,7 +4,7 @@ import { Routes, RouterModule } from '@angular/router' import { IonicModule } from '@ionic/angular' import { AppActionsPage, AppActionsItemComponent } from './app-actions.page' import { QRComponentModule } from 'src/app/components/qr/qr.component.module' -import { SharingModule } from 'src/app/modules/sharing.module' +import { SharedPipesModule } from '@start9labs/shared' import { GenericFormPageModule } from 'src/app/modals/generic-form/generic-form.module' import { ActionSuccessPageModule } from 'src/app/modals/action-success/action-success.module' @@ -21,13 +21,10 @@ const routes: Routes = [ IonicModule, RouterModule.forChild(routes), QRComponentModule, - SharingModule, + SharedPipesModule, GenericFormPageModule, ActionSuccessPageModule, ], - declarations: [ - AppActionsPage, - AppActionsItemComponent, - ], + declarations: [AppActionsPage, AppActionsItemComponent], }) -export class AppActionsPageModule { } +export class AppActionsPageModule {} diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-actions/app-actions.page.ts b/frontend/projects/ui/src/app/pages/apps-routes/app-actions/app-actions.page.ts index 245626389..b4032374a 100644 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-actions/app-actions.page.ts +++ b/frontend/projects/ui/src/app/pages/apps-routes/app-actions/app-actions.page.ts @@ -19,7 +19,7 @@ import { WizardBaker } from 'src/app/components/install-wizard/prebaked-wizards' import { Subscription } from 'rxjs' import { GenericFormPage } from 'src/app/modals/generic-form/generic-form.page' import { ErrorToastService } from 'src/app/services/error-toast.service' -import { isEmptyObject } from 'src/app/util/misc.util' +import { isEmptyObject } from '@start9labs/shared' import { ActionSuccessPage } from 'src/app/modals/action-success/action-success.page' @Component({ diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-interfaces/app-interfaces.module.ts b/frontend/projects/ui/src/app/pages/apps-routes/app-interfaces/app-interfaces.module.ts index 43d9e4e2f..67cc64f8f 100644 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-interfaces/app-interfaces.module.ts +++ b/frontend/projects/ui/src/app/pages/apps-routes/app-interfaces/app-interfaces.module.ts @@ -2,8 +2,11 @@ import { NgModule } from '@angular/core' import { CommonModule } from '@angular/common' import { Routes, RouterModule } from '@angular/router' import { IonicModule } from '@ionic/angular' -import { AppInterfacesItemComponent, AppInterfacesPage } from './app-interfaces.page' -import { SharingModule } from 'src/app/modules/sharing.module' +import { + AppInterfacesItemComponent, + AppInterfacesPage, +} from './app-interfaces.page' +import { SharedPipesModule } from '@start9labs/shared' const routes: Routes = [ { @@ -17,11 +20,8 @@ const routes: Routes = [ CommonModule, IonicModule, RouterModule.forChild(routes), - SharingModule, - ], - declarations: [ - AppInterfacesPage, - AppInterfacesItemComponent, + SharedPipesModule, ], + declarations: [AppInterfacesPage, AppInterfacesItemComponent], }) -export class AppInterfacesPageModule { } +export class AppInterfacesPageModule {} diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-interfaces/app-interfaces.page.ts b/frontend/projects/ui/src/app/pages/apps-routes/app-interfaces/app-interfaces.page.ts index 7b07c02fb..1b9fe3183 100644 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-interfaces/app-interfaces.page.ts +++ b/frontend/projects/ui/src/app/pages/apps-routes/app-interfaces/app-interfaces.page.ts @@ -2,7 +2,10 @@ import { Component, Input, ViewChild } from '@angular/core' import { ActivatedRoute } from '@angular/router' import { IonContent, ToastController } from '@ionic/angular' import { getUiInterfaceKey } from 'src/app/services/config.service' -import { InstalledPackageDataEntry, InterfaceDef } from 'src/app/services/patch-db/data-model' +import { + InstalledPackageDataEntry, + InterfaceDef, +} from 'src/app/services/patch-db/data-model' import { PatchDbService } from 'src/app/services/patch-db/patch-db.service' import { copyToClipboard } from 'src/app/util/web.util' @@ -22,12 +25,12 @@ export class AppInterfacesPage { other: LocalInterface[] = [] pkgId: string - constructor ( + constructor( private readonly route: ActivatedRoute, public readonly patch: PatchDbService, - ) { } + ) {} - ngOnInit () { + ngOnInit() { this.pkgId = this.route.snapshot.paramMap.get('pkgId') const pkg = this.patch.getData()['package-data'][this.pkgId] const interfaces = pkg.manifest.interfaces @@ -40,8 +43,12 @@ export class AppInterfacesPage { this.ui = { def: interfaces[uiKey], addresses: { - 'lan-address': uiAddresses['lan-address'] ? 'https://' + uiAddresses['lan-address'] : null, - 'tor-address': uiAddresses['tor-address'] ? 'http://' + uiAddresses['tor-address'] : null, + 'lan-address': uiAddresses['lan-address'] + ? 'https://' + uiAddresses['lan-address'] + : null, + 'tor-address': uiAddresses['tor-address'] + ? 'http://' + uiAddresses['tor-address'] + : null, }, } } @@ -53,18 +60,22 @@ export class AppInterfacesPage { return { def: interfaces[key], addresses: { - 'lan-address': addresses['lan-address'] ? 'https://' + addresses['lan-address'] : null, - 'tor-address': addresses['tor-address'] ? 'http://' + addresses['tor-address'] : null, + 'lan-address': addresses['lan-address'] + ? 'https://' + addresses['lan-address'] + : null, + 'tor-address': addresses['tor-address'] + ? 'http://' + addresses['tor-address'] + : null, }, } }) } - ngAfterViewInit () { + ngAfterViewInit() { this.content.scrollToPoint(undefined, 1) } - asIsOrder () { + asIsOrder() { return 0 } } @@ -77,18 +88,17 @@ export class AppInterfacesPage { export class AppInterfacesItemComponent { @Input() interface: LocalInterface - constructor ( - private readonly toastCtrl: ToastController, - ) { } + constructor(private readonly toastCtrl: ToastController) {} - launch (url: string): void { + launch(url: string): void { window.open(url, '_blank', 'noreferrer') } - async copy (address: string): Promise { + async copy(address: string): Promise { let message = '' - await copyToClipboard(address || '') - .then(success => { message = success ? 'copied to clipboard!' : 'failed to copy' }) + await copyToClipboard(address || '').then(success => { + message = success ? 'copied to clipboard!' : 'failed to copy' + }) const toast = await this.toastCtrl.create({ header: message, diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list-pkg/app-list-pkg.component.ts b/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list-pkg/app-list-pkg.component.ts index 572bcce36..1f7f0ed56 100644 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list-pkg/app-list-pkg.component.ts +++ b/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list-pkg/app-list-pkg.component.ts @@ -1,12 +1,6 @@ -import { - ChangeDetectionStrategy, - Component, - Inject, - Input, -} from '@angular/core' +import { ChangeDetectionStrategy, Component, Input } from '@angular/core' import { PackageMainStatus, - PackageDataEntry, Manifest, } from 'src/app/services/patch-db/data-model' import { PkgInfo } from 'src/app/util/get-package-info' diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list-reorder/app-list-reorder.component.ts b/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list-reorder/app-list-reorder.component.ts index 549b0b581..168ac094c 100644 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list-reorder/app-list-reorder.component.ts +++ b/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list-reorder/app-list-reorder.component.ts @@ -34,16 +34,16 @@ export class AppListReorderComponent { readonly connectionFailure$ = this.connectionService .watchFailure$() - .pipe(map((failure) => failure !== ConnectionFailure.None)) + .pipe(map(failure => failure !== ConnectionFailure.None)) - constructor (private readonly connectionService: ConnectionService) { } + constructor(private readonly connectionService: ConnectionService) {} - toggle () { + toggle() { this.reordering = !this.reordering this.reorderingChange.emit(this.reordering) } - reorder ({ detail }: CustomEvent): void { + reorder({ detail }: CustomEvent): void { this.pkgs = detail.complete([...this.pkgs]) this.pkgsChange.emit(this.pkgs) } diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list.module.ts b/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list.module.ts index c3b77d9b7..97cc80ea8 100644 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list.module.ts +++ b/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list.module.ts @@ -3,9 +3,14 @@ import { CommonModule } from '@angular/common' import { Routes, RouterModule } from '@angular/router' import { IonicModule } from '@ionic/angular' import { AppListPage } from './app-list.page' -import { StatusComponentModule } from 'src/app/components/status/status.component.module' -import { SharingModule } from 'src/app/modules/sharing.module' +import { + EmverPipesModule, + TextSpinnerComponentModule, +} from '@start9labs/shared' import { BadgeMenuComponentModule } from 'src/app/components/badge-menu-button/badge-menu.component.module' +import { StatusComponentModule } from 'src/app/components/status/status.component.module' +import { LaunchablePipeModule } from 'src/app/pipes/launchable/launchable.module' +import { UiPipeModule } from 'src/app/pipes/ui/ui.module' import { AppListIconComponent } from './app-list-icon/app-list-icon.component' import { AppListEmptyComponent } from './app-list-empty/app-list-empty.component' import { AppListPkgComponent } from './app-list-pkg/app-list-pkg.component' @@ -24,7 +29,10 @@ const routes: Routes = [ imports: [ CommonModule, StatusComponentModule, - SharingModule, + EmverPipesModule, + TextSpinnerComponentModule, + LaunchablePipeModule, + UiPipeModule, IonicModule, RouterModule.forChild(routes), BadgeMenuComponentModule, @@ -39,4 +47,4 @@ const routes: Routes = [ PackageInfoPipe, ], }) -export class AppListPageModule { } +export class AppListPageModule {} diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list.page.ts b/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list.page.ts index c6036df60..2803d77af 100644 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list.page.ts +++ b/frontend/projects/ui/src/app/pages/apps-routes/app-list/app-list.page.ts @@ -3,10 +3,9 @@ import { PatchDbService } from 'src/app/services/patch-db/patch-db.service' import { PackageDataEntry } from 'src/app/services/patch-db/data-model' import { Observable } from 'rxjs' import { filter, map, switchMapTo, take, takeUntil, tap } from 'rxjs/operators' -import { isEmptyObject, exists } from 'src/app/util/misc.util' +import { isEmptyObject, exists, DestroyService } from '@start9labs/shared' import { ApiService } from 'src/app/services/api/embassy-api.service' import { parseDataModel, RecoveredInfo } from 'src/app/util/parse-data-model' -import { DestroyService } from 'src/app/services/destroy.service' @Component({ selector: 'app-list', @@ -20,21 +19,21 @@ export class AppListPage { order: readonly string[] = [] reordering = false - constructor ( + constructor( private readonly api: ApiService, private readonly destroy$: DestroyService, public readonly patch: PatchDbService, - ) { } + ) {} - get empty (): boolean { + get empty(): boolean { return !this.pkgs.length && isEmptyObject(this.recoveredPkgs) } - ngOnInit () { + ngOnInit() { this.patch .watch$() .pipe( - filter((data) => exists(data) && !isEmptyObject(data)), + filter(data => exists(data) && !isEmptyObject(data)), take(1), map(parseDataModel), tap(({ order, pkgs, recoveredPkgs }) => { @@ -53,7 +52,7 @@ export class AppListPage { .subscribe() } - onReordering (reordering: boolean): void { + onReordering(reordering: boolean): void { if (!reordering) { this.setOrder() } @@ -61,35 +60,33 @@ export class AppListPage { this.reordering = reordering } - deleteRecovered (rec: RecoveredInfo): void { - this.recoveredPkgs = this.recoveredPkgs.filter((item) => item !== rec) + deleteRecovered(rec: RecoveredInfo): void { + this.recoveredPkgs = this.recoveredPkgs.filter(item => item !== rec) } - private watchNewlyRecovered (): Observable { + private watchNewlyRecovered(): Observable { return this.patch.watch$('package-data').pipe( - filter((pkgs) => !!pkgs && Object.keys(pkgs).length !== this.pkgs.length), - tap((pkgs) => { + filter(pkgs => !!pkgs && Object.keys(pkgs).length !== this.pkgs.length), + tap(pkgs => { const ids = Object.keys(pkgs) const newIds = ids.filter( - (id) => !this.pkgs.find((pkg) => pkg.manifest.id === id), + id => !this.pkgs.find(pkg => pkg.manifest.id === id), ) // remove uninstalled - const filtered = this.pkgs.filter((pkg) => - ids.includes(pkg.manifest.id), - ) + const filtered = this.pkgs.filter(pkg => ids.includes(pkg.manifest.id)) // add new entry to beginning of array - const added = newIds.map((id) => pkgs[id]) + const added = newIds.map(id => pkgs[id]) this.pkgs = [...added, ...filtered] - this.recoveredPkgs = this.recoveredPkgs.filter((rec) => !pkgs[rec.id]) + this.recoveredPkgs = this.recoveredPkgs.filter(rec => !pkgs[rec.id]) }), ) } - private setOrder (): void { - this.order = this.pkgs.map((pkg) => pkg.manifest.id) + private setOrder(): void { + this.order = this.pkgs.map(pkg => pkg.manifest.id) this.api.setDbValue({ pointer: '/pkg-order', value: this.order }) } } diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-list/package-info.pipe.ts b/frontend/projects/ui/src/app/pages/apps-routes/app-list/package-info.pipe.ts index 6c67129ae..1abaf0ad6 100644 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-list/package-info.pipe.ts +++ b/frontend/projects/ui/src/app/pages/apps-routes/app-list/package-info.pipe.ts @@ -1,21 +1,21 @@ -import { Pipe, PipeTransform } from "@angular/core"; -import { Observable } from "rxjs"; -import { filter, map, startWith } from "rxjs/operators"; -import { PackageDataEntry } from "../../../services/patch-db/data-model"; -import { getPackageInfo, PkgInfo } from "../../../util/get-package-info"; -import { PatchDbService } from "../../../services/patch-db/patch-db.service"; +import { Pipe, PipeTransform } from '@angular/core' +import { Observable } from 'rxjs' +import { filter, map, startWith } from 'rxjs/operators' +import { PackageDataEntry } from '../../../services/patch-db/data-model' +import { getPackageInfo, PkgInfo } from '../../../util/get-package-info' +import { PatchDbService } from '../../../services/patch-db/patch-db.service' @Pipe({ - name: "packageInfo", + name: 'packageInfo', }) export class PackageInfoPipe implements PipeTransform { constructor(private readonly patch: PatchDbService) {} transform(pkg: PackageDataEntry): Observable { - return this.patch.watch$("package-data", pkg.manifest.id).pipe( - filter((v) => !!v), + return this.patch.watch$('package-data', pkg.manifest.id).pipe( + filter(v => !!v), map(getPackageInfo), - startWith(getPackageInfo(pkg)) - ); + startWith(getPackageInfo(pkg)), + ) } } diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-logs/app-logs.module.ts b/frontend/projects/ui/src/app/pages/apps-routes/app-logs/app-logs.module.ts index 7128ecd66..b6a4e3d86 100644 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-logs/app-logs.module.ts +++ b/frontend/projects/ui/src/app/pages/apps-routes/app-logs/app-logs.module.ts @@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common' import { Routes, RouterModule } from '@angular/router' import { IonicModule } from '@ionic/angular' import { AppLogsPage } from './app-logs.page' -import { SharingModule } from 'src/app/modules/sharing.module' +import { SharedPipesModule } from '@start9labs/shared' import { LogsPageModule } from 'src/app/components/logs/logs.module' const routes: Routes = [ @@ -18,9 +18,9 @@ const routes: Routes = [ CommonModule, IonicModule, RouterModule.forChild(routes), - SharingModule, + SharedPipesModule, LogsPageModule, ], declarations: [AppLogsPage], }) -export class AppLogsPageModule { } +export class AppLogsPageModule {} diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-metrics/app-metrics.module.ts b/frontend/projects/ui/src/app/pages/apps-routes/app-metrics/app-metrics.module.ts index 1e6346782..2c53d0fea 100644 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-metrics/app-metrics.module.ts +++ b/frontend/projects/ui/src/app/pages/apps-routes/app-metrics/app-metrics.module.ts @@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common' import { Routes, RouterModule } from '@angular/router' import { IonicModule } from '@ionic/angular' import { AppMetricsPage } from './app-metrics.page' -import { SharingModule } from 'src/app/modules/sharing.module' +import { SharedPipesModule } from '@start9labs/shared' import { SkeletonListComponentModule } from 'src/app/components/skeleton-list/skeleton-list.component.module' const routes: Routes = [ @@ -18,9 +18,9 @@ const routes: Routes = [ CommonModule, IonicModule, RouterModule.forChild(routes), - SharingModule, + SharedPipesModule, SkeletonListComponentModule, ], declarations: [AppMetricsPage], }) -export class AppMetricsPageModule { } +export class AppMetricsPageModule {} diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-metrics/app-metrics.page.ts b/frontend/projects/ui/src/app/pages/apps-routes/app-metrics/app-metrics.page.ts index f7163cb89..8cea346ff 100644 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-metrics/app-metrics.page.ts +++ b/frontend/projects/ui/src/app/pages/apps-routes/app-metrics/app-metrics.page.ts @@ -6,7 +6,7 @@ import { Metric } from 'src/app/services/api/api.types' import { ApiService } from 'src/app/services/api/embassy-api.service' import { ErrorToastService } from 'src/app/services/error-toast.service' import { MainStatus } from 'src/app/services/patch-db/data-model' -import { pauseFor } from 'src/app/util/misc.util' +import { pauseFor } from '@start9labs/shared' @Component({ selector: 'app-metrics', @@ -23,26 +23,26 @@ export class AppMetricsPage { @ViewChild(IonContent) content: IonContent - constructor ( + constructor( private readonly route: ActivatedRoute, private readonly errToast: ErrorToastService, private readonly embassyApi: ApiService, - ) { } + ) {} - ngOnInit () { + ngOnInit() { this.pkgId = this.route.snapshot.paramMap.get('pkgId') this.startDaemon() } - ngAfterViewInit () { + ngAfterViewInit() { this.content.scrollToPoint(undefined, 1) } - ngOnDestroy () { + ngOnDestroy() { this.stopDaemon() } - async startDaemon (): Promise { + async startDaemon(): Promise { this.going = true while (this.going) { const startTime = Date.now() @@ -51,13 +51,13 @@ export class AppMetricsPage { } } - stopDaemon () { + stopDaemon() { this.going = false } - async getMetrics (): Promise { + async getMetrics(): Promise { try { - this.metrics = await this.embassyApi.getPkgMetrics({ id: this.pkgId}) + this.metrics = await this.embassyApi.getPkgMetrics({ id: this.pkgId }) } catch (e) { this.errToast.present(e) this.stopDaemon() @@ -66,7 +66,7 @@ export class AppMetricsPage { } } - asIsOrder (a: any, b: any) { + asIsOrder(a: any, b: any) { return 0 } } diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-properties/app-properties.module.ts b/frontend/projects/ui/src/app/pages/apps-routes/app-properties/app-properties.module.ts index db64af1b9..2d8553017 100644 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-properties/app-properties.module.ts +++ b/frontend/projects/ui/src/app/pages/apps-routes/app-properties/app-properties.module.ts @@ -4,7 +4,11 @@ import { Routes, RouterModule } from '@angular/router' import { IonicModule } from '@ionic/angular' import { AppPropertiesPage } from './app-properties.page' import { QRComponentModule } from 'src/app/components/qr/qr.component.module' -import { SharingModule } from 'src/app/modules/sharing.module' +import { MaskPipeModule } from 'src/app/pipes/mask/mask.module' +import { + SharedPipesModule, + TextSpinnerComponentModule, +} from '@start9labs/shared' const routes: Routes = [ { @@ -19,8 +23,10 @@ const routes: Routes = [ IonicModule, RouterModule.forChild(routes), QRComponentModule, - SharingModule, + SharedPipesModule, + TextSpinnerComponentModule, + MaskPipeModule, ], declarations: [AppPropertiesPage], }) -export class AppPropertiesPageModule { } +export class AppPropertiesPageModule {} diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-properties/app-properties.page.ts b/frontend/projects/ui/src/app/pages/apps-routes/app-properties/app-properties.page.ts index 6aecde6a4..1f228730d 100644 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-properties/app-properties.page.ts +++ b/frontend/projects/ui/src/app/pages/apps-routes/app-properties/app-properties.page.ts @@ -3,7 +3,13 @@ import { ActivatedRoute } from '@angular/router' import { ApiService } from 'src/app/services/api/embassy-api.service' import { Subscription } from 'rxjs' import { copyToClipboard } from 'src/app/util/web.util' -import { AlertController, IonContent, ModalController, NavController, ToastController } from '@ionic/angular' +import { + AlertController, + IonContent, + ModalController, + NavController, + ToastController, +} from '@ionic/angular' import { PackageProperties } from 'src/app/util/properties.util' import { QRComponent } from 'src/app/components/qr/qr.component' import { PatchDbService } from 'src/app/services/patch-db/patch-db.service' @@ -22,13 +28,13 @@ export class AppPropertiesPage { pointer: string properties: PackageProperties node: PackageProperties - unmasked: { [key: string]: boolean } = { } + unmasked: { [key: string]: boolean } = {} running = true @ViewChild(IonContent) content: IonContent subs: Subscription[] = [] - constructor ( + constructor( private readonly route: ActivatedRoute, private readonly embassyApi: ApiService, private readonly errToast: ErrorToastService, @@ -37,40 +43,50 @@ export class AppPropertiesPage { private readonly modalCtrl: ModalController, private readonly navCtrl: NavController, private readonly patch: PatchDbService, - ) { } + ) {} - async ngOnInit () { + async ngOnInit() { this.pkgId = this.route.snapshot.paramMap.get('pkgId') await this.getProperties() this.subs = [ - this.route.queryParams - .subscribe(queryParams => { + this.route.queryParams.subscribe(queryParams => { if (queryParams['pointer'] === this.pointer) return this.pointer = queryParams['pointer'] this.node = getValueByPointer(this.properties, this.pointer || '') }), - this.patch.watch$('package-data', this.pkgId, 'installed', 'status', 'main', 'status') - .subscribe(status => { - this.running = status === PackageMainStatus.Running - }), + this.patch + .watch$( + 'package-data', + this.pkgId, + 'installed', + 'status', + 'main', + 'status', + ) + .subscribe(status => { + this.running = status === PackageMainStatus.Running + }), ] } - ngAfterViewInit () { + ngAfterViewInit() { this.content.scrollToPoint(undefined, 1) } - ngOnDestroy () { + ngOnDestroy() { this.subs.forEach(sub => sub.unsubscribe()) } - async refresh () { + async refresh() { await this.getProperties() } - async presentDescription (property: { key: string, value: PackageProperties[''] }, e: Event) { + async presentDescription( + property: { key: string; value: PackageProperties[''] }, + e: Event, + ) { e.stopPropagation() const alert = await this.alertCtrl.create({ @@ -80,7 +96,7 @@ export class AppPropertiesPage { await alert.present() } - async goToNested (key: string): Promise { + async goToNested(key: string): Promise { this.navCtrl.navigateForward(`/services/${this.pkgId}/properties`, { queryParams: { pointer: `${this.pointer || ''}/${key}/value`, @@ -88,9 +104,11 @@ export class AppPropertiesPage { }) } - async copy (text: string): Promise { + async copy(text: string): Promise { let message = '' - await copyToClipboard(text).then(success => { message = success ? 'copied to clipboard!' : 'failed to copy'}) + await copyToClipboard(text).then(success => { + message = success ? 'copied to clipboard!' : 'failed to copy' + }) const toast = await this.toastCtrl.create({ header: message, @@ -100,7 +118,7 @@ export class AppPropertiesPage { await toast.present() } - async showQR (text: string): Promise { + async showQR(text: string): Promise { const modal = await this.modalCtrl.create({ component: QRComponent, componentProps: { @@ -111,14 +129,16 @@ export class AppPropertiesPage { await modal.present() } - toggleMask (key: string) { + toggleMask(key: string) { this.unmasked[key] = !this.unmasked[key] } - private async getProperties (): Promise { + private async getProperties(): Promise { this.loading = true try { - this.properties = await this.embassyApi.getPackageProperties({ id: this.pkgId }) + this.properties = await this.embassyApi.getPackageProperties({ + id: this.pkgId, + }) this.node = getValueByPointer(this.properties, this.pointer || '') } catch (e) { this.errToast.present(e) @@ -127,7 +147,7 @@ export class AppPropertiesPage { } } - asIsOrder (a: any, b: any) { + asIsOrder(a: any, b: any) { return 0 } } diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-show/app-show.module.ts b/frontend/projects/ui/src/app/pages/apps-routes/app-show/app-show.module.ts index 79cb8f805..95f8baaec 100644 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-show/app-show.module.ts +++ b/frontend/projects/ui/src/app/pages/apps-routes/app-show/app-show.module.ts @@ -3,10 +3,12 @@ import { CommonModule } from '@angular/common' import { Routes, RouterModule } from '@angular/router' import { IonicModule } from '@ionic/angular' import { AppShowPage } from './app-show.page' -import { StatusComponentModule } from 'src/app/components/status/status.component.module' -import { SharingModule } from 'src/app/modules/sharing.module' +import { EmverPipesModule } from '@start9labs/shared' import { InstallWizardComponentModule } from 'src/app/components/install-wizard/install-wizard.component.module' +import { StatusComponentModule } from 'src/app/components/status/status.component.module' import { AppConfigPageModule } from 'src/app/modals/app-config/app-config.module' +import { LaunchablePipeModule } from 'src/app/pipes/launchable/launchable.module' +import { UiPipeModule } from 'src/app/pipes/ui/ui.module' import { AppShowHeaderComponent } from './components/app-show-header/app-show-header.component' import { AppShowProgressComponent } from './components/app-show-progress/app-show-progress.component' import { AppShowStatusComponent } from './components/app-show-status/app-show-status.component' @@ -18,6 +20,7 @@ import { ToHealthChecksPipe } from './pipes/to-health-checks.pipe' import { ToButtonsPipe } from './pipes/to-buttons.pipe' import { ToDependenciesPipe } from './pipes/to-dependencies.pipe' import { ToStatusPipe } from './pipes/to-status.pipe' +import { InstallStatePipe } from './pipes/install-state.pipe' const routes: Routes = [ { @@ -30,6 +33,7 @@ const routes: Routes = [ declarations: [ AppShowPage, HealthColorPipe, + InstallStatePipe, ToHealthChecksPipe, ToButtonsPipe, ToDependenciesPipe, @@ -48,7 +52,9 @@ const routes: Routes = [ RouterModule.forChild(routes), InstallWizardComponentModule, AppConfigPageModule, - SharingModule, + EmverPipesModule, + LaunchablePipeModule, + UiPipeModule, ], }) export class AppShowPageModule {} diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-show/app-show.page.ts b/frontend/projects/ui/src/app/pages/apps-routes/app-show/app-show.page.ts index 406c02913..4bb15c46b 100644 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-show/app-show.page.ts +++ b/frontend/projects/ui/src/app/pages/apps-routes/app-show/app-show.page.ts @@ -1,10 +1,8 @@ import { ChangeDetectionStrategy, Component } from '@angular/core' import { NavController } from '@ionic/angular' import { PatchDbService } from 'src/app/services/patch-db/patch-db.service' -import { - PackageDataEntry, - PackageState, -} from 'src/app/services/patch-db/data-model' +import { PackageDataEntry } from 'src/app/services/patch-db/data-model' +import { PackageState } from '@start9labs/shared' import { PackageStatus, PrimaryStatus, @@ -70,4 +68,3 @@ export class AppShowPage { return STATES.includes(state) } } - diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-show/components/app-show-progress/app-show-progress.component.ts b/frontend/projects/ui/src/app/pages/apps-routes/app-show/components/app-show-progress/app-show-progress.component.ts index 750ee90b9..4360152ba 100644 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-show/components/app-show-progress/app-show-progress.component.ts +++ b/frontend/projects/ui/src/app/pages/apps-routes/app-show/components/app-show-progress/app-show-progress.component.ts @@ -1,9 +1,6 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core' -import { - InstallProgress, - PackageDataEntry, -} from 'src/app/services/patch-db/data-model' -import { ProgressData } from 'src/app/util/package-loading-progress' +import { PackageDataEntry } from 'src/app/services/patch-db/data-model' +import { InstallProgress, ProgressData } from '@start9labs/shared' @Component({ selector: 'app-show-progress', diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-show/components/app-show-status/app-show-status.component.ts b/frontend/projects/ui/src/app/pages/apps-routes/app-show/components/app-show-status/app-show-status.component.ts index e27dffb1f..81f597214 100644 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-show/components/app-show-status/app-show-status.component.ts +++ b/frontend/projects/ui/src/app/pages/apps-routes/app-show/components/app-show-status/app-show-status.component.ts @@ -1,17 +1,16 @@ import { ChangeDetectionStrategy, Component, Input } from '@angular/core' import { UiLauncherService } from 'src/app/services/ui-launcher.service' -import { - InterfaceDef, - PackageDataEntry, - PackageState, - Status, -} from 'src/app/services/patch-db/data-model' import { PackageStatus, PrimaryRendering, PrimaryStatus, } from 'src/app/services/pkg-status-rendering.service' -import { isEmptyObject } from 'src/app/util/misc.util' +import { + InterfaceDef, + PackageDataEntry, + Status, +} from 'src/app/services/patch-db/data-model' +import { isEmptyObject, PackageState } from '@start9labs/shared' import { wizardModal } from 'src/app/components/install-wizard/install-wizard.component' import { AlertController, diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-show/pipes/install-state.pipe.ts b/frontend/projects/ui/src/app/pages/apps-routes/app-show/pipes/install-state.pipe.ts new file mode 100644 index 000000000..8cb655099 --- /dev/null +++ b/frontend/projects/ui/src/app/pages/apps-routes/app-show/pipes/install-state.pipe.ts @@ -0,0 +1,12 @@ +import { Pipe, PipeTransform } from '@angular/core' +import { PackageDataEntry } from 'src/app/services/patch-db/data-model' +import { ProgressData, packageLoadingProgress } from '@start9labs/shared' + +@Pipe({ + name: 'installState', +}) +export class InstallStatePipe implements PipeTransform { + transform(pkg: PackageDataEntry): ProgressData | null { + return packageLoadingProgress(pkg['install-progress']) + } +} diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-show/pipes/to-buttons.pipe.ts b/frontend/projects/ui/src/app/pages/apps-routes/app-show/pipes/to-buttons.pipe.ts index dfc46b127..117e3e882 100644 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-show/pipes/to-buttons.pipe.ts +++ b/frontend/projects/ui/src/app/pages/apps-routes/app-show/pipes/to-buttons.pipe.ts @@ -84,7 +84,8 @@ export class ToButtonsPipe implements PipeTransform { }, // view in marketplace { - action: () => this.navCtrl.navigateForward([`marketplace/${pkg.manifest.id}`]), + action: () => + this.navCtrl.navigateForward([`marketplace/${pkg.manifest.id}`]), title: 'Marketplace', description: 'View service in marketplace', icon: 'storefront-outline', diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-show/pipes/to-dependencies.pipe.ts b/frontend/projects/ui/src/app/pages/apps-routes/app-show/pipes/to-dependencies.pipe.ts index 489620df0..66ed75f03 100644 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-show/pipes/to-dependencies.pipe.ts +++ b/frontend/projects/ui/src/app/pages/apps-routes/app-show/pipes/to-dependencies.pipe.ts @@ -3,12 +3,12 @@ import { NavigationExtras } from '@angular/router' import { NavController } from '@ionic/angular' import { combineLatest, Observable } from 'rxjs' import { filter, map, startWith } from 'rxjs/operators' -import { DependentInfo, exists } from 'src/app/util/misc.util' import { DependencyError, DependencyErrorType, PackageDataEntry, } from 'src/app/services/patch-db/data-model' +import { DependentInfo, exists } from '@start9labs/shared' import { PatchDbService } from 'src/app/services/patch-db/patch-db.service' import { ModalService } from 'src/app/services/modal.service' diff --git a/frontend/projects/ui/src/app/pages/apps-routes/app-show/pipes/to-health-checks.pipe.ts b/frontend/projects/ui/src/app/pages/apps-routes/app-show/pipes/to-health-checks.pipe.ts index aaf413a60..f6cbbe3e8 100644 --- a/frontend/projects/ui/src/app/pages/apps-routes/app-show/pipes/to-health-checks.pipe.ts +++ b/frontend/projects/ui/src/app/pages/apps-routes/app-show/pipes/to-health-checks.pipe.ts @@ -1,10 +1,10 @@ -import { Inject, Pipe, PipeTransform } from '@angular/core' +import { Pipe, PipeTransform } from '@angular/core' import { HealthCheckResult, PackageDataEntry, PackageMainStatus, } from 'src/app/services/patch-db/data-model' -import { exists, isEmptyObject } from 'src/app/util/misc.util' +import { exists, isEmptyObject } from '@start9labs/shared' import { filter, map, startWith } from 'rxjs/operators' import { PatchDbService } from 'src/app/services/patch-db/patch-db.service' import { Observable } from 'rxjs' @@ -30,7 +30,8 @@ export class ToHealthChecksPipe implements PipeTransform { map(main => { // Question: is this ok or do we have to use Object.keys // to maintain order and the keys initially present in pkg? - return main.status === PackageMainStatus.Running && !isEmptyObject(main.health) + return main.status === PackageMainStatus.Running && + !isEmptyObject(main.health) ? main.health : healthChecks }), diff --git a/frontend/projects/ui/src/app/pages/developer-routes/dev-config/dev-config.module.ts b/frontend/projects/ui/src/app/pages/developer-routes/dev-config/dev-config.module.ts index b4a554667..649ab7dfc 100644 --- a/frontend/projects/ui/src/app/pages/developer-routes/dev-config/dev-config.module.ts +++ b/frontend/projects/ui/src/app/pages/developer-routes/dev-config/dev-config.module.ts @@ -4,7 +4,6 @@ import { IonicModule } from '@ionic/angular' import { RouterModule, Routes } from '@angular/router' import { DevConfigPage } from './dev-config.page' import { BadgeMenuComponentModule } from 'src/app/components/badge-menu-button/badge-menu.component.module' -import { SharingModule } from 'src/app/modules/sharing.module' import { BackupReportPageModule } from 'src/app/modals/backup-report/backup-report.module' import { FormsModule } from '@angular/forms' import { MonacoEditorModule } from '@materia-ui/ngx-monaco-editor' @@ -22,7 +21,6 @@ const routes: Routes = [ IonicModule, RouterModule.forChild(routes), BadgeMenuComponentModule, - SharingModule, BackupReportPageModule, FormsModule, MonacoEditorModule, diff --git a/frontend/projects/ui/src/app/pages/developer-routes/dev-instructions/dev-instructions.module.ts b/frontend/projects/ui/src/app/pages/developer-routes/dev-instructions/dev-instructions.module.ts index b4db3e5af..ce15130e5 100644 --- a/frontend/projects/ui/src/app/pages/developer-routes/dev-instructions/dev-instructions.module.ts +++ b/frontend/projects/ui/src/app/pages/developer-routes/dev-instructions/dev-instructions.module.ts @@ -4,7 +4,6 @@ import { IonicModule } from '@ionic/angular' import { RouterModule, Routes } from '@angular/router' import { DevInstructionsPage } from './dev-instructions.page' import { BadgeMenuComponentModule } from 'src/app/components/badge-menu-button/badge-menu.component.module' -import { SharingModule } from 'src/app/modules/sharing.module' import { BackupReportPageModule } from 'src/app/modals/backup-report/backup-report.module' import { FormsModule } from '@angular/forms' import { MonacoEditorModule } from '@materia-ui/ngx-monaco-editor' @@ -22,7 +21,6 @@ const routes: Routes = [ IonicModule, RouterModule.forChild(routes), BadgeMenuComponentModule, - SharingModule, BackupReportPageModule, FormsModule, MonacoEditorModule, diff --git a/frontend/projects/ui/src/app/pages/developer-routes/developer-list/developer-list.module.ts b/frontend/projects/ui/src/app/pages/developer-routes/developer-list/developer-list.module.ts index 7bff12e52..edb90709a 100644 --- a/frontend/projects/ui/src/app/pages/developer-routes/developer-list/developer-list.module.ts +++ b/frontend/projects/ui/src/app/pages/developer-routes/developer-list/developer-list.module.ts @@ -4,7 +4,6 @@ import { IonicModule } from '@ionic/angular' import { RouterModule, Routes } from '@angular/router' import { DeveloperPage } from './developer-list.page' import { BadgeMenuComponentModule } from 'src/app/components/badge-menu-button/badge-menu.component.module' -import { SharingModule } from 'src/app/modules/sharing.module' import { BackupReportPageModule } from 'src/app/modals/backup-report/backup-report.module' const routes: Routes = [ @@ -20,7 +19,6 @@ const routes: Routes = [ IonicModule, RouterModule.forChild(routes), BadgeMenuComponentModule, - SharingModule, BackupReportPageModule, ], declarations: [DeveloperPage], diff --git a/frontend/projects/ui/src/app/pages/login/login.module.ts b/frontend/projects/ui/src/app/pages/login/login.module.ts index 5074a668a..3c815b035 100644 --- a/frontend/projects/ui/src/app/pages/login/login.module.ts +++ b/frontend/projects/ui/src/app/pages/login/login.module.ts @@ -4,7 +4,7 @@ import { CommonModule } from '@angular/common' import { FormsModule } from '@angular/forms' import { IonicModule } from '@ionic/angular' import { LoginPage } from './login.page' -import { SharingModule } from 'src/app/modules/sharing.module' +import { SharedPipesModule } from '@start9labs/shared' const routes: Routes = [ { @@ -19,8 +19,8 @@ const routes: Routes = [ FormsModule, IonicModule, RouterModule.forChild(routes), - SharingModule, + SharedPipesModule, ], declarations: [LoginPage], }) -export class LoginPageModule { } +export class LoginPageModule {} diff --git a/frontend/projects/ui/src/app/pages/marketplace-routes/app-release-notes/app-release-notes.module.ts b/frontend/projects/ui/src/app/pages/marketplace-routes/app-release-notes/app-release-notes.module.ts index ac54f1a3c..5082481ca 100644 --- a/frontend/projects/ui/src/app/pages/marketplace-routes/app-release-notes/app-release-notes.module.ts +++ b/frontend/projects/ui/src/app/pages/marketplace-routes/app-release-notes/app-release-notes.module.ts @@ -2,8 +2,13 @@ import { NgModule } from '@angular/core' import { CommonModule } from '@angular/common' import { Routes, RouterModule } from '@angular/router' import { IonicModule } from '@ionic/angular' +import { + EmverPipesModule, + MarkdownPipeModule, + TextSpinnerComponentModule, +} from '@start9labs/shared' import { AppReleaseNotes } from './app-release-notes.page' -import { SharingModule } from 'src/app/modules/sharing.module' +import { MarketplacePipesModule } from '../pipes/marketplace-pipes.module' const routes: Routes = [ { @@ -17,8 +22,11 @@ const routes: Routes = [ CommonModule, IonicModule, RouterModule.forChild(routes), - SharingModule, + TextSpinnerComponentModule, + EmverPipesModule, + MarkdownPipeModule, + MarketplacePipesModule, ], declarations: [AppReleaseNotes], }) -export class ReleaseNotesModule { } +export class ReleaseNotesModule {} diff --git a/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.module.ts b/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.module.ts index 75dcc5d9c..425c2ac03 100644 --- a/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.module.ts +++ b/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.module.ts @@ -1,12 +1,16 @@ import { NgModule } from '@angular/core' import { CommonModule } from '@angular/common' +import { FormsModule } from '@angular/forms' import { Routes, RouterModule } from '@angular/router' import { IonicModule } from '@ionic/angular' -import { MarketplaceListPage } from './marketplace-list.page' -import { SharingModule } from '../../../modules/sharing.module' +import { + SharedPipesModule, + EmverPipesModule, + TextSpinnerComponentModule, +} from '@start9labs/shared' import { BadgeMenuComponentModule } from 'src/app/components/badge-menu-button/badge-menu.component.module' -import { StatusComponentModule } from 'src/app/components/status/status.component.module' -import { FormsModule } from '@angular/forms' +import { MarketplacePipesModule } from '../pipes/marketplace-pipes.module' +import { MarketplaceListPage } from './marketplace-list.page' const routes: Routes = [ { @@ -21,10 +25,12 @@ const routes: Routes = [ IonicModule, FormsModule, RouterModule.forChild(routes), - StatusComponentModule, - SharingModule, + TextSpinnerComponentModule, + SharedPipesModule, + EmverPipesModule, + MarketplacePipesModule, BadgeMenuComponentModule, ], declarations: [MarketplaceListPage], }) -export class MarketplaceListPageModule { } +export class MarketplaceListPageModule {} diff --git a/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.page.html b/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.page.html index c83472f98..77860c5a8 100644 --- a/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.page.html +++ b/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.page.html @@ -122,7 +122,7 @@ - +

diff --git a/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.page.ts b/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.page.ts index f075835a3..91d3f164a 100644 --- a/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.page.ts +++ b/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.page.ts @@ -1,16 +1,13 @@ import { Component, ViewChild } from '@angular/core' import { MarketplacePkg } from 'src/app/services/api/api.types' import { IonContent } from '@ionic/angular' -import { - PackageDataEntry, - PackageState, -} from 'src/app/services/patch-db/data-model' import { Subscription } from 'rxjs' import { ErrorToastService } from 'src/app/services/error-toast.service' import { MarketplaceService } from '../marketplace.service' import { PatchDbService } from 'src/app/services/patch-db/patch-db.service' import Fuse from 'fuse.js/dist/fuse.min.js' -import { exists, isEmptyObject } from 'src/app/util/misc.util' +import { exists, isEmptyObject, PackageState } from '@start9labs/shared' +import { PackageDataEntry } from 'src/app/services/patch-db/data-model' import { filter, first } from 'rxjs/operators' const defaultOps = { @@ -46,7 +43,7 @@ export class MarketplaceListPage { pkgs: MarketplacePkg[] = [] categories: string[] - localPkgs: { [id: string]: PackageDataEntry } = {} + localPkgs: Record = {} category = 'featured' query: string loading = true diff --git a/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.module.ts b/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.module.ts index 3cf576e98..c584f4107 100644 --- a/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.module.ts +++ b/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.module.ts @@ -3,9 +3,14 @@ import { CommonModule } from '@angular/common' import { Routes, RouterModule } from '@angular/router' import { IonicModule } from '@ionic/angular' import { MarketplaceShowPage } from './marketplace-show.page' -import { SharingModule } from 'src/app/modules/sharing.module' -import { StatusComponentModule } from 'src/app/components/status/status.component.module' +import { + SharedPipesModule, + EmverPipesModule, + MarkdownPipeModule, + TextSpinnerComponentModule, +} from '@start9labs/shared' import { InstallWizardComponentModule } from 'src/app/components/install-wizard/install-wizard.component.module' +import { MarketplacePipesModule } from '../pipes/marketplace-pipes.module' const routes: Routes = [ { @@ -18,11 +23,14 @@ const routes: Routes = [ imports: [ CommonModule, IonicModule, - StatusComponentModule, RouterModule.forChild(routes), - SharingModule, + TextSpinnerComponentModule, + SharedPipesModule, + EmverPipesModule, + MarkdownPipeModule, + MarketplacePipesModule, InstallWizardComponentModule, ], declarations: [MarketplaceShowPage], }) -export class MarketplaceShowPageModule { } +export class MarketplaceShowPageModule {} diff --git a/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.html b/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.html index 63ca6c61f..c78c388d1 100644 --- a/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.html +++ b/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.html @@ -18,7 +18,7 @@
- +

{{ pkg.manifest.title }}

@@ -198,7 +198,7 @@ diff --git a/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.ts b/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.ts index 622813073..5f0b6857b 100644 --- a/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.ts +++ b/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.ts @@ -9,15 +9,16 @@ import { } from '@ionic/angular' import { wizardModal } from 'src/app/components/install-wizard/install-wizard.component' import { WizardBaker } from 'src/app/components/install-wizard/prebaked-wizards' -import { Emver } from 'src/app/services/emver.service' -import { displayEmver } from 'src/app/pipes/emver.pipe' -import { DependentInfo, pauseFor } from 'src/app/util/misc.util' +import { + displayEmver, + Emver, + DependentInfo, + pauseFor, + PackageState, +} from '@start9labs/shared' +import { PackageDataEntry } from 'src/app/services/patch-db/data-model' import { PatchDbService } from 'src/app/services/patch-db/patch-db.service' import { ErrorToastService } from 'src/app/services/error-toast.service' -import { - PackageDataEntry, - PackageState, -} from 'src/app/services/patch-db/data-model' import { MarketplaceService } from '../marketplace.service' import { Subscription } from 'rxjs' import { MarkdownPage } from 'src/app/modals/markdown/markdown.page' diff --git a/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace.service.ts b/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace.service.ts index 5fbee8c97..06826b5ca 100644 --- a/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace.service.ts +++ b/frontend/projects/ui/src/app/pages/marketplace-routes/marketplace.service.ts @@ -7,7 +7,7 @@ import { } from 'src/app/services/api/api.types' import { ApiService } from 'src/app/services/api/embassy-api.service' import { ConfigService } from 'src/app/services/config.service' -import { Emver } from 'src/app/services/emver.service' +import { Emver } from '@start9labs/shared' import { PackageDataEntry } from 'src/app/services/patch-db/data-model' import { PatchDbService } from 'src/app/services/patch-db/patch-db.service' @@ -24,14 +24,14 @@ export class MarketplaceService { } = {} marketplaceUrl: string - constructor ( + constructor( private readonly api: ApiService, private readonly emver: Emver, private readonly patch: PatchDbService, private readonly config: ConfigService, - ) { } + ) {} - init (): Subscription { + init(): Subscription { return this.patch.watch$('ui', 'marketplace').subscribe(marketplace => { if (!marketplace || !marketplace['selected-id']) { this.marketplaceUrl = this.config.marketplace.url @@ -42,7 +42,7 @@ export class MarketplaceService { }) } - async load (): Promise { + async load(): Promise { try { const [data, pkgs] = await Promise.all([ this.getMarketplaceData({}), @@ -67,9 +67,9 @@ export class MarketplaceService { } } - async getUpdates (localPkgs: { - [id: string]: PackageDataEntry - }): Promise { + async getUpdates( + localPkgs: Record, + ): Promise { const id = this.patch.getData().ui.marketplace?.['selected-id'] const url = id ? this.patch.getData().ui.marketplace['known-hosts'][id].url @@ -95,7 +95,7 @@ export class MarketplaceService { }) } - async getPkg (id: string, version = '*'): Promise { + async getPkg(id: string, version = '*'): Promise { const pkgs = await this.getMarketplacePkgs({ ids: [{ id, version }], }) @@ -108,11 +108,11 @@ export class MarketplaceService { } } - async cacheReleaseNotes (id: string): Promise { + async cacheReleaseNotes(id: string): Promise { this.releaseNotes[id] = await this.getReleaseNotes({ id }) } - async getMarketplaceData ( + async getMarketplaceData( params: RR.GetMarketplaceDataReq, url?: string, ): Promise { @@ -120,7 +120,7 @@ export class MarketplaceService { return this.api.marketplaceProxy('/package/v0/info', params, url) } - async getMarketplacePkgs ( + async getMarketplacePkgs( params: Omit, ): Promise { if (params.query) delete params.category @@ -139,7 +139,7 @@ export class MarketplaceService { ) } - async getReleaseNotes ( + async getReleaseNotes( params: RR.GetReleaseNotesReq, ): Promise { return this.api.marketplaceProxy( diff --git a/frontend/projects/ui/src/app/pipes/install-progress.pipe.ts b/frontend/projects/ui/src/app/pages/marketplace-routes/pipes/install-progress.pipe.ts similarity index 70% rename from frontend/projects/ui/src/app/pipes/install-progress.pipe.ts rename to frontend/projects/ui/src/app/pages/marketplace-routes/pipes/install-progress.pipe.ts index eb6eb34fe..c7474b9b8 100644 --- a/frontend/projects/ui/src/app/pipes/install-progress.pipe.ts +++ b/frontend/projects/ui/src/app/pages/marketplace-routes/pipes/install-progress.pipe.ts @@ -1,6 +1,5 @@ import { Pipe, PipeTransform } from '@angular/core' -import { InstallProgress } from '../services/patch-db/data-model' -import { packageLoadingProgress } from '../util/package-loading-progress' +import { InstallProgress, packageLoadingProgress } from '@start9labs/shared' @Pipe({ name: 'installProgress', diff --git a/frontend/projects/ui/src/app/pages/marketplace-routes/pipes/marketplace-pipes.module.ts b/frontend/projects/ui/src/app/pages/marketplace-routes/pipes/marketplace-pipes.module.ts new file mode 100644 index 000000000..3c8659f10 --- /dev/null +++ b/frontend/projects/ui/src/app/pages/marketplace-routes/pipes/marketplace-pipes.module.ts @@ -0,0 +1,9 @@ +import { NgModule } from '@angular/core' +import { InstallProgressPipe } from './install-progress.pipe' +import { TrustPipe } from './trust.pipe' + +@NgModule({ + declarations: [InstallProgressPipe, TrustPipe], + exports: [InstallProgressPipe, TrustPipe], +}) +export class MarketplacePipesModule {} diff --git a/frontend/projects/ui/src/app/pages/marketplace-routes/pipes/trust.pipe.ts b/frontend/projects/ui/src/app/pages/marketplace-routes/pipes/trust.pipe.ts new file mode 100644 index 000000000..283ad3a76 --- /dev/null +++ b/frontend/projects/ui/src/app/pages/marketplace-routes/pipes/trust.pipe.ts @@ -0,0 +1,13 @@ +import { Pipe, PipeTransform } from '@angular/core' +import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser' + +@Pipe({ + name: 'trust', +}) +export class TrustPipe implements PipeTransform { + constructor(public readonly sanitizer: DomSanitizer) {} + + transform(base64Icon: string): SafeResourceUrl { + return this.sanitizer.bypassSecurityTrustResourceUrl(base64Icon) + } +} diff --git a/frontend/projects/ui/src/app/pages/notifications/notifications.module.ts b/frontend/projects/ui/src/app/pages/notifications/notifications.module.ts index 5b5feed93..5ff2b4572 100644 --- a/frontend/projects/ui/src/app/pages/notifications/notifications.module.ts +++ b/frontend/projects/ui/src/app/pages/notifications/notifications.module.ts @@ -4,7 +4,7 @@ import { IonicModule } from '@ionic/angular' import { RouterModule, Routes } from '@angular/router' import { NotificationsPage } from './notifications.page' import { BadgeMenuComponentModule } from 'src/app/components/badge-menu-button/badge-menu.component.module' -import { SharingModule } from 'src/app/modules/sharing.module' +import { SharedPipesModule } from '@start9labs/shared' import { BackupReportPageModule } from 'src/app/modals/backup-report/backup-report.module' const routes: Routes = [ @@ -20,9 +20,9 @@ const routes: Routes = [ IonicModule, RouterModule.forChild(routes), BadgeMenuComponentModule, - SharingModule, + SharedPipesModule, BackupReportPageModule, ], declarations: [NotificationsPage], }) -export class NotificationsPageModule { } +export class NotificationsPageModule {} diff --git a/frontend/projects/ui/src/app/pages/notifications/notifications.page.html b/frontend/projects/ui/src/app/pages/notifications/notifications.page.html index 61aa916c8..b3b9d4381 100644 --- a/frontend/projects/ui/src/app/pages/notifications/notifications.page.html +++ b/frontend/projects/ui/src/app/pages/notifications/notifications.page.html @@ -78,14 +78,10 @@ {{ not['package-id'] }} - - {{ not.title }} + {{ not.title }}

-

- {{ not.message | truncateTail: 240 }} -

+

{{ truncate(not.message) }}

{ + async getNotifications(): Promise { let notifications: ServerNotifications = [] try { - notifications = await this.embassyApi.getNotifications({ before: this.beforeCursor, limit: this.perPage }) + notifications = await this.embassyApi.getNotifications({ + before: this.beforeCursor, + limit: this.perPage, + }) this.beforeCursor = notifications[notifications.length - 1]?.id this.needInfinite = notifications.length >= this.perPage } catch (e) { @@ -53,7 +64,7 @@ export class NotificationsPage { } } - async delete (id: number, index: number): Promise { + async delete(id: number, index: number): Promise { const loader = await this.loadingCtrl.create({ spinner: 'lines', message: 'Deleting...', @@ -72,7 +83,7 @@ export class NotificationsPage { } } - async presentAlertDeleteAll () { + async presentAlertDeleteAll() { const alert = await this.alertCtrl.create({ backdropDismiss: false, header: 'Delete All?', @@ -94,7 +105,7 @@ export class NotificationsPage { await alert.present() } - async viewBackupReport (notification: ServerNotification<1>) { + async viewBackupReport(notification: ServerNotification<1>) { const modal = await this.modalCtrl.create({ component: BackupReportPage, componentProps: { @@ -105,7 +116,7 @@ export class NotificationsPage { await modal.present() } - async viewFullMessage (title: string, message: string) { + async viewFullMessage(title: string, message: string) { const alert = await this.alertCtrl.create({ header: title, message: message, @@ -123,7 +134,26 @@ export class NotificationsPage { await alert.present() } - private async deleteAll (): Promise { + truncate(message: string): string { + return message.length <= 240 ? message : '...' + message.substr(-240) + } + + getColor({ level }: ServerNotification): string { + switch (level) { + case NotificationLevel.Info: + return 'primary' + case NotificationLevel.Success: + return 'success' + case NotificationLevel.Warning: + return 'warning' + case NotificationLevel.Error: + return 'danger' + default: + return '' + } + } + + private async deleteAll(): Promise { const loader = await this.loadingCtrl.create({ spinner: 'lines', message: 'Deleting...', @@ -132,7 +162,9 @@ export class NotificationsPage { await loader.present() try { - await this.embassyApi.deleteAllNotifications({ before: this.notifications[0].id }) + await this.embassyApi.deleteAllNotifications({ + before: this.notifications[0].id, + }) this.notifications = [] this.beforeCursor = undefined } catch (e) { @@ -142,4 +174,3 @@ export class NotificationsPage { } } } - diff --git a/frontend/projects/ui/src/app/pages/server-routes/lan/lan.module.ts b/frontend/projects/ui/src/app/pages/server-routes/lan/lan.module.ts index 538f55d14..dc0216ce2 100644 --- a/frontend/projects/ui/src/app/pages/server-routes/lan/lan.module.ts +++ b/frontend/projects/ui/src/app/pages/server-routes/lan/lan.module.ts @@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common' import { Routes, RouterModule } from '@angular/router' import { IonicModule } from '@ionic/angular' import { LANPage } from './lan.page' -import { SharingModule } from 'src/app/modules/sharing.module' +import { SharedPipesModule } from '@start9labs/shared' const routes: Routes = [ { @@ -17,8 +17,8 @@ const routes: Routes = [ CommonModule, IonicModule, RouterModule.forChild(routes), - SharingModule, + SharedPipesModule, ], declarations: [LANPage], }) -export class LANPageModule { } +export class LANPageModule {} diff --git a/frontend/projects/ui/src/app/pages/server-routes/marketplaces/marketplaces.module.ts b/frontend/projects/ui/src/app/pages/server-routes/marketplaces/marketplaces.module.ts index e46aa7324..2bd707498 100644 --- a/frontend/projects/ui/src/app/pages/server-routes/marketplaces/marketplaces.module.ts +++ b/frontend/projects/ui/src/app/pages/server-routes/marketplaces/marketplaces.module.ts @@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common' import { IonicModule } from '@ionic/angular' import { RouterModule, Routes } from '@angular/router' import { MarketplacesPage } from './marketplaces.page' -import { SharingModule } from 'src/app/modules/sharing.module' +import { SharedPipesModule } from '@start9labs/shared' const routes: Routes = [ { @@ -17,7 +17,7 @@ const routes: Routes = [ CommonModule, IonicModule, RouterModule.forChild(routes), - SharingModule, + SharedPipesModule, ], declarations: [MarketplacesPage], }) diff --git a/frontend/projects/ui/src/app/pages/server-routes/preferences/preferences.module.ts b/frontend/projects/ui/src/app/pages/server-routes/preferences/preferences.module.ts index 88353ab46..7172c65a4 100644 --- a/frontend/projects/ui/src/app/pages/server-routes/preferences/preferences.module.ts +++ b/frontend/projects/ui/src/app/pages/server-routes/preferences/preferences.module.ts @@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common' import { IonicModule } from '@ionic/angular' import { PreferencesPage } from './preferences.page' import { Routes, RouterModule } from '@angular/router' -import { SharingModule } from 'src/app/modules/sharing.module' +import { SharedPipesModule } from '@start9labs/shared' const routes: Routes = [ { @@ -17,10 +17,8 @@ const routes: Routes = [ CommonModule, IonicModule, RouterModule.forChild(routes), - SharingModule, - ], - declarations: [ - PreferencesPage, + SharedPipesModule, ], + declarations: [PreferencesPage], }) -export class PreferencesPageModule { } +export class PreferencesPageModule {} diff --git a/frontend/projects/ui/src/app/pages/server-routes/preferences/preferences.page.ts b/frontend/projects/ui/src/app/pages/server-routes/preferences/preferences.page.ts index 94c416c7f..51a53510d 100644 --- a/frontend/projects/ui/src/app/pages/server-routes/preferences/preferences.page.ts +++ b/frontend/projects/ui/src/app/pages/server-routes/preferences/preferences.page.ts @@ -24,7 +24,7 @@ export class PreferencesPage { defaultName: string clicks = 0 - constructor( + constructor ( private readonly loadingCtrl: LoadingController, private readonly modalCtrl: ModalController, private readonly api: ApiService, @@ -32,17 +32,17 @@ export class PreferencesPage { private readonly localStorageService: LocalStorageService, public readonly serverConfig: ServerConfigService, public readonly patch: PatchDbService, - ) {} + ) { } - ngOnInit() { + ngOnInit () { this.defaultName = `Embassy-${this.patch.getData()['server-info'].id}` } - ngAfterViewInit() { + ngAfterViewInit () { this.content.scrollToPoint(undefined, 1) } - async presentModalName(): Promise { + async presentModalName (): Promise { const options: GenericInputOptions = { title: 'Edit Device Name', message: 'This is for your reference only.', @@ -66,7 +66,7 @@ export class PreferencesPage { await modal.present() } - async setDbValue(key: string, value: any): Promise { + private async setDbValue (key: string, value: string): Promise { const loader = await this.loadingCtrl.create({ spinner: 'lines', message: 'Saving...', @@ -81,7 +81,7 @@ export class PreferencesPage { } } - async addClick() { + async addClick () { this.clicks++ if (this.clicks >= 5) { this.clicks = 0 diff --git a/frontend/projects/ui/src/app/pages/server-routes/restore/restore.component.module.ts b/frontend/projects/ui/src/app/pages/server-routes/restore/restore.component.module.ts index 234569c82..8cb4f6916 100644 --- a/frontend/projects/ui/src/app/pages/server-routes/restore/restore.component.module.ts +++ b/frontend/projects/ui/src/app/pages/server-routes/restore/restore.component.module.ts @@ -3,7 +3,7 @@ import { RouterModule, Routes } from '@angular/router' import { CommonModule } from '@angular/common' import { IonicModule } from '@ionic/angular' import { RestorePage } from './restore.component' -import { SharingModule } from 'src/app/modules/sharing.module' +import { SharedPipesModule } from '@start9labs/shared' import { BackupDrivesComponentModule } from 'src/app/components/backup-drives/backup-drives.component.module' import { AppRecoverSelectPageModule } from 'src/app/modals/app-recover-select/app-recover-select.module' @@ -19,12 +19,10 @@ const routes: Routes = [ CommonModule, IonicModule, RouterModule.forChild(routes), - SharingModule, + SharedPipesModule, BackupDrivesComponentModule, AppRecoverSelectPageModule, ], - declarations: [ - RestorePage, - ], + declarations: [RestorePage], }) -export class RestorePageModule { } \ No newline at end of file +export class RestorePageModule {} diff --git a/frontend/projects/ui/src/app/pages/server-routes/restore/restore.component.ts b/frontend/projects/ui/src/app/pages/server-routes/restore/restore.component.ts index b2633eaaf..c973458a6 100644 --- a/frontend/projects/ui/src/app/pages/server-routes/restore/restore.component.ts +++ b/frontend/projects/ui/src/app/pages/server-routes/restore/restore.component.ts @@ -1,9 +1,16 @@ import { Component } from '@angular/core' import { ModalController, NavController } from '@ionic/angular' import { ApiService } from 'src/app/services/api/embassy-api.service' -import { GenericInputComponent, GenericInputOptions } from 'src/app/modals/generic-input/generic-input.component' -import { MappedBackupTarget } from 'src/app/util/misc.util' -import { BackupInfo, CifsBackupTarget, DiskBackupTarget } from 'src/app/services/api/api.types' +import { + GenericInputComponent, + GenericInputOptions, +} from 'src/app/modals/generic-input/generic-input.component' +import { MappedBackupTarget } from 'src/app/types/mapped-backup-target' +import { + BackupInfo, + CifsBackupTarget, + DiskBackupTarget, +} from 'src/app/services/api/api.types' import { AppRecoverSelectPage } from 'src/app/modals/app-recover-select/app-recover-select.page' import { PatchDbService } from 'src/app/services/patch-db/patch-db.service' import * as argon2 from '@start9labs/argon2' @@ -14,18 +21,20 @@ import * as argon2 from '@start9labs/argon2' styleUrls: ['./restore.component.scss'], }) export class RestorePage { - - constructor ( + constructor( private readonly modalCtrl: ModalController, private readonly navCtrl: NavController, private readonly embassyApi: ApiService, private readonly patch: PatchDbService, - ) { } + ) {} - async presentModalPassword (target: MappedBackupTarget): Promise { + async presentModalPassword( + target: MappedBackupTarget, + ): Promise { const options: GenericInputOptions = { title: 'Master Password Required', - message: 'Enter your master password. On the next screen, you will select the individual services you want to restore.', + message: + 'Enter your master password. On the next screen, you will select the individual services you want to restore.', label: 'Master Password', placeholder: 'Enter master password', useMask: true, @@ -43,7 +52,10 @@ export class RestorePage { await modal.present() } - private async decryptDrive (target: MappedBackupTarget, password: string): Promise { + private async decryptDrive( + target: MappedBackupTarget, + password: string, + ): Promise { const passwordHash = this.patch.getData()['server-info']['password-hash'] argon2.verify(passwordHash, password) @@ -55,15 +67,20 @@ export class RestorePage { } } - private async presentModalOldPassword (target: MappedBackupTarget, password: string): Promise { + private async presentModalOldPassword( + target: MappedBackupTarget, + password: string, + ): Promise { const options: GenericInputOptions = { title: 'Original Password Needed', - message: 'This backup was created with a different password. Enter the ORIGINAL password that was used to encrypt this backup.', + message: + 'This backup was created with a different password. Enter the ORIGINAL password that was used to encrypt this backup.', label: 'Original Password', placeholder: 'Enter original password', useMask: true, buttonText: 'Restore From Backup', - submitFn: (oldPassword: string) => this.restoreFromBackup(target, password, oldPassword), + submitFn: (oldPassword: string) => + this.restoreFromBackup(target, password, oldPassword), } const m = await this.modalCtrl.create({ @@ -76,7 +93,11 @@ export class RestorePage { await m.present() } - private async restoreFromBackup (target: MappedBackupTarget, password: string, oldPassword?: string): Promise { + private async restoreFromBackup( + target: MappedBackupTarget, + password: string, + oldPassword?: string, + ): Promise { const backupInfo = await this.embassyApi.getBackupInfo({ 'target-id': target.id, password, @@ -84,7 +105,12 @@ export class RestorePage { this.presentModalSelect(target.id, backupInfo, password, oldPassword) } - private async presentModalSelect (id: string, backupInfo: BackupInfo, password: string, oldPassword?: string): Promise { + private async presentModalSelect( + id: string, + backupInfo: BackupInfo, + password: string, + oldPassword?: string, + ): Promise { const modal = await this.modalCtrl.create({ componentProps: { id, diff --git a/frontend/projects/ui/src/app/pages/server-routes/server-backup/server-backup.module.ts b/frontend/projects/ui/src/app/pages/server-routes/server-backup/server-backup.module.ts index 4cf401106..d4262392d 100644 --- a/frontend/projects/ui/src/app/pages/server-routes/server-backup/server-backup.module.ts +++ b/frontend/projects/ui/src/app/pages/server-routes/server-backup/server-backup.module.ts @@ -4,7 +4,7 @@ import { IonicModule } from '@ionic/angular' import { ServerBackupPage } from './server-backup.page' import { RouterModule, Routes } from '@angular/router' import { BackupDrivesComponentModule } from 'src/app/components/backup-drives/backup-drives.component.module' -import { SharingModule } from 'src/app/modules/sharing.module' +import { SharedPipesModule } from '@start9labs/shared' const routes: Routes = [ { @@ -18,11 +18,9 @@ const routes: Routes = [ CommonModule, IonicModule, RouterModule.forChild(routes), - SharingModule, + SharedPipesModule, BackupDrivesComponentModule, ], - declarations: [ - ServerBackupPage, - ], + declarations: [ServerBackupPage], }) -export class ServerBackupPageModule { } \ No newline at end of file +export class ServerBackupPageModule {} diff --git a/frontend/projects/ui/src/app/pages/server-routes/server-backup/server-backup.page.ts b/frontend/projects/ui/src/app/pages/server-routes/server-backup/server-backup.page.ts index 51aaf628d..d17df8dc4 100644 --- a/frontend/projects/ui/src/app/pages/server-routes/server-backup/server-backup.page.ts +++ b/frontend/projects/ui/src/app/pages/server-routes/server-backup/server-backup.page.ts @@ -10,14 +10,13 @@ import { GenericInputOptions, } from 'src/app/modals/generic-input/generic-input.component' import { PatchDbService } from 'src/app/services/patch-db/patch-db.service' +import { Subscription } from 'rxjs' +import { take } from 'rxjs/operators' +import { MappedBackupTarget } from 'src/app/types/mapped-backup-target' import { PackageDataEntry, PackageMainStatus, - ServerStatus, } from 'src/app/services/patch-db/data-model' -import { Subscription } from 'rxjs' -import { take } from 'rxjs/operators' -import { MappedBackupTarget } from 'src/app/util/misc.util' import * as argon2 from '@start9labs/argon2' import { CifsBackupTarget, diff --git a/frontend/projects/ui/src/app/pages/server-routes/server-logs/server-logs.module.ts b/frontend/projects/ui/src/app/pages/server-routes/server-logs/server-logs.module.ts index d8c95bf02..90bd3f02f 100644 --- a/frontend/projects/ui/src/app/pages/server-routes/server-logs/server-logs.module.ts +++ b/frontend/projects/ui/src/app/pages/server-routes/server-logs/server-logs.module.ts @@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common' import { Routes, RouterModule } from '@angular/router' import { IonicModule } from '@ionic/angular' import { ServerLogsPage } from './server-logs.page' -import { SharingModule } from 'src/app/modules/sharing.module' +import { SharedPipesModule } from '@start9labs/shared' import { LogsPageModule } from 'src/app/components/logs/logs.module' const routes: Routes = [ @@ -18,9 +18,9 @@ const routes: Routes = [ CommonModule, IonicModule, RouterModule.forChild(routes), - SharingModule, + SharedPipesModule, LogsPageModule, ], declarations: [ServerLogsPage], }) -export class ServerLogsPageModule { } +export class ServerLogsPageModule {} diff --git a/frontend/projects/ui/src/app/pages/server-routes/server-metrics/server-metrics.module.ts b/frontend/projects/ui/src/app/pages/server-routes/server-metrics/server-metrics.module.ts index ba6defbd9..a45dd577c 100644 --- a/frontend/projects/ui/src/app/pages/server-routes/server-metrics/server-metrics.module.ts +++ b/frontend/projects/ui/src/app/pages/server-routes/server-metrics/server-metrics.module.ts @@ -4,7 +4,7 @@ import { Routes, RouterModule } from '@angular/router' import { IonicModule } from '@ionic/angular' import { ServerMetricsPage } from './server-metrics.page' import { SkeletonListComponentModule } from 'src/app/components/skeleton-list/skeleton-list.component.module' -import { SharingModule } from 'src/app/modules/sharing.module' +import { SharedPipesModule } from '@start9labs/shared' const routes: Routes = [ { @@ -19,8 +19,8 @@ const routes: Routes = [ IonicModule, RouterModule.forChild(routes), SkeletonListComponentModule, - SharingModule, + SharedPipesModule, ], declarations: [ServerMetricsPage], }) -export class ServerMetricsPageModule { } +export class ServerMetricsPageModule {} diff --git a/frontend/projects/ui/src/app/pages/server-routes/server-metrics/server-metrics.page.ts b/frontend/projects/ui/src/app/pages/server-routes/server-metrics/server-metrics.page.ts index 4a9703155..ead7cfca2 100644 --- a/frontend/projects/ui/src/app/pages/server-routes/server-metrics/server-metrics.page.ts +++ b/frontend/projects/ui/src/app/pages/server-routes/server-metrics/server-metrics.page.ts @@ -2,7 +2,7 @@ import { Component } from '@angular/core' import { Metrics } from 'src/app/services/api/api.types' import { ApiService } from 'src/app/services/api/embassy-api.service' import { ErrorToastService } from 'src/app/services/error-toast.service' -import { pauseFor } from 'src/app/util/misc.util' +import { pauseFor } from '@start9labs/shared' @Component({ selector: 'server-metrics', @@ -12,14 +12,14 @@ import { pauseFor } from 'src/app/util/misc.util' export class ServerMetricsPage { loading = true going = false - metrics: Metrics = { } + metrics: Metrics = {} - constructor ( + constructor( private readonly errToast: ErrorToastService, private readonly embassyApi: ApiService, - ) { } + ) {} - async ngOnInit () { + async ngOnInit() { await this.getMetrics() let headersCount = 0 let rowsCount = 0 @@ -36,11 +36,11 @@ export class ServerMetricsPage { this.loading = false } - ngOnDestroy () { + ngOnDestroy() { this.stopDaemon() } - private async startDaemon (): Promise { + private async startDaemon(): Promise { this.going = true while (this.going) { const startTime = Date.now() @@ -49,20 +49,20 @@ export class ServerMetricsPage { } } - private stopDaemon () { + private stopDaemon() { this.going = false } - private async getMetrics (): Promise { + private async getMetrics(): Promise { try { - this.metrics = await this.embassyApi.getServerMetrics({ }) + this.metrics = await this.embassyApi.getServerMetrics({}) } catch (e) { this.errToast.present(e) this.stopDaemon() } } - asIsOrder (a: any, b: any) { + asIsOrder(a: any, b: any) { return 0 } } diff --git a/frontend/projects/ui/src/app/pages/server-routes/server-show/server-show.module.ts b/frontend/projects/ui/src/app/pages/server-routes/server-show/server-show.module.ts index 8c41afc98..2efdac950 100644 --- a/frontend/projects/ui/src/app/pages/server-routes/server-show/server-show.module.ts +++ b/frontend/projects/ui/src/app/pages/server-routes/server-show/server-show.module.ts @@ -3,9 +3,8 @@ import { CommonModule } from '@angular/common' import { IonicModule } from '@ionic/angular' import { RouterModule, Routes } from '@angular/router' import { ServerShowPage } from './server-show.page' -import { StatusComponentModule } from 'src/app/components/status/status.component.module' import { FormsModule } from '@angular/forms' -import { SharingModule } from 'src/app/modules/sharing.module' +import { TextSpinnerComponentModule } from '@start9labs/shared' import { BadgeMenuComponentModule } from 'src/app/components/badge-menu-button/badge-menu.component.module' const routes: Routes = [ @@ -19,12 +18,11 @@ const routes: Routes = [ imports: [ CommonModule, FormsModule, - StatusComponentModule, IonicModule, RouterModule.forChild(routes), - SharingModule, + TextSpinnerComponentModule, BadgeMenuComponentModule, ], declarations: [ServerShowPage], }) -export class ServerShowPageModule { } +export class ServerShowPageModule {} diff --git a/frontend/projects/ui/src/app/pages/server-routes/server-show/server-show.page.ts b/frontend/projects/ui/src/app/pages/server-routes/server-show/server-show.page.ts index ead88c75d..822bf7e1e 100644 --- a/frontend/projects/ui/src/app/pages/server-routes/server-show/server-show.page.ts +++ b/frontend/projects/ui/src/app/pages/server-routes/server-show/server-show.page.ts @@ -10,13 +10,13 @@ import { ApiService } from 'src/app/services/api/embassy-api.service' import { ActivatedRoute } from '@angular/router' import { ErrorToastService } from 'src/app/services/error-toast.service' import { PatchDbService } from 'src/app/services/patch-db/patch-db.service' -import { ServerStatus } from 'src/app/services/patch-db/data-model' import { Observable, of } from 'rxjs' import { filter, map, take } from 'rxjs/operators' import { WizardBaker } from 'src/app/components/install-wizard/prebaked-wizards' import { wizardModal } from 'src/app/components/install-wizard/install-wizard.component' -import { exists, isEmptyObject } from 'src/app/util/misc.util' +import { exists, isEmptyObject } from '@start9labs/shared' import { EOSService } from 'src/app/services/eos.service' +import { ServerStatus } from 'src/app/services/patch-db/data-model' @Component({ selector: 'server-show', diff --git a/frontend/projects/ui/src/app/pages/server-routes/server-specs/server-specs.module.ts b/frontend/projects/ui/src/app/pages/server-routes/server-specs/server-specs.module.ts index a6b28c60c..4cb7db15e 100644 --- a/frontend/projects/ui/src/app/pages/server-routes/server-specs/server-specs.module.ts +++ b/frontend/projects/ui/src/app/pages/server-routes/server-specs/server-specs.module.ts @@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common' import { Routes, RouterModule } from '@angular/router' import { IonicModule } from '@ionic/angular' import { ServerSpecsPage } from './server-specs.page' -import { SharingModule } from 'src/app/modules/sharing.module' +import { EmverPipesModule } from '@start9labs/shared' const routes: Routes = [ { @@ -17,8 +17,8 @@ const routes: Routes = [ CommonModule, IonicModule, RouterModule.forChild(routes), - SharingModule, + EmverPipesModule, ], declarations: [ServerSpecsPage], }) -export class ServerSpecsPageModule { } +export class ServerSpecsPageModule {} diff --git a/frontend/projects/ui/src/app/pages/server-routes/sessions/sessions.module.ts b/frontend/projects/ui/src/app/pages/server-routes/sessions/sessions.module.ts index 15ef586e4..f4f43a1bd 100644 --- a/frontend/projects/ui/src/app/pages/server-routes/sessions/sessions.module.ts +++ b/frontend/projects/ui/src/app/pages/server-routes/sessions/sessions.module.ts @@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common' import { IonicModule } from '@ionic/angular' import { RouterModule, Routes } from '@angular/router' import { SessionsPage } from './sessions.page' -import { SharingModule } from 'src/app/modules/sharing.module' +import { SharedPipesModule } from '@start9labs/shared' const routes: Routes = [ { @@ -17,8 +17,8 @@ const routes: Routes = [ CommonModule, IonicModule, RouterModule.forChild(routes), - SharingModule, + SharedPipesModule, ], declarations: [SessionsPage], }) -export class SessionsPageModule { } +export class SessionsPageModule {} diff --git a/frontend/projects/ui/src/app/pages/server-routes/ssh-keys/ssh-keys.module.ts b/frontend/projects/ui/src/app/pages/server-routes/ssh-keys/ssh-keys.module.ts index 5e3bd9b91..4e974498c 100644 --- a/frontend/projects/ui/src/app/pages/server-routes/ssh-keys/ssh-keys.module.ts +++ b/frontend/projects/ui/src/app/pages/server-routes/ssh-keys/ssh-keys.module.ts @@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common' import { IonicModule } from '@ionic/angular' import { RouterModule, Routes } from '@angular/router' import { SSHKeysPage } from './ssh-keys.page' -import { SharingModule } from 'src/app/modules/sharing.module' +import { SharedPipesModule } from '@start9labs/shared' const routes: Routes = [ { @@ -17,8 +17,8 @@ const routes: Routes = [ CommonModule, IonicModule, RouterModule.forChild(routes), - SharingModule, + SharedPipesModule, ], declarations: [SSHKeysPage], }) -export class SSHKeysPageModule { } +export class SSHKeysPageModule {} diff --git a/frontend/projects/ui/src/app/pages/server-routes/wifi/wifi.module.ts b/frontend/projects/ui/src/app/pages/server-routes/wifi/wifi.module.ts index 8f54ab544..5233db8d4 100644 --- a/frontend/projects/ui/src/app/pages/server-routes/wifi/wifi.module.ts +++ b/frontend/projects/ui/src/app/pages/server-routes/wifi/wifi.module.ts @@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common' import { IonicModule } from '@ionic/angular' import { RouterModule, Routes } from '@angular/router' import { WifiPage } from './wifi.page' -import { SharingModule } from 'src/app/modules/sharing.module' +import { SharedPipesModule } from '@start9labs/shared' const routes: Routes = [ { @@ -17,8 +17,8 @@ const routes: Routes = [ CommonModule, IonicModule, RouterModule.forChild(routes), - SharingModule, + SharedPipesModule, ], declarations: [WifiPage], }) -export class WifiPageModule { } +export class WifiPageModule {} diff --git a/frontend/projects/ui/src/app/pages/server-routes/wifi/wifi.page.ts b/frontend/projects/ui/src/app/pages/server-routes/wifi/wifi.page.ts index 14f8eb8cb..d96d0c4f1 100644 --- a/frontend/projects/ui/src/app/pages/server-routes/wifi/wifi.page.ts +++ b/frontend/projects/ui/src/app/pages/server-routes/wifi/wifi.page.ts @@ -12,7 +12,7 @@ import { ActionSheetButton } from '@ionic/core' import { ErrorToastService } from 'src/app/services/error-toast.service' import { ValueSpecObject } from 'src/app/pkg-config/config-types' import { RR } from 'src/app/services/api/api.types' -import { pauseFor } from 'src/app/util/misc.util' +import { pauseFor } from '@start9labs/shared' import { GenericFormPage } from 'src/app/modals/generic-form/generic-form.page' import { ConfigService } from 'src/app/services/config.service' diff --git a/frontend/projects/ui/src/app/pipes/convert-bytes.pipe.ts b/frontend/projects/ui/src/app/pipes/convert-bytes.pipe.ts deleted file mode 100644 index d60a59722..000000000 --- a/frontend/projects/ui/src/app/pipes/convert-bytes.pipe.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Pipe, PipeTransform } from '@angular/core' - -// converts bytes to gigabytes -@Pipe({ - name: 'convertBytes', -}) -export class ConvertBytesPipe implements PipeTransform { - transform (bytes: number): string { - if (bytes === 0) return '0 Bytes' - - const k = 1024 - const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] - - const i = Math.floor(Math.log(bytes) / Math.log(k)) - - return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i] - } -} diff --git a/frontend/projects/ui/src/app/pipes/install-state.pipe.ts b/frontend/projects/ui/src/app/pipes/install-state.pipe.ts deleted file mode 100644 index 0d339b8e5..000000000 --- a/frontend/projects/ui/src/app/pipes/install-state.pipe.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Pipe, PipeTransform } from '@angular/core' -import { PackageDataEntry } from '../services/patch-db/data-model' -import { - packageLoadingProgress, - ProgressData, -} from '../util/package-loading-progress' - -@Pipe({ - name: 'installState', -}) -export class InstallState implements PipeTransform { - transform(pkg: PackageDataEntry): ProgressData | null { - return packageLoadingProgress(pkg['install-progress']) - } -} diff --git a/frontend/projects/ui/src/app/pipes/launchable/launchable.module.ts b/frontend/projects/ui/src/app/pipes/launchable/launchable.module.ts new file mode 100644 index 000000000..9d516789f --- /dev/null +++ b/frontend/projects/ui/src/app/pipes/launchable/launchable.module.ts @@ -0,0 +1,8 @@ +import { NgModule } from '@angular/core' +import { LaunchablePipe } from './launchable.pipe' + +@NgModule({ + declarations: [LaunchablePipe], + exports: [LaunchablePipe], +}) +export class LaunchablePipeModule {} diff --git a/frontend/projects/ui/src/app/pipes/launchable/launchable.pipe.ts b/frontend/projects/ui/src/app/pipes/launchable/launchable.pipe.ts new file mode 100644 index 000000000..b664ab142 --- /dev/null +++ b/frontend/projects/ui/src/app/pipes/launchable/launchable.pipe.ts @@ -0,0 +1,22 @@ +import { Pipe, PipeTransform } from '@angular/core' +import { PackageState } from '@start9labs/shared' +import { + InterfaceDef, + PackageMainStatus, +} from 'src/app/services/patch-db/data-model' +import { ConfigService } from '../../services/config.service' + +@Pipe({ + name: 'isLaunchable', +}) +export class LaunchablePipe implements PipeTransform { + constructor(private configService: ConfigService) {} + + transform( + state: PackageState, + status: PackageMainStatus, + interfaces: Record, + ): boolean { + return this.configService.isLaunchable(state, status, interfaces) + } +} diff --git a/frontend/projects/ui/src/app/pipes/mask/mask.module.ts b/frontend/projects/ui/src/app/pipes/mask/mask.module.ts new file mode 100644 index 000000000..13950e553 --- /dev/null +++ b/frontend/projects/ui/src/app/pipes/mask/mask.module.ts @@ -0,0 +1,8 @@ +import { NgModule } from '@angular/core' +import { MaskPipe } from './mask.pipe' + +@NgModule({ + declarations: [MaskPipe], + exports: [MaskPipe], +}) +export class MaskPipeModule {} diff --git a/frontend/projects/ui/src/app/pipes/mask.pipe.ts b/frontend/projects/ui/src/app/pipes/mask/mask.pipe.ts similarity index 83% rename from frontend/projects/ui/src/app/pipes/mask.pipe.ts rename to frontend/projects/ui/src/app/pipes/mask/mask.pipe.ts index 143017beb..5f0dc2081 100644 --- a/frontend/projects/ui/src/app/pipes/mask.pipe.ts +++ b/frontend/projects/ui/src/app/pipes/mask/mask.pipe.ts @@ -4,9 +4,9 @@ import { Pipe, PipeTransform } from '@angular/core' name: 'mask', }) export class MaskPipe implements PipeTransform { - transform (val: string, max = 16): string { + transform(val: string, max = 16): string { if (!val) return val const times = val.length <= max ? val.length : max return '●'.repeat(times) } -} \ No newline at end of file +} diff --git a/frontend/projects/ui/src/app/pipes/notification-color.pipe.ts b/frontend/projects/ui/src/app/pipes/notification-color.pipe.ts deleted file mode 100644 index 6b48def86..000000000 --- a/frontend/projects/ui/src/app/pipes/notification-color.pipe.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Pipe, PipeTransform } from '@angular/core' -import { NotificationLevel, ServerNotification } from '../services/api/api.types' - -@Pipe({ - name: 'notificationColor', -}) -export class NotificationColorPipe implements PipeTransform { - transform (notification: ServerNotification): string { - const level = notification.level - switch (level) { - case NotificationLevel.Info: - return 'primary' - case NotificationLevel.Success: - return 'success' - case NotificationLevel.Warning: - return 'warning' - case NotificationLevel.Error: - return 'danger' - default: - return '' - } - } -} diff --git a/frontend/projects/ui/src/app/pipes/truncate.pipe.ts b/frontend/projects/ui/src/app/pipes/truncate.pipe.ts deleted file mode 100644 index 7100c7119..000000000 --- a/frontend/projects/ui/src/app/pipes/truncate.pipe.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Pipe, PipeTransform } from '@angular/core' - -@Pipe({ - name: 'truncateCenter', -}) -export class TruncateCenterPipe implements PipeTransform { - transform (value: string, front: number, back: number, fullOnDesktop: boolean = false): unknown { - if (value.length <= front + back + 3) return value - if (fullOnDesktop && screen.width > 500) return value - return value.slice(0, front) + '...' + value.slice(value.length - back, value.length) - } -} - -@Pipe({ - name: 'truncateEnd', -}) -export class TruncateEndPipe implements PipeTransform { - transform (val: string, length: number): unknown { - if (val.length <= length) return val - return val.slice(0, length) + '...' - } -} - -@Pipe({ - name: 'truncateTail', -}) -export class TruncateTailPipe implements PipeTransform { - transform (val: string, length: number): unknown { - if (val.length <= length) return val - return '...' + val.substr(length * -1) - } -} - diff --git a/frontend/projects/ui/src/app/pipes/typeof.pipe.ts b/frontend/projects/ui/src/app/pipes/typeof.pipe.ts deleted file mode 100644 index 46060c9a1..000000000 --- a/frontend/projects/ui/src/app/pipes/typeof.pipe.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Pipe, PipeTransform } from '@angular/core' - -@Pipe({ - name: 'typeof', -}) -export class TypeofPipe implements PipeTransform { - transform (value: any): any { - if (value === null) { - return 'null' - } else if (Array.isArray(value)) { - return 'array' - } - - return typeof value - } -} \ No newline at end of file diff --git a/frontend/projects/ui/src/app/pipes/ui.pipe.ts b/frontend/projects/ui/src/app/pipes/ui.pipe.ts deleted file mode 100644 index 481e46a99..000000000 --- a/frontend/projects/ui/src/app/pipes/ui.pipe.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Pipe, PipeTransform } from '@angular/core' -import { - InterfaceDef, - PackageMainStatus, - PackageState, -} from '../services/patch-db/data-model' -import { ConfigService, hasUi } from '../services/config.service' -import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser' - -@Pipe({ - name: 'hasUi', -}) -export class HasUiPipe implements PipeTransform { - transform(interfaces: { [id: string]: InterfaceDef }): boolean { - return hasUi(interfaces) - } -} - -@Pipe({ - name: 'isLaunchable', -}) -export class LaunchablePipe implements PipeTransform { - constructor(private configService: ConfigService) {} - - transform( - state: PackageState, - status: PackageMainStatus, - interfaces: { [id: string]: InterfaceDef }, - ): boolean { - return this.configService.isLaunchable(state, status, interfaces) - } -} - -@Pipe({ - name: 'sanitize', -}) -export class SanitizePipe implements PipeTransform { - constructor(public readonly sanitizer: DomSanitizer) {} - - transform(base64Icon: string): SafeResourceUrl { - return this.sanitizer.bypassSecurityTrustResourceUrl(base64Icon) - } -} diff --git a/frontend/projects/ui/src/app/pipes/ui/ui.module.ts b/frontend/projects/ui/src/app/pipes/ui/ui.module.ts new file mode 100644 index 000000000..9637306de --- /dev/null +++ b/frontend/projects/ui/src/app/pipes/ui/ui.module.ts @@ -0,0 +1,8 @@ +import { NgModule } from '@angular/core' +import { UiPipe } from './ui.pipe' + +@NgModule({ + declarations: [UiPipe], + exports: [UiPipe], +}) +export class UiPipeModule {} diff --git a/frontend/projects/ui/src/app/pipes/ui/ui.pipe.ts b/frontend/projects/ui/src/app/pipes/ui/ui.pipe.ts new file mode 100644 index 000000000..9d46bfd86 --- /dev/null +++ b/frontend/projects/ui/src/app/pipes/ui/ui.pipe.ts @@ -0,0 +1,12 @@ +import { Pipe, PipeTransform } from '@angular/core' +import { InterfaceDef } from '../../services/patch-db/data-model' +import { hasUi } from '../../services/config.service' + +@Pipe({ + name: 'hasUi', +}) +export class UiPipe implements PipeTransform { + transform(interfaces: Record): boolean { + return hasUi(interfaces) + } +} diff --git a/frontend/projects/ui/src/app/pipes/unit-conversion.pipe.ts b/frontend/projects/ui/src/app/pipes/unit-conversion.pipe.ts deleted file mode 100644 index b43d6c6d6..000000000 --- a/frontend/projects/ui/src/app/pipes/unit-conversion.pipe.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Pipe, PipeTransform } from '@angular/core' - -@Pipe({ - name: 'durationToSeconds', -}) -export class DurationToSecondsPipe implements PipeTransform { - transform (duration: string | null): number { - if (!duration) return 0 - const splitUnit = duration.match(/^([0-9]*(\.[0-9]+)?)(ns|µs|ms|s|m|d)$/) - const unit = splitUnit[3] - const num = splitUnit[1] - return Number(num) * unitsToSeconds[unit] - } -} - -const unitsToSeconds = { - 'ns': 1e-9, - 'µs': 1e-6, - 'ms': 0.001, - 's': 1, - 'm': 60, - 'h': 3600, - 'd': 86400, -} \ No newline at end of file diff --git a/frontend/projects/ui/src/app/pkg-config/config-types.ts b/frontend/projects/ui/src/app/pkg-config/config-types.ts index b690ba1c9..0cc5da1a2 100644 --- a/frontend/projects/ui/src/app/pkg-config/config-types.ts +++ b/frontend/projects/ui/src/app/pkg-config/config-types.ts @@ -1,6 +1,4 @@ -export interface ConfigSpec { - [key: string]: ValueSpec -} +export type ConfigSpec = Record export type ValueType = | 'string' diff --git a/frontend/projects/ui/src/app/pkg-config/config-utilities.ts b/frontend/projects/ui/src/app/pkg-config/config-utilities.ts index a7a0ba49a..672625f9d 100644 --- a/frontend/projects/ui/src/app/pkg-config/config-utilities.ts +++ b/frontend/projects/ui/src/app/pkg-config/config-utilities.ts @@ -6,7 +6,7 @@ export class Range { minInclusive: boolean maxInclusive: boolean - static from (s: string): Range { + static from(s: string): Range { const r = new Range() r.minInclusive = s.startsWith('[') r.maxInclusive = s.endsWith(']') @@ -16,44 +16,38 @@ export class Range { return r } - checkIncludes (n: number) { + checkIncludes(n: number) { if ( this.hasMin() !== undefined && - ( - (this.min > n) || - (!this.minInclusive && this.min == n) - ) + (this.min > n || (!this.minInclusive && this.min == n)) ) { throw new Error(this.minMessage()) } if ( this.hasMax() && - ( - (this.max < n) || - (!this.maxInclusive && this.max == n) - ) + (this.max < n || (!this.maxInclusive && this.max == n)) ) { throw new Error(this.maxMessage()) } } - hasMin (): boolean { + hasMin(): boolean { return this.min !== undefined } - hasMax (): boolean { + hasMax(): boolean { return this.max !== undefined } - minMessage (): string { + minMessage(): string { return `greater than${this.minInclusive ? ' or equal to' : ''} ${this.min}` } - maxMessage (): string { + maxMessage(): string { return `less than${this.maxInclusive ? ' or equal to' : ''} ${this.max}` } - description (): string { + description(): string { let message = 'Value can be any number.' if (this.hasMin() || this.hasMax()) { @@ -71,7 +65,7 @@ export class Range { return message } - integralMin (): number | undefined { + integralMin(): number | undefined { if (this.min) { const ceil = Math.ceil(this.min) if (this.minInclusive) { @@ -86,7 +80,7 @@ export class Range { } } - integralMax (): number | undefined { + integralMax(): number | undefined { if (this.max) { const floor = Math.floor(this.max) if (this.maxInclusive) { @@ -102,7 +96,7 @@ export class Range { } } -export function getDefaultDescription (spec: ValueSpec): string { +export function getDefaultDescription(spec: ValueSpec): string { let toReturn: string | undefined switch (spec.type) { case 'string': @@ -128,7 +122,7 @@ export function getDefaultDescription (spec: ValueSpec): string { return toReturn || '' } -export function getDefaultString (defaultSpec: DefaultString): string { +export function getDefaultString(defaultSpec: DefaultString): string { if (typeof defaultSpec === 'string') { return defaultSpec } else { @@ -142,7 +136,7 @@ export function getDefaultString (defaultSpec: DefaultString): string { } // a,g,h,A-Z,,,,- -export function getRandomCharInSet (charset: string): string { +export function getRandomCharInSet(charset: string): string { const set = stringToCharSet(charset) let charIdx = Math.floor(Math.random() * set.len) for (let range of set.ranges) { @@ -154,7 +148,7 @@ export function getRandomCharInSet (charset: string): string { throw new Error('unreachable') } -function stringToCharSet (charset: string): CharSet { +function stringToCharSet(charset: string): CharSet { let set: CharSet = { ranges: [], len: 0 } let start: string | null = null let end: string | null = null @@ -238,4 +232,4 @@ interface CharSet { len: number }[] len: number -} \ No newline at end of file +} diff --git a/frontend/projects/ui/src/app/services/api/api.fixures.ts b/frontend/projects/ui/src/app/services/api/api.fixures.ts index 034ea00d1..4bf35f109 100644 --- a/frontend/projects/ui/src/app/services/api/api.fixures.ts +++ b/frontend/projects/ui/src/app/services/api/api.fixures.ts @@ -1,3 +1,4 @@ +import { PackageState } from '@start9labs/shared' import { ConfigSpec } from 'src/app/pkg-config/config-types' import { DependencyErrorType, @@ -5,14 +6,13 @@ import { Manifest, PackageDataEntry, PackageMainStatus, - PackageState, } from 'src/app/services/patch-db/data-model' import { Log, MarketplacePkg, Metric, - NotificationLevel, RR, + NotificationLevel, ServerNotifications, } from './api.types' @@ -479,7 +479,7 @@ export module Mock { 'As long as Bitcoin is pruned, LND needs Bitcoin Proxy to fetch block over the P2P network.', requirement: { type: 'opt-in', - how: "To use Proxy's user management system, go to LND config and select Bitcoin Proxy under Bitcoin config.", + how: `To use Proxy's user management system, go to LND config and select Bitcoin Proxy under Bitcoin config.`, }, config: null, }, diff --git a/frontend/projects/ui/src/app/services/api/embassy-mock-api.service.ts b/frontend/projects/ui/src/app/services/api/embassy-mock-api.service.ts index 916d08dff..e8c46f097 100644 --- a/frontend/projects/ui/src/app/services/api/embassy-mock-api.service.ts +++ b/frontend/projects/ui/src/app/services/api/embassy-mock-api.service.ts @@ -1,14 +1,13 @@ import { Injectable } from '@angular/core' -import { pauseFor } from '../../util/misc.util' +import { InstallProgress, pauseFor } from '@start9labs/shared' import { ApiService } from './embassy-api.service' import { PatchOp, Update, Operation, RemoveOperation } from 'patch-db-client' +import { PackageState } from '@start9labs/shared' import { DataModel, DependencyErrorType, - InstallProgress, PackageDataEntry, PackageMainStatus, - PackageState, ServerStatus, } from 'src/app/services/patch-db/data-model' import { CifsBackupTarget, Log, RR, WithRevision } from './api.types' @@ -25,22 +24,22 @@ export class MockApiService extends ApiService { private readonly revertTime = 4000 sequence: number - constructor (private readonly bootstrapper: LocalStorageBootstrap) { + constructor(private readonly bootstrapper: LocalStorageBootstrap) { super() } - async getStatic (url: string): Promise { + async getStatic(url: string): Promise { await pauseFor(2000) return markdown } // db - async getRevisions (since: number): Promise { + async getRevisions(since: number): Promise { return this.getDump() } - async getDump (): Promise { + async getDump(): Promise { const cache = await this.bootstrapper.init() return { id: cache.sequence, @@ -49,7 +48,7 @@ export class MockApiService extends ApiService { } } - async setDbValueRaw (params: RR.SetDBValueReq): Promise { + async setDbValueRaw(params: RR.SetDBValueReq): Promise { await pauseFor(2000) const patch = [ { @@ -63,7 +62,7 @@ export class MockApiService extends ApiService { // auth - async login (params: RR.LoginReq): Promise { + async login(params: RR.LoginReq): Promise { await pauseFor(2000) setTimeout(() => { @@ -73,24 +72,24 @@ export class MockApiService extends ApiService { return null } - async logout (params: RR.LogoutReq): Promise { + async logout(params: RR.LogoutReq): Promise { await pauseFor(2000) return null } - async getSessions (params: RR.GetSessionsReq): Promise { + async getSessions(params: RR.GetSessionsReq): Promise { await pauseFor(2000) return Mock.Sessions } - async killSessions (params: RR.KillSessionsReq): Promise { + async killSessions(params: RR.KillSessionsReq): Promise { await pauseFor(2000) return null } // server - async getServerLogs ( + async getServerLogs( params: RR.GetServerLogsReq, ): Promise { await pauseFor(2000) @@ -112,21 +111,21 @@ export class MockApiService extends ApiService { } } - async getServerMetrics ( + async getServerMetrics( params: RR.GetServerMetricsReq, ): Promise { await pauseFor(2000) return Mock.getServerMetrics() } - async getPkgMetrics ( + async getPkgMetrics( params: RR.GetServerMetricsReq, ): Promise { await pauseFor(2000) return Mock.getAppMetrics() } - async updateServerRaw ( + async updateServerRaw( params: RR.UpdateServerReq, ): Promise { await pauseFor(2000) @@ -150,21 +149,21 @@ export class MockApiService extends ApiService { return this.withRevision(patch, 'updating') } - async restartServer ( + async restartServer( params: RR.RestartServerReq, ): Promise { await pauseFor(2000) return null } - async shutdownServer ( + async shutdownServer( params: RR.ShutdownServerReq, ): Promise { await pauseFor(2000) return null } - async systemRebuild ( + async systemRebuild( params: RR.RestartServerReq, ): Promise { await pauseFor(2000) @@ -173,7 +172,7 @@ export class MockApiService extends ApiService { // marketplace URLs - async marketplaceProxy (path: string, params: {}, url: string): Promise { + async marketplaceProxy(path: string, params: {}, url: string): Promise { await pauseFor(2000) if (path === '/package/v0/info') { @@ -196,7 +195,7 @@ export class MockApiService extends ApiService { } } - async getEos ( + async getEos( params: RR.GetMarketplaceEOSReq, ): Promise { await pauseFor(2000) @@ -211,7 +210,7 @@ export class MockApiService extends ApiService { // notification - async getNotificationsRaw ( + async getNotificationsRaw( params: RR.GetNotificationsReq, ): Promise { await pauseFor(2000) @@ -226,14 +225,14 @@ export class MockApiService extends ApiService { return this.withRevision(patch, Mock.Notifications) } - async deleteNotification ( + async deleteNotification( params: RR.DeleteNotificationReq, ): Promise { await pauseFor(2000) return null } - async deleteAllNotifications ( + async deleteAllNotifications( params: RR.DeleteAllNotificationsReq, ): Promise { await pauseFor(2000) @@ -242,60 +241,60 @@ export class MockApiService extends ApiService { // wifi - async getWifi (params: RR.GetWifiReq): Promise { + async getWifi(params: RR.GetWifiReq): Promise { await pauseFor(2000) return Mock.Wifi } - async setWifiCountry ( + async setWifiCountry( params: RR.SetWifiCountryReq, ): Promise { await pauseFor(2000) return null } - async addWifi (params: RR.AddWifiReq): Promise { + async addWifi(params: RR.AddWifiReq): Promise { await pauseFor(2000) return null } - async connectWifi (params: RR.ConnectWifiReq): Promise { + async connectWifi(params: RR.ConnectWifiReq): Promise { await pauseFor(2000) return null } - async deleteWifi (params: RR.DeleteWifiReq): Promise { + async deleteWifi(params: RR.DeleteWifiReq): Promise { await pauseFor(2000) return null } // ssh - async getSshKeys (params: RR.GetSSHKeysReq): Promise { + async getSshKeys(params: RR.GetSSHKeysReq): Promise { await pauseFor(2000) return Mock.SshKeys } - async addSshKey (params: RR.AddSSHKeyReq): Promise { + async addSshKey(params: RR.AddSSHKeyReq): Promise { await pauseFor(2000) return Mock.SshKey } - async deleteSshKey (params: RR.DeleteSSHKeyReq): Promise { + async deleteSshKey(params: RR.DeleteSSHKeyReq): Promise { await pauseFor(2000) return null } // backup - async getBackupTargets ( + async getBackupTargets( params: RR.GetBackupTargetsReq, ): Promise { await pauseFor(2000) return Mock.BackupTargets } - async addBackupTarget ( + async addBackupTarget( params: RR.AddBackupTargetReq, ): Promise { await pauseFor(2000) @@ -312,7 +311,7 @@ export class MockApiService extends ApiService { } } - async updateBackupTarget ( + async updateBackupTarget( params: RR.UpdateBackupTargetReq, ): Promise { await pauseFor(2000) @@ -327,21 +326,21 @@ export class MockApiService extends ApiService { } } - async removeBackupTarget ( + async removeBackupTarget( params: RR.RemoveBackupTargetReq, ): Promise { await pauseFor(2000) return null } - async getBackupInfo ( + async getBackupInfo( params: RR.GetBackupInfoReq, ): Promise { await pauseFor(2000) return Mock.BackupInfo } - async createBackupRaw ( + async createBackupRaw( params: RR.CreateBackupReq, ): Promise { await pauseFor(2000) @@ -392,14 +391,14 @@ export class MockApiService extends ApiService { // package - async getPackageProperties ( + async getPackageProperties( params: RR.GetPackagePropertiesReq, ): Promise['data']> { await pauseFor(2000) return parsePropertiesPermissive(Mock.PackageProperties) } - async getPackageLogs ( + async getPackageLogs( params: RR.GetPackageLogsReq, ): Promise { await pauseFor(2000) @@ -421,7 +420,7 @@ export class MockApiService extends ApiService { } } - async installPackageRaw ( + async installPackageRaw( params: RR.InstallPackageReq, ): Promise { await pauseFor(2000) @@ -456,14 +455,14 @@ export class MockApiService extends ApiService { return this.withRevision(patch) } - async dryUpdatePackage ( + async dryUpdatePackage( params: RR.DryUpdatePackageReq, ): Promise { await pauseFor(2000) return {} } - async getPackageConfig ( + async getPackageConfig( params: RR.GetPackageConfigReq, ): Promise { await pauseFor(2000) @@ -473,14 +472,14 @@ export class MockApiService extends ApiService { } } - async drySetPackageConfig ( + async drySetPackageConfig( params: RR.DrySetPackageConfigReq, ): Promise { await pauseFor(2000) return {} } - async setPackageConfigRaw ( + async setPackageConfigRaw( params: RR.SetPackageConfigReq, ): Promise { await pauseFor(2000) @@ -494,7 +493,7 @@ export class MockApiService extends ApiService { return this.withRevision(patch) } - async restorePackagesRaw ( + async restorePackagesRaw( params: RR.RestorePackagesReq, ): Promise { await pauseFor(2000) @@ -530,14 +529,14 @@ export class MockApiService extends ApiService { return this.withRevision(patch) } - async executePackageAction ( + async executePackageAction( params: RR.ExecutePackageActionReq, ): Promise { await pauseFor(2000) return Mock.ActionResponse } - async startPackageRaw ( + async startPackageRaw( params: RR.StartPackageReq, ): Promise { const path = `/package-data/${params.id}/installed/status/main` @@ -616,7 +615,7 @@ export class MockApiService extends ApiService { return this.withRevision(originalPatch) } - async dryStopPackage ( + async dryStopPackage( params: RR.DryStopPackageReq, ): Promise { await pauseFor(2000) @@ -630,7 +629,7 @@ export class MockApiService extends ApiService { } } - async stopPackageRaw (params: RR.StopPackageReq): Promise { + async stopPackageRaw(params: RR.StopPackageReq): Promise { await pauseFor(2000) const path = `/package-data/${params.id}/installed/status/main` @@ -661,14 +660,14 @@ export class MockApiService extends ApiService { return this.withRevision(patch) } - async dryUninstallPackage ( + async dryUninstallPackage( params: RR.DryUninstallPackageReq, ): Promise { await pauseFor(2000) return {} } - async uninstallPackageRaw ( + async uninstallPackageRaw( params: RR.UninstallPackageReq, ): Promise { await pauseFor(2000) @@ -694,7 +693,7 @@ export class MockApiService extends ApiService { return this.withRevision(patch) } - async deleteRecoveredPackageRaw ( + async deleteRecoveredPackageRaw( params: RR.DeleteRecoveredPackageReq, ): Promise { await pauseFor(2000) @@ -707,7 +706,7 @@ export class MockApiService extends ApiService { return this.withRevision(patch) } - async dryConfigureDependency ( + async dryConfigureDependency( params: RR.DryConfigureDependencyReq, ): Promise { await pauseFor(2000) @@ -718,7 +717,7 @@ export class MockApiService extends ApiService { } } - private async updateProgress ( + private async updateProgress( id: string, initialProgress: InstallProgress, ): Promise { @@ -764,7 +763,7 @@ export class MockApiService extends ApiService { }, 1000) } - private async updateOSProgress (size: number) { + private async updateOSProgress(size: number) { let downloaded = 0 while (downloaded < size) { await pauseFor(250) @@ -814,7 +813,7 @@ export class MockApiService extends ApiService { }, 1000) } - private async updateMock (patch: Operation[]): Promise { + private async updateMock(patch: Operation[]): Promise { if (!this.sequence) { const { sequence } = await this.bootstrapper.init() this.sequence = sequence @@ -827,7 +826,7 @@ export class MockApiService extends ApiService { this.mockPatch$.next(revision) } - private async withRevision ( + private async withRevision( patch: Operation[], response: T = null, ): Promise> { diff --git a/frontend/projects/ui/src/app/services/api/mock-patch.ts b/frontend/projects/ui/src/app/services/api/mock-patch.ts index 014614577..4ec4962ea 100644 --- a/frontend/projects/ui/src/app/services/api/mock-patch.ts +++ b/frontend/projects/ui/src/app/services/api/mock-patch.ts @@ -1,3 +1,4 @@ +import { PackageState } from '@start9labs/shared' import { DataModel, DependencyErrorType, @@ -5,13 +6,11 @@ import { HealthResult, Manifest, PackageMainStatus, - PackageState, - ServerStatus, } from 'src/app/services/patch-db/data-model' export const mockPatchData: DataModel = { ui: { - name: "Matt's Embassy", + name: `Matt's Embassy`, 'auto-check-updates': true, 'pkg-order': [], 'ack-welcome': '1.0.0', @@ -86,13 +85,11 @@ export const mockPatchData: DataModel = { }, 'ephemeral-health-check': { name: 'Ephemeral Health Check', - description: - "Checks to see if your new user registrations are on. If they are but you're not expecting any new user signups, you should disable this in Config, as anyone who knows your onion URL can create accounts on your server.", + description: `Checks to see if your new user registrations are on. If they are but you're not expecting any new user signups, you should disable this in Config, as anyone who knows your onion URL can create accounts on your server.`, }, 'p2p-interface': { name: 'P2P Interface', - description: - "Checks to see if your new user registrations are on. If they are but you're not expecting any new user signups, you should disable this in Config, as anyone who knows your onion URL can create accounts on your server.", + description: `Checks to see if your new user registrations are on. If they are but you're not expecting any new user signups, you should disable this in Config, as anyone who knows your onion URL can create accounts on your server.`, }, 'rpc-interface': { name: 'RPC Interface', @@ -577,7 +574,7 @@ export const mockPatchData: DataModel = { 'As long as Bitcoin is pruned, LND needs Bitcoin Proxy to fetch block over the P2P network.', requirement: { type: 'opt-in', - how: "To use Proxy's user management system, go to LND config and select Bitcoin Proxy under Bitcoin config.", + how: `To use Proxy's user management system, go to LND config and select Bitcoin Proxy under Bitcoin config.`, }, config: null, }, diff --git a/frontend/projects/ui/src/app/services/config.service.ts b/frontend/projects/ui/src/app/services/config.service.ts index 0b2442ac1..05cc718d5 100644 --- a/frontend/projects/ui/src/app/services/config.service.ts +++ b/frontend/projects/ui/src/app/services/config.service.ts @@ -1,11 +1,10 @@ import { Injectable } from '@angular/core' +import { WorkspaceConfig, PackageState } from '@start9labs/shared' import { InterfaceDef, PackageDataEntry, PackageMainStatus, - PackageState, -} from './patch-db/data-model' -import { WorkspaceConfig } from '@shared' +} from 'src/app/services/patch-db/data-model' const { gitHash, diff --git a/frontend/projects/ui/src/app/services/eos.service.ts b/frontend/projects/ui/src/app/services/eos.service.ts index bf0d9657a..1dfde300d 100644 --- a/frontend/projects/ui/src/app/services/eos.service.ts +++ b/frontend/projects/ui/src/app/services/eos.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core' import { BehaviorSubject } from 'rxjs' import { MarketplaceEOS } from 'src/app/services/api/api.types' import { ApiService } from 'src/app/services/api/embassy-api.service' -import { Emver } from 'src/app/services/emver.service' +import { Emver } from '@start9labs/shared' import { PatchDbService } from 'src/app/services/patch-db/patch-db.service' @Injectable({ diff --git a/frontend/projects/ui/src/app/services/form.service.ts b/frontend/projects/ui/src/app/services/form.service.ts index 87007c145..77819ea15 100644 --- a/frontend/projects/ui/src/app/services/form.service.ts +++ b/frontend/projects/ui/src/app/services/form.service.ts @@ -1,6 +1,31 @@ import { Injectable } from '@angular/core' -import { AbstractControl, FormArray, FormBuilder, FormControl, FormGroup, ValidationErrors, ValidatorFn, Validators } from '@angular/forms' -import { ConfigSpec, isValueSpecListOf, ListValueSpecNumber, ListValueSpecObject, ListValueSpecOf, ListValueSpecString, ListValueSpecUnion, UniqueBy, ValueSpec, ValueSpecEnum, ValueSpecList, ValueSpecNumber, ValueSpecObject, ValueSpecString, ValueSpecUnion } from '../pkg-config/config-types' +import { + AbstractControl, + FormArray, + FormBuilder, + FormControl, + FormGroup, + ValidationErrors, + ValidatorFn, + Validators, +} from '@angular/forms' +import { + ConfigSpec, + isValueSpecListOf, + ListValueSpecNumber, + ListValueSpecObject, + ListValueSpecOf, + ListValueSpecString, + ListValueSpecUnion, + UniqueBy, + ValueSpec, + ValueSpecEnum, + ValueSpecList, + ValueSpecNumber, + ValueSpecObject, + ValueSpecString, + ValueSpecUnion, +} from 'src/app/pkg-config/config-types' import { getDefaultString, Range } from '../pkg-config/config-utilities' const Mustache = require('mustache') @@ -8,18 +33,24 @@ const Mustache = require('mustache') providedIn: 'root', }) export class FormService { + constructor(private readonly formBuilder: FormBuilder) {} - constructor ( - private readonly formBuilder: FormBuilder, - ) { } - - createForm (spec: ConfigSpec, current: { [key: string]: any } = { }): FormGroup { + createForm( + spec: ConfigSpec, + current: { [key: string]: any } = {}, + ): FormGroup { return this.getFormGroup(spec, [], current) } - getUnionObject (spec: ValueSpecUnion | ListValueSpecUnion, selection: string, current?: { [key: string]: any }): FormGroup { + getUnionObject( + spec: ValueSpecUnion | ListValueSpecUnion, + selection: string, + current?: { [key: string]: any }, + ): FormGroup { const { variants, tag } = spec - const { name, description, warning } = isFullUnion(spec) ? spec : { ...spec.tag, warning: undefined } + const { name, description, warning } = isFullUnion(spec) + ? spec + : { ...spec.tag, warning: undefined } const enumSpec: ValueSpecEnum = { type: 'enum', @@ -30,10 +61,14 @@ export class FormService { values: Object.keys(variants), 'value-names': tag['variant-names'], } - return this.getFormGroup({ [spec.tag.id]: enumSpec, ...spec.variants[selection] }, [], current) + return this.getFormGroup( + { [spec.tag.id]: enumSpec, ...spec.variants[selection] }, + [], + current, + ) } - getListItem (spec: ValueSpecList, entry: any) { + getListItem(spec: ValueSpecList, entry: any) { const listItemValidators = this.getListItemValidators(spec) if (isValueSpecListOf(spec, 'string')) { return this.formBuilder.control(entry, listItemValidators) @@ -48,7 +83,7 @@ export class FormService { } } - private getListItemValidators (spec: ValueSpecList) { + private getListItemValidators(spec: ValueSpecList) { if (isValueSpecListOf(spec, 'string')) { return this.stringValidators(spec.spec) } else if (isValueSpecListOf(spec, 'number')) { @@ -56,16 +91,23 @@ export class FormService { } } - private getFormGroup (config: ConfigSpec, validators: ValidatorFn[] = [], current: { [key: string]: any } = { }): FormGroup { - let group = { } + private getFormGroup( + config: ConfigSpec, + validators: ValidatorFn[] = [], + current: { [key: string]: any } = {}, + ): FormGroup { + let group = {} Object.entries(config).map(([key, spec]) => { if (spec.type === 'pointer') return group[key] = this.getFormEntry(spec, current ? current[key] : undefined) }) - return this.formBuilder.group(group, { validators } ) + return this.formBuilder.group(group, { validators }) } - private getFormEntry (spec: ValueSpec, currentValue?: any): FormGroup | FormArray | FormControl { + private getFormEntry( + spec: ValueSpec, + currentValue?: any, + ): FormGroup | FormArray | FormControl { let validators: ValidatorFn[] let value: any switch (spec.type) { @@ -89,12 +131,18 @@ export class FormService { return this.getFormGroup(spec.spec, [], currentValue) case 'list': validators = this.listValidators(spec) - const mapped = (Array.isArray(currentValue) ? currentValue : spec.default as any[]).map(entry => { + const mapped = ( + Array.isArray(currentValue) ? currentValue : (spec.default as any[]) + ).map(entry => { return this.getListItem(spec, entry) }) return this.formBuilder.array(mapped, validators) case 'union': - return this.getUnionObject(spec, currentValue?.[spec.tag.id] || spec.default, currentValue) + return this.getUnionObject( + spec, + currentValue?.[spec.tag.id] || spec.default, + currentValue, + ) case 'boolean': case 'enum': value = currentValue === undefined ? spec.default : currentValue @@ -102,7 +150,9 @@ export class FormService { } } - private stringValidators (spec: ValueSpecString | ListValueSpecString): ValidatorFn[] { + private stringValidators( + spec: ValueSpecString | ListValueSpecString, + ): ValidatorFn[] { const validators: ValidatorFn[] = [] if (!(spec as ValueSpecString).nullable) { @@ -116,7 +166,9 @@ export class FormService { return validators } - private numberValidators (spec: ValueSpecNumber | ListValueSpecNumber): ValidatorFn[] { + private numberValidators( + spec: ValueSpecNumber | ListValueSpecNumber, + ): ValidatorFn[] { const validators: ValidatorFn[] = [] validators.push(isNumber()) @@ -134,7 +186,7 @@ export class FormService { return validators } - private listValidators (spec: ValueSpecList): ValidatorFn[] { + private listValidators(spec: ValueSpecList): ValidatorFn[] { const validators: ValidatorFn[] = [] validators.push(listInRange(spec.range)) @@ -149,11 +201,13 @@ export class FormService { } } -function isFullUnion (spec: ValueSpecUnion | ListValueSpecUnion): spec is ValueSpecUnion { +function isFullUnion( + spec: ValueSpecUnion | ListValueSpecUnion, +): spec is ValueSpecUnion { return !!(spec as ValueSpecUnion).name } -export function numberInRange (stringRange: string): ValidatorFn { +export function numberInRange(stringRange: string): ValidatorFn { return (control: AbstractControl): ValidationErrors | null => { const value = control.value if (!value) return null @@ -166,23 +220,23 @@ export function numberInRange (stringRange: string): ValidatorFn { } } -export function isNumber (): ValidatorFn { +export function isNumber(): ValidatorFn { return (control: AbstractControl): ValidationErrors | null => { - return !control.value || control.value == Number(control.value) ? - null : - { notNumber: { value: control.value } } + return !control.value || control.value == Number(control.value) + ? null + : { notNumber: { value: control.value } } } } -export function isInteger (): ValidatorFn { +export function isInteger(): ValidatorFn { return (control: AbstractControl): ValidationErrors | null => { - return !control.value || control.value == Math.trunc(control.value) ? - null : - { numberNotInteger: { value: control.value } } + return !control.value || control.value == Math.trunc(control.value) + ? null + : { numberNotInteger: { value: control.value } } } } -export function listInRange (stringRange: string): ValidatorFn { +export function listInRange(stringRange: string): ValidatorFn { return (control: FormArray): ValidationErrors | null => { try { Range.from(stringRange).checkIncludes(control.value.length) @@ -193,7 +247,7 @@ export function listInRange (stringRange: string): ValidatorFn { } } -export function listItemIssue (): ValidatorFn { +export function listItemIssue(): ValidatorFn { return (parentControl: FormArray): ValidationErrors | null => { const problemChild = parentControl.controls.find(c => c.invalid) if (problemChild) { @@ -204,7 +258,7 @@ export function listItemIssue (): ValidatorFn { } } -export function listUnique (spec: ValueSpecList): ValidatorFn { +export function listUnique(spec: ValueSpecList): ValidatorFn { return (control: FormArray): ValidationErrors | null => { const list = control.value for (let idx = 0; idx < list.length; idx++) { @@ -212,17 +266,33 @@ export function listUnique (spec: ValueSpecList): ValidatorFn { if (listItemEquals(spec, list[idx], list[idx2])) { let display1: string let display2: string - let uniqueMessage = isObjectOrUnion(spec.spec) ? uniqueByMessageWrapper(spec.spec['unique-by'], spec.spec, list[idx]) : '' + let uniqueMessage = isObjectOrUnion(spec.spec) + ? uniqueByMessageWrapper( + spec.spec['unique-by'], + spec.spec, + list[idx], + ) + : '' if (isObjectOrUnion(spec.spec) && spec.spec['display-as']) { - display1 = `"${(Mustache as any).render(spec.spec['display-as'], list[idx])}"` - display2 = `"${(Mustache as any).render(spec.spec['display-as'], list[idx2])}"` + display1 = `"${(Mustache as any).render( + spec.spec['display-as'], + list[idx], + )}"` + display2 = `"${(Mustache as any).render( + spec.spec['display-as'], + list[idx2], + )}"` } else { display1 = `Entry ${idx + 1}` display2 = `Entry ${idx2 + 1}` } - return { listNotUnique: { value: `${display1} and ${display2} are not unique.${uniqueMessage}` } } + return { + listNotUnique: { + value: `${display1} and ${display2} are not unique.${uniqueMessage}`, + }, + } } } } @@ -230,22 +300,32 @@ export function listUnique (spec: ValueSpecList): ValidatorFn { } } -function listItemEquals (spec: ValueSpecList, val1: any, val2: any): boolean { +function listItemEquals(spec: ValueSpecList, val1: any, val2: any): boolean { switch (spec.subtype) { case 'string': case 'number': case 'enum': return val1 == val2 case 'object': - return listObjEquals(spec.spec['unique-by'], (spec.spec as ListValueSpecObject), val1, val2) + return listObjEquals( + spec.spec['unique-by'], + spec.spec as ListValueSpecObject, + val1, + val2, + ) case 'union': - return unionEquals(spec.spec['unique-by'], spec.spec as ListValueSpecUnion, val1, val2) + return unionEquals( + spec.spec['unique-by'], + spec.spec as ListValueSpecUnion, + val1, + val2, + ) default: return false } } -function itemEquals (spec: ValueSpec, val1: any, val2: any): boolean { +function itemEquals(spec: ValueSpec, val1: any, val2: any): boolean { switch (spec.type) { case 'string': case 'number': @@ -253,9 +333,9 @@ function itemEquals (spec: ValueSpec, val1: any, val2: any): boolean { case 'enum': return val1 == val2 case 'object': - return objEquals(spec['unique-by'], (spec as ValueSpecObject), val1, val2) + return objEquals(spec['unique-by'], spec as ValueSpecObject, val1, val2) case 'union': - return unionEquals(spec['unique-by'], (spec as ValueSpecUnion), val1, val2) + return unionEquals(spec['unique-by'], spec as ValueSpecUnion, val1, val2) case 'list': if (val1.length !== val2.length) { return false @@ -271,7 +351,12 @@ function itemEquals (spec: ValueSpec, val1: any, val2: any): boolean { } } -function listObjEquals (uniqueBy: UniqueBy, spec: ListValueSpecObject, val1: any, val2: any): boolean { +function listObjEquals( + uniqueBy: UniqueBy, + spec: ListValueSpecObject, + val1: any, + val2: any, +): boolean { if (uniqueBy === null) { return false } else if (typeof uniqueBy === 'string') { @@ -293,7 +378,12 @@ function listObjEquals (uniqueBy: UniqueBy, spec: ListValueSpecObject, val1: any } } -function objEquals (uniqueBy: UniqueBy, spec: ValueSpecObject, val1: any, val2: any): boolean { +function objEquals( + uniqueBy: UniqueBy, + spec: ValueSpecObject, + val1: any, + val2: any, +): boolean { if (uniqueBy === null) { return false } else if (typeof uniqueBy === 'string') { @@ -315,7 +405,12 @@ function objEquals (uniqueBy: UniqueBy, spec: ValueSpecObject, val1: any, val2: } } -function unionEquals (uniqueBy: UniqueBy, spec: ValueSpecUnion | ListValueSpecUnion, val1: any, val2: any): boolean { +function unionEquals( + uniqueBy: UniqueBy, + spec: ValueSpecUnion | ListValueSpecUnion, + val1: any, + val2: any, +): boolean { const tagId = spec.tag.id const variant = spec.variants[val1[tagId]] if (uniqueBy === null) { @@ -343,7 +438,11 @@ function unionEquals (uniqueBy: UniqueBy, spec: ValueSpecUnion | ListValueSpecUn } } -function uniqueByMessageWrapper (uniqueBy: UniqueBy, spec: ListValueSpecObject | ListValueSpecUnion, obj: object) { +function uniqueByMessageWrapper( + uniqueBy: UniqueBy, + spec: ListValueSpecObject | ListValueSpecUnion, + obj: object, +) { let configSpec: ConfigSpec if (isUnion(spec)) { const variantKey = obj[spec.tag.id] @@ -358,7 +457,11 @@ function uniqueByMessageWrapper (uniqueBy: UniqueBy, spec: ListValueSpecObject | } } -function uniqueByMessage (uniqueBy: UniqueBy, configSpec: ConfigSpec, outermost = true): string { +function uniqueByMessage( + uniqueBy: UniqueBy, + configSpec: ConfigSpec, + outermost = true, +): string { let joinFunc const subSpecs = [] if (uniqueBy === null) { @@ -377,20 +480,27 @@ function uniqueByMessage (uniqueBy: UniqueBy, configSpec: ConfigSpec, outermost } } const ret = subSpecs.filter(ss => ss).join(joinFunc) - return outermost || subSpecs.filter(ss => ss).length === 1 ? ret : '(' + ret + ')' + return outermost || subSpecs.filter(ss => ss).length === 1 + ? ret + : '(' + ret + ')' } -function isObjectOrUnion (spec: ListValueSpecOf): spec is ListValueSpecObject | ListValueSpecUnion { +function isObjectOrUnion( + spec: ListValueSpecOf, +): spec is ListValueSpecObject | ListValueSpecUnion { // only lists of objects and unions have unique-by return spec['unique-by'] !== undefined } -function isUnion (spec: any): spec is ListValueSpecUnion { +function isUnion(spec: any): spec is ListValueSpecUnion { // only unions have tag return !!spec.tag } -export function convertValuesRecursive (configSpec: ConfigSpec, group: FormGroup) { +export function convertValuesRecursive( + configSpec: ConfigSpec, + group: FormGroup, +) { Object.entries(configSpec).forEach(([key, valueSpec]) => { if (valueSpec.type === 'number') { const control = group.get(key) @@ -422,7 +532,8 @@ export function convertValuesRecursive (configSpec: ConfigSpec, group: FormGroup } else if (valueSpec.subtype === 'union') { formArr.controls.forEach((formGroup: FormGroup) => { const unionSpec = valueSpec.spec as ListValueSpecUnion - const spec = unionSpec.variants[formGroup.controls[unionSpec.tag.id].value] + const spec = + unionSpec.variants[formGroup.controls[unionSpec.tag.id].value] convertValuesRecursive(spec, formGroup) }) } diff --git a/frontend/projects/ui/src/app/services/modal.service.ts b/frontend/projects/ui/src/app/services/modal.service.ts index 77cbda2b4..df8174333 100644 --- a/frontend/projects/ui/src/app/services/modal.service.ts +++ b/frontend/projects/ui/src/app/services/modal.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core' import { ActivatedRoute } from '@angular/router' import { ModalController } from '@ionic/angular' -import { DependentInfo } from 'src/app/util/misc.util' +import { DependentInfo } from '@start9labs/shared' import { AppConfigPage } from 'src/app/modals/app-config/app-config.page' @Injectable({ diff --git a/frontend/projects/ui/src/app/services/patch-db/data-model.ts b/frontend/projects/ui/src/app/services/patch-db/data-model.ts index e08d307a9..d3a483942 100644 --- a/frontend/projects/ui/src/app/services/patch-db/data-model.ts +++ b/frontend/projects/ui/src/app/services/patch-db/data-model.ts @@ -1,4 +1,5 @@ import { ConfigSpec } from 'src/app/pkg-config/config-types' +import { InstallProgress, PackageState } from '@start9labs/shared' export interface DataModel { 'server-info': ServerInfo @@ -64,16 +65,6 @@ export interface PackageDataEntry { 'install-progress'?: InstallProgress // exists when: installing, updating } -export interface InstallProgress { - size: number | null - downloaded: number - 'download-complete': boolean - validated: number - 'validation-complete': boolean - unpacked: number - 'unpack-complete': boolean -} - export interface InstalledPackageDataEntry { status: Status manifest: Manifest @@ -99,14 +90,6 @@ export interface CurrentDependencyInfo { 'health-checks': string[] // array of health check IDs } -export enum PackageState { - Installing = 'installing', - Installed = 'installed', - Updating = 'updating', - Removing = 'removing', - Restoring = 'restoring', -} - export interface Manifest { id: string title: string @@ -377,17 +360,17 @@ export interface DependencyInfo { export interface DependencyEntry { version: string requirement: - | { - type: 'opt-in' - how: string - } - | { - type: 'opt-out' - how: string - } - | { - type: 'required' - } + | { + type: 'opt-in' + how: string + } + | { + type: 'opt-out' + how: string + } + | { + type: 'required' + } description: string | null config: { check: ActionImpl diff --git a/frontend/projects/ui/src/app/services/patch-db/local-storage-bootstrap.ts b/frontend/projects/ui/src/app/services/patch-db/local-storage-bootstrap.ts index 10b349cec..9a8c01e81 100644 --- a/frontend/projects/ui/src/app/services/patch-db/local-storage-bootstrap.ts +++ b/frontend/projects/ui/src/app/services/patch-db/local-storage-bootstrap.ts @@ -1,5 +1,5 @@ import { Bootstrapper, DBCache } from 'patch-db-client' -import { DataModel } from './data-model' +import { DataModel } from 'src/app/services/patch-db/data-model' import { Injectable } from '@angular/core' import { Storage } from '@ionic/storage-angular' @@ -9,16 +9,16 @@ import { Storage } from '@ionic/storage-angular' export class LocalStorageBootstrap implements Bootstrapper { static CONTENT_KEY = 'patch-db-cache' - constructor ( - private readonly storage: Storage, - ) { } + constructor(private readonly storage: Storage) {} - async init (): Promise> { - const cache: DBCache = await this.storage.get(LocalStorageBootstrap.CONTENT_KEY) - return cache || { sequence: 0, data: { } as DataModel } + async init(): Promise> { + const cache: DBCache = await this.storage.get( + LocalStorageBootstrap.CONTENT_KEY, + ) + return cache || { sequence: 0, data: {} as DataModel } } - async update (cache: DBCache): Promise { + async update(cache: DBCache): Promise { await this.storage.set(LocalStorageBootstrap.CONTENT_KEY, cache) } } diff --git a/frontend/projects/ui/src/app/services/patch-db/patch-db.factory.ts b/frontend/projects/ui/src/app/services/patch-db/patch-db.factory.ts index 73b5a4f10..0e0d326c3 100644 --- a/frontend/projects/ui/src/app/services/patch-db/patch-db.factory.ts +++ b/frontend/projects/ui/src/app/services/patch-db/patch-db.factory.ts @@ -1,24 +1,26 @@ import { MockSource, PollSource, WebsocketSource } from 'patch-db-client' import { ConfigService } from 'src/app/services/config.service' -import { DataModel } from './data-model' import { LocalStorageBootstrap } from './local-storage-bootstrap' import { PatchDbService } from './patch-db.service' import { ApiService } from 'src/app/services/api/embassy-api.service' import { AuthService } from '../auth.service' import { MockApiService } from '../api/embassy-mock-api.service' import { filter } from 'rxjs/operators' -import { exists } from 'src/app/util/misc.util' +import { exists } from '@start9labs/shared' +import { DataModel } from 'src/app/services/patch-db/data-model' import { Storage } from '@ionic/storage-angular' -export function PatchDbServiceFactory ( +export function PatchDbServiceFactory( config: ConfigService, embassyApi: ApiService, bootstrapper: LocalStorageBootstrap, auth: AuthService, storage: Storage, ): PatchDbService { - - const { useMocks, patchDb: { poll } } = config + const { + useMocks, + patchDb: { poll }, + } = config if (useMocks) { const source = new MockSource( diff --git a/frontend/projects/ui/src/app/services/patch-db/patch-db.service.ts b/frontend/projects/ui/src/app/services/patch-db/patch-db.service.ts index c3d4dfebf..fb6771011 100644 --- a/frontend/projects/ui/src/app/services/patch-db/patch-db.service.ts +++ b/frontend/projects/ui/src/app/services/patch-db/patch-db.service.ts @@ -10,10 +10,10 @@ import { tap, withLatestFrom, } from 'rxjs/operators' -import { isEmptyObject, pauseFor } from 'src/app/util/misc.util' +import { isEmptyObject, pauseFor } from '@start9labs/shared' +import { DataModel } from './data-model' import { ApiService } from '../api/embassy-api.service' import { AuthService } from '../auth.service' -import { DataModel } from './data-model' export const PATCH_HTTP = new InjectionToken>('') export const PATCH_SOURCE = new InjectionToken>('') @@ -44,15 +44,18 @@ export class PatchDbService { data: DataModel errors = 0 - getData () { + getData() { return this.patchDb.store.cache.data } - get loaded (): boolean { - return this.patchDb?.store?.cache?.data && !isEmptyObject(this.patchDb.store.cache.data) + get loaded(): boolean { + return ( + this.patchDb?.store?.cache?.data && + !isEmptyObject(this.patchDb.store.cache.data) + ) } - constructor ( + constructor( @Inject(PATCH_SOURCE) private readonly wsSource: Source, @Inject(PATCH_SOURCE) private readonly pollSource: Source, @Inject(PATCH_HTTP) private readonly http: ApiService, @@ -60,9 +63,9 @@ export class PatchDbService { private readonly bootstrapper: Bootstrapper, @Inject(AUTH) private readonly auth: AuthService, @Inject(STORAGE) private readonly storage: Storage, - ) { } + ) {} - async init (): Promise { + async init(): Promise { const cache = await this.bootstrapper.init() this.sources$.next([this.wsSource, this.http]) @@ -72,7 +75,7 @@ export class PatchDbService { this.data = this.patchDb.store.cache.data } - async start (): Promise { + async start(): Promise { await this.init() this.subs.push( @@ -156,26 +159,27 @@ export class PatchDbService { ) } - stop (): void { + stop(): void { if (this.patchDb) { console.log('patchDB: STOPPING') this.patchConnection$.next(PatchConnection.Initializing) this.patchDb.store.reset() } - this.subs.forEach((x) => x.unsubscribe()) + this.subs.forEach(x => x.unsubscribe()) this.subs = [] } - watchPatchConnection$ (): Observable { + watchPatchConnection$(): Observable { return this.patchConnection$.asObservable() } + // prettier-ignore watch$: Store['watch$'] = (...args: (string | number)[]): Observable => { const argsString = '/' + args.join('/') console.log('patchDB: WATCHING ', argsString) return this.patchDb.store.watch$(...(args as [])).pipe( - tap((data) => console.log('patchDB: NEW VALUE', argsString, data)), - catchError((e) => { + tap(data => console.log('patchDB: NEW VALUE', argsString, data)), + catchError(e => { console.error('patchDB: WATCH ERROR', e) return of(e.message) }), diff --git a/frontend/projects/ui/src/app/services/pkg-status-rendering.service.ts b/frontend/projects/ui/src/app/services/pkg-status-rendering.service.ts index 31094caf0..3ff832d9f 100644 --- a/frontend/projects/ui/src/app/services/pkg-status-rendering.service.ts +++ b/frontend/projects/ui/src/app/services/pkg-status-rendering.service.ts @@ -1,10 +1,9 @@ -import { isEmptyObject } from '../util/misc.util' +import { isEmptyObject, PackageState } from '@start9labs/shared' import { PackageDataEntry, PackageMainStatus, - PackageState, Status, -} from './patch-db/data-model' +} from 'src/app/services/patch-db/data-model' export interface PackageStatus { primary: PrimaryStatus @@ -95,25 +94,61 @@ export enum HealthStatus { Healthy = 'healthy', } -export const PrimaryRendering: { [key: string]: StatusRendering } = { - [PrimaryStatus.Installing]: { display: 'Installing', color: 'primary', showDots: true }, - [PrimaryStatus.Updating]: { display: 'Updating', color: 'primary', showDots: true }, - [PrimaryStatus.Removing]: { display: 'Removing', color: 'danger', showDots: true }, - [PrimaryStatus.Restoring]: { display: 'Restoring', color: 'primary', showDots: true }, - [PrimaryStatus.Stopping]: { display: 'Stopping', color: 'dark-shade', showDots: true }, - [PrimaryStatus.Stopped]: { display: 'Stopped', color: 'dark-shade', showDots: false }, - [PrimaryStatus.BackingUp]: { display: 'Backing Up', color: 'primary', showDots: true }, - [PrimaryStatus.Starting]: { display: 'Starting', color: 'primary', showDots: true }, - [PrimaryStatus.Running]: { display: 'Running', color: 'success', showDots: false }, +export const PrimaryRendering: Record = { + [PrimaryStatus.Installing]: { + display: 'Installing', + color: 'primary', + showDots: true, + }, + [PrimaryStatus.Updating]: { + display: 'Updating', + color: 'primary', + showDots: true, + }, + [PrimaryStatus.Removing]: { + display: 'Removing', + color: 'danger', + showDots: true, + }, + [PrimaryStatus.Restoring]: { + display: 'Restoring', + color: 'primary', + showDots: true, + }, + [PrimaryStatus.Stopping]: { + display: 'Stopping', + color: 'dark-shade', + showDots: true, + }, + [PrimaryStatus.Stopped]: { + display: 'Stopped', + color: 'dark-shade', + showDots: false, + }, + [PrimaryStatus.BackingUp]: { + display: 'Backing Up', + color: 'primary', + showDots: true, + }, + [PrimaryStatus.Starting]: { + display: 'Starting', + color: 'primary', + showDots: true, + }, + [PrimaryStatus.Running]: { + display: 'Running', + color: 'success', + showDots: false, + }, [PrimaryStatus.NeedsConfig]: { display: 'Needs Config', color: 'warning' }, } -export const DependencyRendering: { [key: string]: StatusRendering } = { +export const DependencyRendering: Record = { [DependencyStatus.Warning]: { display: 'Issue', color: 'warning' }, [DependencyStatus.Satisfied]: { display: 'Satisfied', color: 'success' }, } -export const HealthRendering: { [key: string]: StatusRendering } = { +export const HealthRendering: Record = { [HealthStatus.Failure]: { display: 'Failure', color: 'danger' }, [HealthStatus.Starting]: { display: 'Starting', color: 'primary' }, [HealthStatus.Loading]: { display: 'Loading', color: 'primary' }, diff --git a/frontend/projects/ui/src/app/services/server-config.service.ts b/frontend/projects/ui/src/app/services/server-config.service.ts index ec850782e..386d4bbbf 100644 --- a/frontend/projects/ui/src/app/services/server-config.service.ts +++ b/frontend/projects/ui/src/app/services/server-config.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core' import { AlertInput, AlertButton } from '@ionic/core' import { ApiService } from './api/embassy-api.service' -import { ConfigSpec } from '../pkg-config/config-types' +import { ConfigSpec } from 'src/app/pkg-config/config-types' import { AlertController, LoadingController } from '@ionic/angular' import { ErrorToastService } from './error-toast.service' diff --git a/frontend/projects/ui/src/app/services/ui-launcher.service.ts b/frontend/projects/ui/src/app/services/ui-launcher.service.ts index 77a782476..267fb7b52 100644 --- a/frontend/projects/ui/src/app/services/ui-launcher.service.ts +++ b/frontend/projects/ui/src/app/services/ui-launcher.service.ts @@ -1,6 +1,6 @@ import { Inject, Injectable } from '@angular/core' import { DOCUMENT } from '@angular/common' -import { PackageDataEntry } from './patch-db/data-model' +import { PackageDataEntry } from 'src/app/services/patch-db/data-model' import { ConfigService } from './config.service' @Injectable({ diff --git a/frontend/projects/ui/src/app/types/mapped-backup-target.ts b/frontend/projects/ui/src/app/types/mapped-backup-target.ts new file mode 100644 index 000000000..13b51d4b5 --- /dev/null +++ b/frontend/projects/ui/src/app/types/mapped-backup-target.ts @@ -0,0 +1,5 @@ +export interface MappedBackupTarget { + id: string + hasValidBackup: boolean + entry: T +} diff --git a/frontend/projects/ui/src/app/util/get-package-info.ts b/frontend/projects/ui/src/app/util/get-package-info.ts index bc9bf9c0d..c130a5cba 100644 --- a/frontend/projects/ui/src/app/util/get-package-info.ts +++ b/frontend/projects/ui/src/app/util/get-package-info.ts @@ -6,11 +6,7 @@ import { renderPkgStatus, StatusRendering, } from '../services/pkg-status-rendering.service' -import { isEmptyObject } from './misc.util' -import { - packageLoadingProgress, - ProgressData, -} from './package-loading-progress' +import { packageLoadingProgress, ProgressData } from '@start9labs/shared' import { Subscription } from 'rxjs' export function getPackageInfo(entry: PackageDataEntry): PkgInfo { diff --git a/frontend/projects/ui/src/app/util/misc.util.ts b/frontend/projects/ui/src/app/util/misc.util.ts deleted file mode 100644 index 060c8599a..000000000 --- a/frontend/projects/ui/src/app/util/misc.util.ts +++ /dev/null @@ -1,197 +0,0 @@ -import { OperatorFunction } from 'rxjs' -import { map } from 'rxjs/operators' - -export type Omit = Pick> -export type PromiseRes = { result: 'resolve', value: T } | { result: 'reject', value: Error } - -export interface MappedBackupTarget { - id: string - hasValidBackup: boolean - entry: T -} - -export interface DependentInfo { - id: string - title: string - version?: string -} - -export function trace (t: T): T { - console.log(`TRACE`, t) - return t -} - -// curried description. This allows e.g somePromise.thentraceDesc('my result')) -export function traceDesc (description: string): (t: T) => T { - return t => { - console.log(`TRACE`, description, t) - return t - } -} - -// for use in observables. This allows e.g. someObservable.pipe(traceM('my result')) -// the practical equivalent of `tap(t => console.log(t, description))` -export function traceWheel (description?: string): OperatorFunction { - return description ? map(traceDesc(description)) : map(trace) -} - -export function traceThrowDesc (description: string, t: T | undefined): T { - if (!t) throw new Error(description) - return t -} - -export function thenReturn (act1 : () => Promise, t: T): Promise { - return act1().then(() => t) -} - -export function modulateTime (ts: Date, count: number, unit: 'days' | 'hours' | 'minutes' | 'seconds' ) { - const ms = inMs(count, unit) - const toReturn = new Date(ts) - toReturn.setMilliseconds( toReturn.getMilliseconds() + ms) - return toReturn -} - -export function inMs ( count: number, unit: 'days' | 'hours' | 'minutes' | 'seconds' ) { - switch (unit){ - case 'seconds' : return count * 1000 - case 'minutes' : return inMs(count * 60, 'seconds') - case 'hours' : return inMs(count * 60, 'minutes') - case 'days' : return inMs(count * 24, 'hours') - } -} - -export async function tryAll ( promises: [Promise, Promise]): Promise<[PromiseRes, PromiseRes]> -export async function tryAll ( promises: Promise[] ): Promise[]> { - return Promise.all(promises.map( - p => p - .then (r => ({ result: 'resolve' as 'resolve', value: r })) - .catch(e => ({ result: 'reject' as 'reject', value: e })), - )) -} - -// arr1 - arr2 -export function diff (arr1: T[], arr2: T[]): T[] { - return arr1.filter(x => !arr2.includes(x)) -} - -// arr1 & arr2 -export function both (arr1: T[], arr2: T[]): T[] { - return arr1.filter(x => arr2.includes(x)) -} - -export async function doForAtLeast (promises: Promise[], minTime: number): Promise { - const returned = await Promise.all(promises.concat(pauseFor(minTime))) - returned.pop() - return returned -} - -export function isObject (val: any): boolean { - return val && typeof val === 'object' && !Array.isArray(val) -} - -export function isEmptyObject (obj: object): boolean { - if (obj === undefined) return true - return !Object.keys(obj).length -} - -export function pauseFor (ms: number): Promise { - return new Promise(resolve => setTimeout(resolve, ms)) -} - -export type Valued = { [s: string]: T } - -export function toObject (t: T[], map: (t0: T) => string): Valued { - return t.reduce( (acc, next) => { - acc[map(next)] = next - return acc - }, { } as Valued) -} - -export function toDedupObject (t: T[], t2: T[], map: (t0: T) => string): Valued { - return toObject(t.concat(t2), map) -} - -export function update (t: Valued, u: Valued): Valued { - return { ...t, ...u} -} - -export function fromObject (o : Valued): T[] { - return Object.values(o) -} - -export function deepCloneUnknown (value: T): T { - if (typeof value !== 'object' || value === null) { - return value - } - if (Array.isArray(value)) { - return deepCloneArray(value) - } - return deepCloneObject(value) -} - -export function deepCloneObject (source: T) { - const result = { } - Object.keys(source).forEach(key => { - const value = source[key] - result[key] = deepCloneUnknown(value) - }, { }) - return result as T -} - -export function deepCloneArray (collection: any) { - return collection.map(value => { - return deepCloneUnknown(value) - }) -} - -export function partitionArray (ts: T[], condition: (t: T) => boolean): [T[], T[]] { - const yes = [] as T[] - const no = [] as T[] - ts.forEach(t => { - if (condition(t)) { - yes.push(t) - } else { - no.push(t) - } - }) - return [yes, no] -} - -export function uniqueBy (ts: T[], uniqueBy: (t: T) => string, prioritize: (t1: T, t2: T) => T) { - return Object.values(ts.reduce((acc, next) => { - const previousValue = acc[uniqueBy(next)] - if (previousValue) { - acc[uniqueBy(next)] = prioritize(acc[uniqueBy(next)], previousValue) - } else { - acc[uniqueBy(next)] = previousValue - } - return acc - }, { })) -} - -export function capitalizeFirstLetter (string: string): string { - return string.charAt(0).toUpperCase() + string.slice(1) -} - -export const exists = (t: any) => { - return t !== undefined -} - -export type DeepPartial = { - [k in keyof T]?: DeepPartial -} - -export function debounce (delay: number = 300): MethodDecorator { - return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { - const timeoutKey = Symbol() - - const original = descriptor.value - - descriptor.value = function (...args) { - clearTimeout(this[timeoutKey]) - this[timeoutKey] = setTimeout(() => original.apply(this, args), delay) - } - - return descriptor - } -} diff --git a/frontend/projects/ui/src/app/util/parse-data-model.ts b/frontend/projects/ui/src/app/util/parse-data-model.ts index fc8a4644e..e1d6aef24 100644 --- a/frontend/projects/ui/src/app/util/parse-data-model.ts +++ b/frontend/projects/ui/src/app/util/parse-data-model.ts @@ -2,11 +2,11 @@ import { DataModel, PackageDataEntry, RecoveredPackageDataEntry, -} from '../services/patch-db/data-model' +} from 'src/app/services/patch-db/data-model' -export function parseDataModel (data: DataModel): ParsedData { +export function parseDataModel(data: DataModel): ParsedData { const all = JSON.parse(JSON.stringify(data['package-data'])) as { - [id: string]: PackageDataEntry; + [id: string]: PackageDataEntry } const order = [...(data.ui['pkg-order'] || [])] @@ -19,7 +19,7 @@ export function parseDataModel (data: DataModel): ParsedData { })) // add known packages in preferential order - order.forEach((id) => { + order.forEach(id => { if (all[id]) { pkgs.push(all[id]) @@ -28,7 +28,7 @@ export function parseDataModel (data: DataModel): ParsedData { }) // unshift unknown packages - Object.values(all).forEach((pkg) => { + Object.values(all).forEach(pkg => { pkgs.unshift(pkg) }) diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index fe0248a4e..34ca180ae 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -21,8 +21,8 @@ "stream": ["./node_modules/stream-browserify"], "crypto": ["./node_modules/crypto-browserify"], "vm": ["./node_modules/vm-browserify"], - /* This path is relative to each app base folder */ - "@shared": ["../shared/src/public-api"] + /* These paths are relative to each app base folder */ + "@start9labs/shared": ["../shared/src/public-api"] }, "typeRoots": ["node_modules/@types"], "types": ["node"]