+{
+ "name": "frontend",
+ "version": "0.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "frontend",
+ "version": "0.0.0",
+ "dependencies": {
+ "@xterm/addon-fit": "^0.10.0",
+ "@xterm/addon-web-links": "^0.11.0",
+ "@xterm/xterm": "^5.5.0",
+ "js-yaml": "^4.1.0",
+ "vue": "^3.2.37"
+ },
+ "devDependencies": {
+ "@types/node": "^22.13.8",
+ "@vitejs/plugin-vue": "^3.2.0",
+ "@vue/cli-plugin-typescript": "^5.0.8",
+ "@vue/runtime-core": "^3.5.13",
+ "@vue/tsconfig": "^0.7.0",
+ "typescript": "^5.8.2",
+ "vite": "^3.0.7"
+ }
+ },
+ "node_modules/@achrinza/node-ipc": {
+ "version": "9.2.9",
+ "resolved": "https://registry.npmjs.org/@achrinza/node-ipc/-/node-ipc-9.2.9.tgz",
+ "integrity": "sha512-7s0VcTwiK/0tNOVdSX9FWMeFdOEcsAOz9HesBldXxFMaGvIak7KC2z9tV9EgsQXn6KUsWsfIkViMNuIo0GoZDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@node-ipc/js-queue": "2.0.3",
+ "event-pubsub": "4.3.0",
+ "js-message": "1.0.7"
+ },
+ "engines": {
+ "node": "8 || 9 || 10 || 11 || 12 || 13 || 14 || 15 || 16 || 17 || 18 || 19 || 20 || 21 || 22"
+ }
+ },
+ "node_modules/@ampproject/remapping": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+ "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.26.2",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
+ "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.25.9",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.26.8",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz",
+ "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.26.9",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.9.tgz",
+ "integrity": "sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@ampproject/remapping": "^2.2.0",
+ "@babel/code-frame": "^7.26.2",
+ "@babel/generator": "^7.26.9",
+ "@babel/helper-compilation-targets": "^7.26.5",
+ "@babel/helper-module-transforms": "^7.26.0",
+ "@babel/helpers": "^7.26.9",
+ "@babel/parser": "^7.26.9",
+ "@babel/template": "^7.26.9",
+ "@babel/traverse": "^7.26.9",
+ "@babel/types": "^7.26.9",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.26.9",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.9.tgz",
+ "integrity": "sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.26.9",
+ "@babel/types": "^7.26.9",
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "jsesc": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.26.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz",
+ "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.26.5",
+ "@babel/helper-validator-option": "^7.25.9",
+ "browserslist": "^4.24.0",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz",
+ "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz",
+ "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
+ "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
+ "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz",
+ "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.26.9",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.9.tgz",
+ "integrity": "sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.26.9",
+ "@babel/types": "^7.26.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.26.9",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz",
+ "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.26.9"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.26.9",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz",
+ "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.26.2",
+ "@babel/parser": "^7.26.9",
+ "@babel/types": "^7.26.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.26.9",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.9.tgz",
+ "integrity": "sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.26.2",
+ "@babel/generator": "^7.26.9",
+ "@babel/parser": "^7.26.9",
+ "@babel/template": "^7.26.9",
+ "@babel/types": "^7.26.9",
+ "debug": "^4.3.1",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.26.9",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz",
+ "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@discoveryjs/json-ext": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
+ "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.18.tgz",
+ "integrity": "sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz",
+ "integrity": "sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@hapi/hoek": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
+ "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@hapi/topo": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz",
+ "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@hapi/hoek": "^9.0.0"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.8",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
+ "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/set-array": "^1.2.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+ "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/source-map": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
+ "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.25",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@leichtgewicht/ip-codec": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz",
+ "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@node-ipc/js-queue": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@node-ipc/js-queue/-/js-queue-2.0.3.tgz",
+ "integrity": "sha512-fL1wpr8hhD5gT2dA1qifeVaoDFlQR5es8tFuKqjHX+kdOtdNHnxkVZbtIrR2rxnMFvehkjaZRNV2H/gPXlb0hw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "easy-stack": "1.0.1"
+ },
+ "engines": {
+ "node": ">=1.0.0"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@polka/url": {
+ "version": "1.0.0-next.28",
+ "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz",
+ "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@sideway/address": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz",
+ "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@hapi/hoek": "^9.0.0"
+ }
+ },
+ "node_modules/@sideway/formula": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz",
+ "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@sideway/pinpoint": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
+ "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@soda/friendly-errors-webpack-plugin": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.8.1.tgz",
+ "integrity": "sha512-h2ooWqP8XuFqTXT+NyAFbrArzfQA7R6HTezADrvD9Re8fxMLTPPniLdqVTdDaO0eIoLaAwKT+d6w+5GeTk7Vbg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "chalk": "^3.0.0",
+ "error-stack-parser": "^2.0.6",
+ "string-width": "^4.2.3",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ },
+ "peerDependencies": {
+ "webpack": "^4.0.0 || ^5.0.0"
+ }
+ },
+ "node_modules/@soda/get-current-script": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@soda/get-current-script/-/get-current-script-1.0.2.tgz",
+ "integrity": "sha512-T7VNNlYVM1SgQ+VsMYhnDkcGmWhQdL0bDyGm5TlQ3GBXnJscEClUUOKduWTmm2zCnvNLC1hc3JpuXjs/nFOc5w==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@trysound/sax": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
+ "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/@types/body-parser": {
+ "version": "1.19.5",
+ "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
+ "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/connect": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/bonjour": {
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz",
+ "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/connect": {
+ "version": "3.4.38",
+ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
+ "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/connect-history-api-fallback": {
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz",
+ "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/express-serve-static-core": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/eslint": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz",
+ "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "*",
+ "@types/json-schema": "*"
+ }
+ },
+ "node_modules/@types/eslint-scope": {
+ "version": "3.7.7",
+ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz",
+ "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/eslint": "*",
+ "@types/estree": "*"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
+ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/express": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
+ "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/body-parser": "*",
+ "@types/express-serve-static-core": "^4.17.33",
+ "@types/qs": "*",
+ "@types/serve-static": "*"
+ }
+ },
+ "node_modules/@types/express-serve-static-core": {
+ "version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.6.tgz",
+ "integrity": "sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/node": "*",
+ "@types/qs": "*",
+ "@types/range-parser": "*",
+ "@types/send": "*"
+ }
+ },
+ "node_modules/@types/express/node_modules/@types/express-serve-static-core": {
+ "version": "4.19.6",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz",
+ "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/node": "*",
+ "@types/qs": "*",
+ "@types/range-parser": "*",
+ "@types/send": "*"
+ }
+ },
+ "node_modules/@types/html-minifier-terser": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
+ "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@types/http-errors": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz",
+ "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@types/http-proxy": {
+ "version": "1.17.16",
+ "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.16.tgz",
+ "integrity": "sha512-sdWoUajOB1cd0A8cRRQ1cfyWNbmFKLAqBB89Y8x5iYyG/mkJHc0YUH8pdWBy2omi9qtCpiIgGjuwO0dQST2l5w==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/mime": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
+ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@types/minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@types/node": {
+ "version": "22.13.8",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.8.tgz",
+ "integrity": "sha512-G3EfaZS+iOGYWLLRCEAXdWK9my08oHNZ+FHluRiggIYJPOXzhOiDgpVCUHaUvyIC5/fj7C/p637jdzC666AOKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.20.0"
+ }
+ },
+ "node_modules/@types/node-forge": {
+ "version": "1.3.11",
+ "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz",
+ "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/normalize-package-data": {
+ "version": "2.4.4",
+ "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz",
+ "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/parse-json": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz",
+ "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/qs": {
+ "version": "6.9.18",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.18.tgz",
+ "integrity": "sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@types/range-parser": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
+ "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@types/retry": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
+ "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@types/send": {
+ "version": "0.17.4",
+ "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz",
+ "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/mime": "^1",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/serve-index": {
+ "version": "1.9.4",
+ "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz",
+ "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/express": "*"
+ }
+ },
+ "node_modules/@types/serve-static": {
+ "version": "1.15.7",
+ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz",
+ "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/http-errors": "*",
+ "@types/node": "*",
+ "@types/send": "*"
+ }
+ },
+ "node_modules/@types/sockjs": {
+ "version": "0.3.36",
+ "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz",
+ "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/webpack-env": {
+ "version": "1.18.8",
+ "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.18.8.tgz",
+ "integrity": "sha512-G9eAoJRMLjcvN4I08wB5I7YofOb/kaJNd5uoCMX+LbKXTPCF+ZIHuqTnFaK9Jz1rgs035f9JUPUhNFtqgucy/A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/ws": {
+ "version": "8.5.14",
+ "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.14.tgz",
+ "integrity": "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@vitejs/plugin-vue": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-3.2.0.tgz",
+ "integrity": "sha512-E0tnaL4fr+qkdCNxJ+Xd0yM31UwMkQje76fsDVBBUCoGOUPexu2VDUYHL8P4CwV+zMvWw6nlRw19OnRKmYAJpw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^3.0.0",
+ "vue": "^3.2.25"
+ }
+ },
+ "node_modules/@vue/cli-overlay": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/@vue/cli-overlay/-/cli-overlay-5.0.8.tgz",
+ "integrity": "sha512-KmtievE/B4kcXp6SuM2gzsnSd8WebkQpg3XaB6GmFh1BJGRqa1UiW9up7L/Q67uOdTigHxr5Ar2lZms4RcDjwQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@vue/cli-plugin-router": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/@vue/cli-plugin-router/-/cli-plugin-router-5.0.8.tgz",
+ "integrity": "sha512-Gmv4dsGdAsWPqVijz3Ux2OS2HkMrWi1ENj2cYL75nUeL+Xj5HEstSqdtfZ0b1q9NCce+BFB6QnHfTBXc/fCvMg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@vue/cli-shared-utils": "^5.0.8"
+ },
+ "peerDependencies": {
+ "@vue/cli-service": "^3.0.0 || ^4.0.0 || ^5.0.0-0"
+ }
+ },
+ "node_modules/@vue/cli-plugin-typescript": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/@vue/cli-plugin-typescript/-/cli-plugin-typescript-5.0.8.tgz",
+ "integrity": "sha512-JKJOwzJshBqsmp4yLBexwVMebOZ4VGJgbnYvmHVxasJOStF2RxwyW28ZF+zIvASGdat4sAUuo/3mAQyVhm7JHg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.12.16",
+ "@types/webpack-env": "^1.15.2",
+ "@vue/cli-shared-utils": "^5.0.8",
+ "babel-loader": "^8.2.2",
+ "fork-ts-checker-webpack-plugin": "^6.4.0",
+ "globby": "^11.0.2",
+ "thread-loader": "^3.0.0",
+ "ts-loader": "^9.2.5",
+ "webpack": "^5.54.0"
+ },
+ "peerDependencies": {
+ "@vue/cli-service": "^3.0.0 || ^4.0.0 || ^5.0.0-0",
+ "cache-loader": "^4.1.0",
+ "typescript": ">=2",
+ "vue": "^2 || ^3.2.13",
+ "vue-template-compiler": "^2.0.0"
+ },
+ "peerDependenciesMeta": {
+ "cache-loader": {
+ "optional": true
+ },
+ "vue-template-compiler": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vue/cli-plugin-vuex": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/@vue/cli-plugin-vuex/-/cli-plugin-vuex-5.0.8.tgz",
+ "integrity": "sha512-HSYWPqrunRE5ZZs8kVwiY6oWcn95qf/OQabwLfprhdpFWAGtLStShjsGED2aDpSSeGAskQETrtR/5h7VqgIlBA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "peerDependencies": {
+ "@vue/cli-service": "^3.0.0 || ^4.0.0 || ^5.0.0-0"
+ }
+ },
+ "node_modules/@vue/cli-service": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/@vue/cli-service/-/cli-service-5.0.8.tgz",
+ "integrity": "sha512-nV7tYQLe7YsTtzFrfOMIHc5N2hp5lHG2rpYr0aNja9rNljdgcPZLyQRb2YRivTHqTv7lI962UXFURcpStHgyFw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/helper-compilation-targets": "^7.12.16",
+ "@soda/friendly-errors-webpack-plugin": "^1.8.0",
+ "@soda/get-current-script": "^1.0.2",
+ "@types/minimist": "^1.2.0",
+ "@vue/cli-overlay": "^5.0.8",
+ "@vue/cli-plugin-router": "^5.0.8",
+ "@vue/cli-plugin-vuex": "^5.0.8",
+ "@vue/cli-shared-utils": "^5.0.8",
+ "@vue/component-compiler-utils": "^3.3.0",
+ "@vue/vue-loader-v15": "npm:vue-loader@^15.9.7",
+ "@vue/web-component-wrapper": "^1.3.0",
+ "acorn": "^8.0.5",
+ "acorn-walk": "^8.0.2",
+ "address": "^1.1.2",
+ "autoprefixer": "^10.2.4",
+ "browserslist": "^4.16.3",
+ "case-sensitive-paths-webpack-plugin": "^2.3.0",
+ "cli-highlight": "^2.1.10",
+ "clipboardy": "^2.3.0",
+ "cliui": "^7.0.4",
+ "copy-webpack-plugin": "^9.0.1",
+ "css-loader": "^6.5.0",
+ "css-minimizer-webpack-plugin": "^3.0.2",
+ "cssnano": "^5.0.0",
+ "debug": "^4.1.1",
+ "default-gateway": "^6.0.3",
+ "dotenv": "^10.0.0",
+ "dotenv-expand": "^5.1.0",
+ "fs-extra": "^9.1.0",
+ "globby": "^11.0.2",
+ "hash-sum": "^2.0.0",
+ "html-webpack-plugin": "^5.1.0",
+ "is-file-esm": "^1.0.0",
+ "launch-editor-middleware": "^2.2.1",
+ "lodash.defaultsdeep": "^4.6.1",
+ "lodash.mapvalues": "^4.6.0",
+ "mini-css-extract-plugin": "^2.5.3",
+ "minimist": "^1.2.5",
+ "module-alias": "^2.2.2",
+ "portfinder": "^1.0.26",
+ "postcss": "^8.2.6",
+ "postcss-loader": "^6.1.1",
+ "progress-webpack-plugin": "^1.0.12",
+ "ssri": "^8.0.1",
+ "terser-webpack-plugin": "^5.1.1",
+ "thread-loader": "^3.0.0",
+ "vue-loader": "^17.0.0",
+ "vue-style-loader": "^4.1.3",
+ "webpack": "^5.54.0",
+ "webpack-bundle-analyzer": "^4.4.0",
+ "webpack-chain": "^6.5.1",
+ "webpack-dev-server": "^4.7.3",
+ "webpack-merge": "^5.7.3",
+ "webpack-virtual-modules": "^0.4.2",
+ "whatwg-fetch": "^3.6.2"
+ },
+ "bin": {
+ "vue-cli-service": "bin/vue-cli-service.js"
+ },
+ "engines": {
+ "node": "^12.0.0 || >= 14.0.0"
+ },
+ "peerDependencies": {
+ "vue-template-compiler": "^2.0.0",
+ "webpack-sources": "*"
+ },
+ "peerDependenciesMeta": {
+ "cache-loader": {
+ "optional": true
+ },
+ "less-loader": {
+ "optional": true
+ },
+ "pug-plain-loader": {
+ "optional": true
+ },
+ "raw-loader": {
+ "optional": true
+ },
+ "sass-loader": {
+ "optional": true
+ },
+ "stylus-loader": {
+ "optional": true
+ },
+ "vue-template-compiler": {
+ "optional": true
+ },
+ "webpack-sources": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vue/cli-shared-utils": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/@vue/cli-shared-utils/-/cli-shared-utils-5.0.8.tgz",
+ "integrity": "sha512-uK2YB7bBVuQhjOJF+O52P9yFMXeJVj7ozqJkwYE9PlMHL1LMHjtCYm4cSdOebuPzyP+/9p0BimM/OqxsevIopQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@achrinza/node-ipc": "^9.2.5",
+ "chalk": "^4.1.2",
+ "execa": "^1.0.0",
+ "joi": "^17.4.0",
+ "launch-editor": "^2.2.1",
+ "lru-cache": "^6.0.0",
+ "node-fetch": "^2.6.7",
+ "open": "^8.0.2",
+ "ora": "^5.3.0",
+ "read-pkg": "^5.1.1",
+ "semver": "^7.3.4",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "node_modules/@vue/cli-shared-utils/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@vue/cli-shared-utils/node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@vue/cli-shared-utils/node_modules/semver": {
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
+ "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@vue/cli-shared-utils/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/@vue/compiler-core": {
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.13.tgz",
+ "integrity": "sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.25.3",
+ "@vue/shared": "3.5.13",
+ "entities": "^4.5.0",
+ "estree-walker": "^2.0.2",
+ "source-map-js": "^1.2.0"
+ }
+ },
+ "node_modules/@vue/compiler-core/node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/@vue/compiler-dom": {
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz",
+ "integrity": "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-core": "3.5.13",
+ "@vue/shared": "3.5.13"
+ }
+ },
+ "node_modules/@vue/compiler-sfc": {
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.13.tgz",
+ "integrity": "sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.25.3",
+ "@vue/compiler-core": "3.5.13",
+ "@vue/compiler-dom": "3.5.13",
+ "@vue/compiler-ssr": "3.5.13",
+ "@vue/shared": "3.5.13",
+ "estree-walker": "^2.0.2",
+ "magic-string": "^0.30.11",
+ "postcss": "^8.4.48",
+ "source-map-js": "^1.2.0"
+ }
+ },
+ "node_modules/@vue/compiler-ssr": {
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.13.tgz",
+ "integrity": "sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.13",
+ "@vue/shared": "3.5.13"
+ }
+ },
+ "node_modules/@vue/component-compiler-utils": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.3.0.tgz",
+ "integrity": "sha512-97sfH2mYNU+2PzGrmK2haqffDpVASuib9/w2/noxiFi31Z54hW+q3izKQXXQZSNhtiUpAI36uSuYepeBe4wpHQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "consolidate": "^0.15.1",
+ "hash-sum": "^1.0.2",
+ "lru-cache": "^4.1.2",
+ "merge-source-map": "^1.1.0",
+ "postcss": "^7.0.36",
+ "postcss-selector-parser": "^6.0.2",
+ "source-map": "~0.6.1",
+ "vue-template-es2015-compiler": "^1.9.0"
+ },
+ "optionalDependencies": {
+ "prettier": "^1.18.2 || ^2.0.0"
+ }
+ },
+ "node_modules/@vue/component-compiler-utils/node_modules/hash-sum": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz",
+ "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@vue/component-compiler-utils/node_modules/lru-cache": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+ "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "dependencies": {
+ "pseudomap": "^1.0.2",
+ "yallist": "^2.1.2"
+ }
+ },
+ "node_modules/@vue/component-compiler-utils/node_modules/picocolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+ "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true
+ },
+ "node_modules/@vue/component-compiler-utils/node_modules/postcss": {
+ "version": "7.0.39",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+ "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "picocolors": "^0.2.1",
+ "source-map": "^0.6.1"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ }
+ },
+ "node_modules/@vue/component-compiler-utils/node_modules/yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true
+ },
+ "node_modules/@vue/reactivity": {
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.13.tgz",
+ "integrity": "sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/shared": "3.5.13"
+ }
+ },
+ "node_modules/@vue/runtime-core": {
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.13.tgz",
+ "integrity": "sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/reactivity": "3.5.13",
+ "@vue/shared": "3.5.13"
+ }
+ },
+ "node_modules/@vue/runtime-dom": {
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.13.tgz",
+ "integrity": "sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/reactivity": "3.5.13",
+ "@vue/runtime-core": "3.5.13",
+ "@vue/shared": "3.5.13",
+ "csstype": "^3.1.3"
+ }
+ },
+ "node_modules/@vue/server-renderer": {
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.13.tgz",
+ "integrity": "sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-ssr": "3.5.13",
+ "@vue/shared": "3.5.13"
+ },
+ "peerDependencies": {
+ "vue": "3.5.13"
+ }
+ },
+ "node_modules/@vue/shared": {
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.13.tgz",
+ "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==",
+ "license": "MIT"
+ },
+ "node_modules/@vue/tsconfig": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/@vue/tsconfig/-/tsconfig-0.7.0.tgz",
+ "integrity": "sha512-ku2uNz5MaZ9IerPPUyOHzyjhXoX2kVJaVf7hL315DC17vS6IiZRmmCPfggNbU16QTvM80+uYYy3eYJB59WCtvg==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "typescript": "5.x",
+ "vue": "^3.4.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ },
+ "vue": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vue/vue-loader-v15": {
+ "name": "vue-loader",
+ "version": "15.11.1",
+ "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.11.1.tgz",
+ "integrity": "sha512-0iw4VchYLePqJfJu9s62ACWUXeSqM30SQqlIftbYWM3C+jpPcEHKSPUZBLjSF9au4HTHQ/naF6OGnO3Q/qGR3Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@vue/component-compiler-utils": "^3.1.0",
+ "hash-sum": "^1.0.2",
+ "loader-utils": "^1.1.0",
+ "vue-hot-reload-api": "^2.3.0",
+ "vue-style-loader": "^4.1.0"
+ },
+ "peerDependencies": {
+ "css-loader": "*",
+ "webpack": "^3.0.0 || ^4.1.0 || ^5.0.0-0"
+ },
+ "peerDependenciesMeta": {
+ "cache-loader": {
+ "optional": true
+ },
+ "prettier": {
+ "optional": true
+ },
+ "vue-template-compiler": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vue/vue-loader-v15/node_modules/hash-sum": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz",
+ "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@vue/web-component-wrapper": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@vue/web-component-wrapper/-/web-component-wrapper-1.3.0.tgz",
+ "integrity": "sha512-Iu8Tbg3f+emIIMmI2ycSI8QcEuAUgPTgHwesDU1eKMLE4YC/c/sFbGc70QgMq31ijRftV0R7vCm9co6rldCeOA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@webassemblyjs/ast": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz",
+ "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/helper-numbers": "1.13.2",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2"
+ }
+ },
+ "node_modules/@webassemblyjs/floating-point-hex-parser": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz",
+ "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@webassemblyjs/helper-api-error": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz",
+ "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@webassemblyjs/helper-buffer": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz",
+ "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@webassemblyjs/helper-numbers": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz",
+ "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/floating-point-hex-parser": "1.13.2",
+ "@webassemblyjs/helper-api-error": "1.13.2",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webassemblyjs/helper-wasm-bytecode": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz",
+ "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@webassemblyjs/helper-wasm-section": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz",
+ "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/wasm-gen": "1.14.1"
+ }
+ },
+ "node_modules/@webassemblyjs/ieee754": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz",
+ "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@xtuc/ieee754": "^1.2.0"
+ }
+ },
+ "node_modules/@webassemblyjs/leb128": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz",
+ "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@webassemblyjs/utf8": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz",
+ "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@webassemblyjs/wasm-edit": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz",
+ "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/helper-wasm-section": "1.14.1",
+ "@webassemblyjs/wasm-gen": "1.14.1",
+ "@webassemblyjs/wasm-opt": "1.14.1",
+ "@webassemblyjs/wasm-parser": "1.14.1",
+ "@webassemblyjs/wast-printer": "1.14.1"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-gen": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz",
+ "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/ieee754": "1.13.2",
+ "@webassemblyjs/leb128": "1.13.2",
+ "@webassemblyjs/utf8": "1.13.2"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-opt": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz",
+ "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/wasm-gen": "1.14.1",
+ "@webassemblyjs/wasm-parser": "1.14.1"
+ }
+ },
+ "node_modules/@webassemblyjs/wasm-parser": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz",
+ "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-api-error": "1.13.2",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/ieee754": "1.13.2",
+ "@webassemblyjs/leb128": "1.13.2",
+ "@webassemblyjs/utf8": "1.13.2"
+ }
+ },
+ "node_modules/@webassemblyjs/wast-printer": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz",
+ "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@webassemblyjs/ast": "1.14.1",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "node_modules/@xterm/addon-fit": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/@xterm/addon-fit/-/addon-fit-0.10.0.tgz",
+ "integrity": "sha512-UFYkDm4HUahf2lnEyHvio51TNGiLK66mqP2JoATy7hRZeXaGMRDr00JiSF7m63vR5WKATF605yEggJKsw0JpMQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@xterm/xterm": "^5.0.0"
+ }
+ },
+ "node_modules/@xterm/addon-web-links": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@xterm/addon-web-links/-/addon-web-links-0.11.0.tgz",
+ "integrity": "sha512-nIHQ38pQI+a5kXnRaTgwqSHnX7KE6+4SVoceompgHL26unAxdfP6IPqUTSYPQgSwM56hsElfoNrrW5V7BUED/Q==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@xterm/xterm": "^5.0.0"
+ }
+ },
+ "node_modules/@xterm/xterm": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.5.0.tgz",
+ "integrity": "sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A==",
+ "license": "MIT"
+ },
+ "node_modules/@xtuc/ieee754": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+ "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@xtuc/long": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
+ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/accepts": {
+ "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,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/accepts/node_modules/negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.14.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
+ "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-walk": {
+ "version": "8.3.4",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
+ "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "acorn": "^8.11.0"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/address": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz",
+ "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "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,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "ajv": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ajv-formats/node_modules/ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.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,
+ "license": "MIT"
+ },
+ "node_modules/ajv-keywords": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "ajv": "^6.9.1"
+ }
+ },
+ "node_modules/ansi-escapes": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
+ "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ansi-html-community": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz",
+ "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==",
+ "dev": true,
+ "engines": [
+ "node >= 0.8.0"
+ ],
+ "license": "Apache-2.0",
+ "peer": true,
+ "bin": {
+ "ansi-html": "bin/ansi-html"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/any-promise": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/arch": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz",
+ "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "license": "Python-2.0"
+ },
+ "node_modules/array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/async": {
+ "version": "2.6.4",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
+ "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "lodash": "^4.17.14"
+ }
+ },
+ "node_modules/at-least-node": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
+ "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
+ "node_modules/autoprefixer": {
+ "version": "10.4.20",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz",
+ "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/autoprefixer"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "browserslist": "^4.23.3",
+ "caniuse-lite": "^1.0.30001646",
+ "fraction.js": "^4.3.7",
+ "normalize-range": "^0.1.2",
+ "picocolors": "^1.0.1",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "bin": {
+ "autoprefixer": "bin/autoprefixer"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/babel-loader": {
+ "version": "8.4.1",
+ "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.4.1.tgz",
+ "integrity": "sha512-nXzRChX+Z1GoE6yWavBQg6jDslyFF3SDjl2paADuoQtQW10JqShJt62R6eJQ5m/pjJFDT8xgKIWSP85OY8eXeA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "find-cache-dir": "^3.3.1",
+ "loader-utils": "^2.0.4",
+ "make-dir": "^3.1.0",
+ "schema-utils": "^2.6.5"
+ },
+ "engines": {
+ "node": ">= 8.9"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0",
+ "webpack": ">=2"
+ }
+ },
+ "node_modules/babel-loader/node_modules/loader-utils": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
+ "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^2.1.2"
+ },
+ "engines": {
+ "node": ">=8.9.0"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/batch": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
+ "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/big.js": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/bl": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
+ "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer": "^5.5.0",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ }
+ },
+ "node_modules/bluebird": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/body-parser": {
+ "version": "1.20.3",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
+ "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "bytes": "3.1.2",
+ "content-type": "~1.0.5",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "on-finished": "2.4.1",
+ "qs": "6.13.0",
+ "raw-body": "2.5.2",
+ "type-is": "~1.6.18",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/body-parser/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/body-parser/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/bonjour-service": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz",
+ "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "multicast-dns": "^7.2.5"
+ }
+ },
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.24.4",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz",
+ "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001688",
+ "electron-to-chromium": "^1.5.73",
+ "node-releases": "^2.0.19",
+ "update-browserslist-db": "^1.1.1"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz",
+ "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/camel-case": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz",
+ "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "pascal-case": "^3.1.2",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/caniuse-api": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
+ "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "browserslist": "^4.0.0",
+ "caniuse-lite": "^1.0.0",
+ "lodash.memoize": "^4.1.2",
+ "lodash.uniq": "^4.5.0"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001701",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001701.tgz",
+ "integrity": "sha512-faRs/AW3jA9nTwmJBSO1PQ6L/EOgsB5HMQQq4iCu5zhPgVVgO/pZRHlmatwijZKetFw8/Pr4q6dEN8sJuq8qTw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/case-sensitive-paths-webpack-plugin": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz",
+ "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/chokidar/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/chrome-trace-event": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz",
+ "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0"
+ }
+ },
+ "node_modules/clean-css": {
+ "version": "5.3.3",
+ "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz",
+ "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "source-map": "~0.6.0"
+ },
+ "engines": {
+ "node": ">= 10.0"
+ }
+ },
+ "node_modules/cli-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
+ "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "restore-cursor": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cli-highlight": {
+ "version": "2.1.11",
+ "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz",
+ "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "highlight.js": "^10.7.1",
+ "mz": "^2.4.0",
+ "parse5": "^5.1.1",
+ "parse5-htmlparser2-tree-adapter": "^6.0.0",
+ "yargs": "^16.0.0"
+ },
+ "bin": {
+ "highlight": "bin/highlight"
+ },
+ "engines": {
+ "node": ">=8.0.0",
+ "npm": ">=5.0.0"
+ }
+ },
+ "node_modules/cli-highlight/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/cli-spinners": {
+ "version": "2.9.2",
+ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz",
+ "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/clipboardy": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-2.3.0.tgz",
+ "integrity": "sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "arch": "^2.1.1",
+ "execa": "^1.0.0",
+ "is-wsl": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "node_modules/clone": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+ "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/clone-deep": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
+ "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "is-plain-object": "^2.0.4",
+ "kind-of": "^6.0.2",
+ "shallow-clone": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/colord": {
+ "version": "2.9.3",
+ "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz",
+ "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/colorette": {
+ "version": "2.0.20",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
+ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/commander": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
+ "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/commondir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+ "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/compressible": {
+ "version": "2.0.18",
+ "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
+ "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "mime-db": ">= 1.43.0 < 2"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/compression": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.0.tgz",
+ "integrity": "sha512-k6WLKfunuqCYD3t6AsuPGvQWaKwuLLh2/xHNcX4qE+vIfDNXpSqnrhwA7O53R7WVQUnt8dVAIW+YHr7xTgOgGA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "bytes": "3.1.2",
+ "compressible": "~2.0.18",
+ "debug": "2.6.9",
+ "negotiator": "~0.6.4",
+ "on-headers": "~1.0.2",
+ "safe-buffer": "5.2.1",
+ "vary": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/compression/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/compression/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/connect-history-api-fallback": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz",
+ "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/consolidate": {
+ "version": "0.15.1",
+ "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.15.1.tgz",
+ "integrity": "sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==",
+ "deprecated": "Please upgrade to consolidate v1.0.0+ as it has been modernized with several long-awaited fixes implemented. Maintenance is supported by Forward Email at https://forwardemail.net ; follow/watch https://github.com/ladjs/consolidate for updates and release changelog",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "bluebird": "^3.1.1"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
+ "node_modules/content-disposition": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+ "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "safe-buffer": "5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/content-type": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cookie": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
+ "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/copy-webpack-plugin": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-9.1.0.tgz",
+ "integrity": "sha512-rxnR7PaGigJzhqETHGmAcxKnLZSR5u1Y3/bcIv/1FnqXedcL/E2ewK7ZCNrArJKCiSv8yVXhTqetJh8inDvfsA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "fast-glob": "^3.2.7",
+ "glob-parent": "^6.0.1",
+ "globby": "^11.0.3",
+ "normalize-path": "^3.0.0",
+ "schema-utils": "^3.1.1",
+ "serialize-javascript": "^6.0.0"
+ },
+ "engines": {
+ "node": ">= 12.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.1.0"
+ }
+ },
+ "node_modules/copy-webpack-plugin/node_modules/schema-utils": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
+ "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@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/core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/cosmiconfig": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz",
+ "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/parse-json": "^4.0.0",
+ "import-fresh": "^3.1.0",
+ "parse-json": "^5.0.0",
+ "path-type": "^4.0.0",
+ "yaml": "^1.7.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "6.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz",
+ "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ },
+ "engines": {
+ "node": ">=4.8"
+ }
+ },
+ "node_modules/cross-spawn/node_modules/semver": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/css-declaration-sorter": {
+ "version": "6.4.1",
+ "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz",
+ "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.0.9"
+ }
+ },
+ "node_modules/css-loader": {
+ "version": "6.11.0",
+ "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz",
+ "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "icss-utils": "^5.1.0",
+ "postcss": "^8.4.33",
+ "postcss-modules-extract-imports": "^3.1.0",
+ "postcss-modules-local-by-default": "^4.0.5",
+ "postcss-modules-scope": "^3.2.0",
+ "postcss-modules-values": "^4.0.0",
+ "postcss-value-parser": "^4.2.0",
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": ">= 12.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "@rspack/core": "0.x || 1.x",
+ "webpack": "^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@rspack/core": {
+ "optional": true
+ },
+ "webpack": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/css-loader/node_modules/semver": {
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
+ "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/css-minimizer-webpack-plugin": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz",
+ "integrity": "sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "cssnano": "^5.0.6",
+ "jest-worker": "^27.0.2",
+ "postcss": "^8.3.5",
+ "schema-utils": "^4.0.0",
+ "serialize-javascript": "^6.0.0",
+ "source-map": "^0.6.1"
+ },
+ "engines": {
+ "node": ">= 12.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@parcel/css": {
+ "optional": true
+ },
+ "clean-css": {
+ "optional": true
+ },
+ "csso": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/css-minimizer-webpack-plugin/node_modules/ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/css-minimizer-webpack-plugin/node_modules/ajv-keywords": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3"
+ },
+ "peerDependencies": {
+ "ajv": "^8.8.2"
+ }
+ },
+ "node_modules/css-minimizer-webpack-plugin/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,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/css-minimizer-webpack-plugin/node_modules/schema-utils": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz",
+ "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/json-schema": "^7.0.9",
+ "ajv": "^8.9.0",
+ "ajv-formats": "^2.1.1",
+ "ajv-keywords": "^5.1.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/css-select": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz",
+ "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "peer": true,
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-what": "^6.0.1",
+ "domhandler": "^4.3.1",
+ "domutils": "^2.8.0",
+ "nth-check": "^2.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/css-tree": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
+ "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "mdn-data": "2.0.14",
+ "source-map": "^0.6.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/css-what": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
+ "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "peer": true,
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/cssnano": {
+ "version": "5.1.15",
+ "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz",
+ "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "cssnano-preset-default": "^5.2.14",
+ "lilconfig": "^2.0.3",
+ "yaml": "^1.10.2"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/cssnano"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/cssnano-preset-default": {
+ "version": "5.2.14",
+ "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz",
+ "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "css-declaration-sorter": "^6.3.1",
+ "cssnano-utils": "^3.1.0",
+ "postcss-calc": "^8.2.3",
+ "postcss-colormin": "^5.3.1",
+ "postcss-convert-values": "^5.1.3",
+ "postcss-discard-comments": "^5.1.2",
+ "postcss-discard-duplicates": "^5.1.0",
+ "postcss-discard-empty": "^5.1.1",
+ "postcss-discard-overridden": "^5.1.0",
+ "postcss-merge-longhand": "^5.1.7",
+ "postcss-merge-rules": "^5.1.4",
+ "postcss-minify-font-values": "^5.1.0",
+ "postcss-minify-gradients": "^5.1.1",
+ "postcss-minify-params": "^5.1.4",
+ "postcss-minify-selectors": "^5.2.1",
+ "postcss-normalize-charset": "^5.1.0",
+ "postcss-normalize-display-values": "^5.1.0",
+ "postcss-normalize-positions": "^5.1.1",
+ "postcss-normalize-repeat-style": "^5.1.1",
+ "postcss-normalize-string": "^5.1.0",
+ "postcss-normalize-timing-functions": "^5.1.0",
+ "postcss-normalize-unicode": "^5.1.1",
+ "postcss-normalize-url": "^5.1.0",
+ "postcss-normalize-whitespace": "^5.1.1",
+ "postcss-ordered-values": "^5.1.3",
+ "postcss-reduce-initial": "^5.1.2",
+ "postcss-reduce-transforms": "^5.1.0",
+ "postcss-svgo": "^5.1.0",
+ "postcss-unique-selectors": "^5.1.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/cssnano-utils": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz",
+ "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/csso": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz",
+ "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "css-tree": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
+ "license": "MIT"
+ },
+ "node_modules/debounce": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
+ "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/debug": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deepmerge": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/default-gateway": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz",
+ "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "peer": true,
+ "dependencies": {
+ "execa": "^5.0.0"
+ },
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/default-gateway/node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/default-gateway/node_modules/execa": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+ "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^6.0.0",
+ "human-signals": "^2.1.0",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.1",
+ "onetime": "^5.1.2",
+ "signal-exit": "^3.0.3",
+ "strip-final-newline": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/default-gateway/node_modules/get-stream": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
+ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/default-gateway/node_modules/is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/default-gateway/node_modules/npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "path-key": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/default-gateway/node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/default-gateway/node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/default-gateway/node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/default-gateway/node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/defaults": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
+ "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "clone": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/define-lazy-prop": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
+ "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/destroy": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/detect-node": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
+ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/dns-packet": {
+ "version": "5.6.1",
+ "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz",
+ "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@leichtgewicht/ip-codec": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/dom-converter": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz",
+ "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "utila": "~0.4"
+ }
+ },
+ "node_modules/dom-serializer": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
+ "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "domelementtype": "^2.0.1",
+ "domhandler": "^4.2.0",
+ "entities": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "BSD-2-Clause",
+ "peer": true
+ },
+ "node_modules/domhandler": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz",
+ "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "peer": true,
+ "dependencies": {
+ "domelementtype": "^2.2.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/domutils": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
+ "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "peer": true,
+ "dependencies": {
+ "dom-serializer": "^1.0.1",
+ "domelementtype": "^2.2.0",
+ "domhandler": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/dot-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
+ "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "no-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/dotenv": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz",
+ "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/dotenv-expand": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz",
+ "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "peer": true
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/duplexer": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
+ "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/easy-stack": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/easy-stack/-/easy-stack-1.0.1.tgz",
+ "integrity": "sha512-wK2sCs4feiiJeFXn3zvY0p41mdU5VUgbgs1rNsc/y5ngFUijdWd+iIN8eoyuZHKB8xN6BL4PdWmzqFmxNg6V2w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.109",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.109.tgz",
+ "integrity": "sha512-AidaH9JETVRr9DIPGfp1kAarm/W6hRJTPuCnkF+2MqhF4KaAgRIcBc8nvjk+YMXZhwfISof/7WG29eS4iGxQLQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/emojis-list": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
+ "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/encodeurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
+ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "once": "^1.4.0"
+ }
+ },
+ "node_modules/enhanced-resolve": {
+ "version": "5.18.1",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz",
+ "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/enhanced-resolve/node_modules/tapable": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
+ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/entities": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
+ "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "peer": true,
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "node_modules/error-stack-parser": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz",
+ "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "stackframe": "^1.3.4"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-module-lexer": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz",
+ "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.18.tgz",
+ "integrity": "sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/android-arm": "0.15.18",
+ "@esbuild/linux-loong64": "0.15.18",
+ "esbuild-android-64": "0.15.18",
+ "esbuild-android-arm64": "0.15.18",
+ "esbuild-darwin-64": "0.15.18",
+ "esbuild-darwin-arm64": "0.15.18",
+ "esbuild-freebsd-64": "0.15.18",
+ "esbuild-freebsd-arm64": "0.15.18",
+ "esbuild-linux-32": "0.15.18",
+ "esbuild-linux-64": "0.15.18",
+ "esbuild-linux-arm": "0.15.18",
+ "esbuild-linux-arm64": "0.15.18",
+ "esbuild-linux-mips64le": "0.15.18",
+ "esbuild-linux-ppc64le": "0.15.18",
+ "esbuild-linux-riscv64": "0.15.18",
+ "esbuild-linux-s390x": "0.15.18",
+ "esbuild-netbsd-64": "0.15.18",
+ "esbuild-openbsd-64": "0.15.18",
+ "esbuild-sunos-64": "0.15.18",
+ "esbuild-windows-32": "0.15.18",
+ "esbuild-windows-64": "0.15.18",
+ "esbuild-windows-arm64": "0.15.18"
+ }
+ },
+ "node_modules/esbuild-android-64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.18.tgz",
+ "integrity": "sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-android-arm64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.18.tgz",
+ "integrity": "sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-darwin-64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.18.tgz",
+ "integrity": "sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-darwin-arm64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.18.tgz",
+ "integrity": "sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-freebsd-64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.18.tgz",
+ "integrity": "sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-freebsd-arm64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.18.tgz",
+ "integrity": "sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-linux-32": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.18.tgz",
+ "integrity": "sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-linux-64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.18.tgz",
+ "integrity": "sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-linux-arm": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.18.tgz",
+ "integrity": "sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-linux-arm64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.18.tgz",
+ "integrity": "sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-linux-mips64le": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.18.tgz",
+ "integrity": "sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-linux-ppc64le": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.18.tgz",
+ "integrity": "sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-linux-riscv64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.18.tgz",
+ "integrity": "sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-linux-s390x": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.18.tgz",
+ "integrity": "sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-netbsd-64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.18.tgz",
+ "integrity": "sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-openbsd-64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.18.tgz",
+ "integrity": "sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-sunos-64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.18.tgz",
+ "integrity": "sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-windows-32": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.18.tgz",
+ "integrity": "sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-windows-64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.18.tgz",
+ "integrity": "sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-windows-arm64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.18.tgz",
+ "integrity": "sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esrecurse/node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+ "license": "MIT"
+ },
+ "node_modules/etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/event-pubsub": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/event-pubsub/-/event-pubsub-4.3.0.tgz",
+ "integrity": "sha512-z7IyloorXvKbFx9Bpie2+vMJKKx1fH1EN5yiTfp8CiLOTptSYy1g8H4yDpGlEdshL1PBiFtBHepF2cNsqeEeFQ==",
+ "dev": true,
+ "license": "Unlicense",
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/eventemitter3": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
+ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/events": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.x"
+ }
+ },
+ "node_modules/execa": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+ "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cross-spawn": "^6.0.0",
+ "get-stream": "^4.0.0",
+ "is-stream": "^1.1.0",
+ "npm-run-path": "^2.0.0",
+ "p-finally": "^1.0.0",
+ "signal-exit": "^3.0.0",
+ "strip-eof": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/express": {
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
+ "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "accepts": "~1.3.8",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.20.3",
+ "content-disposition": "0.5.4",
+ "content-type": "~1.0.4",
+ "cookie": "0.7.1",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "1.3.1",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "merge-descriptors": "1.0.3",
+ "methods": "~1.1.2",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.12",
+ "proxy-addr": "~2.0.7",
+ "qs": "6.13.0",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.2.1",
+ "send": "0.19.0",
+ "serve-static": "1.16.2",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/express/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/express/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-uri": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz",
+ "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/fastq": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
+ "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/faye-websocket": {
+ "version": "0.11.4",
+ "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz",
+ "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "websocket-driver": ">=0.5.1"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/figures": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+ "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "escape-string-regexp": "^1.0.5"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/finalhandler": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
+ "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "debug": "2.6.9",
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "statuses": "2.0.1",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/finalhandler/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/finalhandler/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/find-cache-dir": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz",
+ "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "commondir": "^1.0.1",
+ "make-dir": "^3.0.2",
+ "pkg-dir": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/avajs/find-cache-dir?sponsor=1"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/flat": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
+ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "peer": true,
+ "bin": {
+ "flat": "cli.js"
+ }
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.15.9",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
+ "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/fork-ts-checker-webpack-plugin": {
+ "version": "6.5.3",
+ "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz",
+ "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.8.3",
+ "@types/json-schema": "^7.0.5",
+ "chalk": "^4.1.0",
+ "chokidar": "^3.4.2",
+ "cosmiconfig": "^6.0.0",
+ "deepmerge": "^4.2.2",
+ "fs-extra": "^9.0.0",
+ "glob": "^7.1.6",
+ "memfs": "^3.1.2",
+ "minimatch": "^3.0.4",
+ "schema-utils": "2.7.0",
+ "semver": "^7.3.2",
+ "tapable": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=10",
+ "yarn": ">=1.0.0"
+ },
+ "peerDependencies": {
+ "eslint": ">= 6",
+ "typescript": ">= 2.7",
+ "vue-template-compiler": "*",
+ "webpack": ">= 4"
+ },
+ "peerDependenciesMeta": {
+ "eslint": {
+ "optional": true
+ },
+ "vue-template-compiler": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/fork-ts-checker-webpack-plugin/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz",
+ "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/json-schema": "^7.0.4",
+ "ajv": "^6.12.2",
+ "ajv-keywords": "^3.4.1"
+ },
+ "engines": {
+ "node": ">= 8.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/fork-ts-checker-webpack-plugin/node_modules/semver": {
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
+ "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fraction.js": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
+ "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "type": "patreon",
+ "url": "https://github.com/sponsors/rawify"
+ }
+ },
+ "node_modules/fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fs-extra": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
+ "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "at-least-node": "^1.0.0",
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/fs-monkey": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz",
+ "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==",
+ "dev": true,
+ "license": "Unlicense"
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pump": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/glob-to-regexp": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
+ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/globby": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+ "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.2.9",
+ "ignore": "^5.2.0",
+ "merge2": "^1.4.1",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/gzip-size": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz",
+ "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "duplexer": "^0.1.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/handle-thing": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
+ "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hash-sum": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz",
+ "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/he": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "he": "bin/he"
+ }
+ },
+ "node_modules/highlight.js": {
+ "version": "10.7.3",
+ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
+ "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "peer": true,
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/hosted-git-info": {
+ "version": "2.8.9",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/hpack.js": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
+ "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "obuf": "^1.0.0",
+ "readable-stream": "^2.0.1",
+ "wbuf": "^1.1.0"
+ }
+ },
+ "node_modules/hpack.js/node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/hpack.js/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/hpack.js/node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/html-entities": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz",
+ "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/mdevils"
+ },
+ {
+ "type": "patreon",
+ "url": "https://patreon.com/mdevils"
+ }
+ ],
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/html-minifier-terser": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
+ "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "camel-case": "^4.1.2",
+ "clean-css": "^5.2.2",
+ "commander": "^8.3.0",
+ "he": "^1.2.0",
+ "param-case": "^3.0.4",
+ "relateurl": "^0.2.7",
+ "terser": "^5.10.0"
+ },
+ "bin": {
+ "html-minifier-terser": "cli.js"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/html-webpack-plugin": {
+ "version": "5.6.3",
+ "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.3.tgz",
+ "integrity": "sha512-QSf1yjtSAsmf7rYBV7XX86uua4W/vkhIt0xNXKbsi2foEeW7vjJQz4bhnpL3xH+l1ryl1680uNv968Z+X6jSYg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/html-minifier-terser": "^6.0.0",
+ "html-minifier-terser": "^6.0.2",
+ "lodash": "^4.17.21",
+ "pretty-error": "^4.0.0",
+ "tapable": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/html-webpack-plugin"
+ },
+ "peerDependencies": {
+ "@rspack/core": "0.x || 1.x",
+ "webpack": "^5.20.0"
+ },
+ "peerDependenciesMeta": {
+ "@rspack/core": {
+ "optional": true
+ },
+ "webpack": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/html-webpack-plugin/node_modules/tapable": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
+ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/htmlparser2": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
+ "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==",
+ "dev": true,
+ "funding": [
+ "https://github.com/fb55/htmlparser2?sponsor=1",
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "domelementtype": "^2.0.1",
+ "domhandler": "^4.0.0",
+ "domutils": "^2.5.2",
+ "entities": "^2.0.0"
+ }
+ },
+ "node_modules/http-deceiver": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz",
+ "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/http-errors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/http-parser-js": {
+ "version": "0.5.9",
+ "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.9.tgz",
+ "integrity": "sha512-n1XsPy3rXVxlqxVioEWdC+0+M+SQw0DpJynwtOPo1X+ZlvdzTLtDBIJJlDQTnwZIFJrZSzSGmIOUdP8tu+SgLw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/http-proxy": {
+ "version": "1.18.1",
+ "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
+ "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "eventemitter3": "^4.0.0",
+ "follow-redirects": "^1.0.0",
+ "requires-port": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/http-proxy-middleware": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz",
+ "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/http-proxy": "^1.17.8",
+ "http-proxy": "^1.18.1",
+ "is-glob": "^4.0.1",
+ "is-plain-obj": "^3.0.0",
+ "micromatch": "^4.0.2"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "@types/express": "^4.17.13"
+ },
+ "peerDependenciesMeta": {
+ "@types/express": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/human-signals": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "peer": true,
+ "engines": {
+ "node": ">=10.17.0"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/icss-utils": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
+ "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "engines": {
+ "node": "^10 || ^12 || >= 14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/ipaddr.js": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz",
+ "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-docker": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
+ "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "is-docker": "cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-file-esm": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-file-esm/-/is-file-esm-1.0.0.tgz",
+ "integrity": "sha512-rZlaNKb4Mr8WlRu2A9XdeoKgnO5aA53XdPHgCKVyCrQ/rWi89RET1+bq37Ru46obaQXeiX4vmFIm1vks41hoSA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "read-pkg-up": "^7.0.1"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-interactive": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
+ "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-plain-obj": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz",
+ "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-unicode-supported": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
+ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-wsl": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+ "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-docker": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/javascript-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz",
+ "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/jest-worker": {
+ "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,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/jest-worker/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/joi": {
+ "version": "17.13.3",
+ "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz",
+ "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@hapi/hoek": "^9.3.0",
+ "@hapi/topo": "^5.1.0",
+ "@sideway/address": "^4.1.5",
+ "@sideway/formula": "^3.0.1",
+ "@sideway/pinpoint": "^2.0.0"
+ }
+ },
+ "node_modules/js-message": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.7.tgz",
+ "integrity": "sha512-efJLHhLjIyKRewNS9EGZ4UpI8NguuL6fKkhRxVuMmrGV2xN/0APGdQYwLFky5w9naebSZ0OwAGp0G6/2Cg90rA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6.0"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/json-parse-better-errors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/klona": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz",
+ "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/launch-editor": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.10.0.tgz",
+ "integrity": "sha512-D7dBRJo/qcGX9xlvt/6wUYzQxjh5G1RvZPgPv8vi4KRU99DVQL/oW7tnVOCCTm2HGeo3C5HvGE5Yrh6UBoZ0vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "picocolors": "^1.0.0",
+ "shell-quote": "^1.8.1"
+ }
+ },
+ "node_modules/launch-editor-middleware": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/launch-editor-middleware/-/launch-editor-middleware-2.10.0.tgz",
+ "integrity": "sha512-RzZu7MeVlE3p1H6Sadc2BhuDGAj7bkeDCBpNq/zSENP4ohJGhso00k5+iYaRwKshIpiOAhMmimce+5D389xmSg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "launch-editor": "^2.10.0"
+ }
+ },
+ "node_modules/lilconfig": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
+ "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/loader-runner": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
+ "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.11.5"
+ }
+ },
+ "node_modules/loader-utils": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz",
+ "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/loader-utils/node_modules/json5": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
+ "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "minimist": "^1.2.0"
+ },
+ "bin": {
+ "json5": "lib/cli.js"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/lodash.defaultsdeep": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz",
+ "integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/lodash.mapvalues": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz",
+ "integrity": "sha512-JPFqXFeZQ7BfS00H58kClY7SPVeHertPE0lNuCyZ26/XlN8TvakYD7b9bGyNmXbT/D3BbtPAAmq90gPWqLkxlQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/lodash.memoize": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
+ "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/lodash.uniq": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+ "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/log-symbols": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
+ "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.1.0",
+ "is-unicode-supported": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-symbols/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/log-update": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz",
+ "integrity": "sha512-vlP11XfFGyeNQlmEn9tJ66rEW1coA/79m5z6BCkudjbAGE83uhAcGYrBFwfs3AdLiLzGRusRPAbSPK9xZteCmg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ansi-escapes": "^3.0.0",
+ "cli-cursor": "^2.0.0",
+ "wrap-ansi": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/log-update/node_modules/ansi-regex": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
+ "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/log-update/node_modules/cli-cursor": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
+ "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "restore-cursor": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/log-update/node_modules/is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/log-update/node_modules/mimic-fn": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
+ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/log-update/node_modules/onetime": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
+ "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "mimic-fn": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/log-update/node_modules/restore-cursor": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
+ "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "onetime": "^2.0.0",
+ "signal-exit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/log-update/node_modules/string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/log-update/node_modules/strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ansi-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/log-update/node_modules/wrap-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz",
+ "integrity": "sha512-iXR3tDXpbnTpzjKSylUJRkLuOrEC7hwEB221cgn6wtF8wpmz28puFXAEfPT5zrjM3wahygB//VuWEr1vTkDcNQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "string-width": "^2.1.1",
+ "strip-ansi": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/lower-case": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
+ "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.17",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
+ "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0"
+ }
+ },
+ "node_modules/make-dir": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/mdn-data": {
+ "version": "2.0.14",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
+ "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==",
+ "dev": true,
+ "license": "CC0-1.0",
+ "peer": true
+ },
+ "node_modules/media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/memfs": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz",
+ "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==",
+ "dev": true,
+ "license": "Unlicense",
+ "dependencies": {
+ "fs-monkey": "^1.0.4"
+ },
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
+ "node_modules/merge-descriptors": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
+ "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/merge-source-map": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz",
+ "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "source-map": "^0.6.1"
+ }
+ },
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/mini-css-extract-plugin": {
+ "version": "2.9.2",
+ "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz",
+ "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "schema-utils": "^4.0.0",
+ "tapable": "^2.2.1"
+ },
+ "engines": {
+ "node": ">= 12.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.0.0"
+ }
+ },
+ "node_modules/mini-css-extract-plugin/node_modules/ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "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",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3"
+ },
+ "peerDependencies": {
+ "ajv": "^8.8.2"
+ }
+ },
+ "node_modules/mini-css-extract-plugin/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,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/mini-css-extract-plugin/node_modules/schema-utils": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz",
+ "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/json-schema": "^7.0.9",
+ "ajv": "^8.9.0",
+ "ajv-formats": "^2.1.1",
+ "ajv-keywords": "^5.1.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/mini-css-extract-plugin/node_modules/tapable": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
+ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/minimalistic-assert": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minipass/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true
+ },
+ "node_modules/mkdirp": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
+ "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "minimist": "^1.2.6"
+ },
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ }
+ },
+ "node_modules/module-alias": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.3.tgz",
+ "integrity": "sha512-23g5BFj4zdQL/b6tor7Ji+QY4pEfNH784BMslY9Qb0UnJWRAt+lQGLYmRaM0KDBwIG23ffEBELhZDP2rhi9f/Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/mrmime": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
+ "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/multicast-dns": {
+ "version": "7.2.5",
+ "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz",
+ "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "dns-packet": "^5.2.2",
+ "thunky": "^1.0.2"
+ },
+ "bin": {
+ "multicast-dns": "cli.js"
+ }
+ },
+ "node_modules/mz": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
+ "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "any-promise": "^1.0.0",
+ "object-assign": "^4.0.1",
+ "thenify-all": "^1.0.0"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.8",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
+ "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/negotiator": {
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz",
+ "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/no-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
+ "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "lower-case": "^2.0.2",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/node-forge": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
+ "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==",
+ "dev": true,
+ "license": "(BSD-3-Clause OR GPL-2.0)",
+ "peer": true,
+ "engines": {
+ "node": ">= 6.13.0"
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.19",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
+ "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/normalize-package-data": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+ "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "hosted-git-info": "^2.1.4",
+ "resolve": "^1.10.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ }
+ },
+ "node_modules/normalize-package-data/node_modules/semver": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/normalize-range": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+ "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/normalize-url": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
+ "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm-run-path": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+ "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "peer": true,
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/obuf": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
+ "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/on-finished": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/on-headers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
+ "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/open": {
+ "version": "8.4.2",
+ "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz",
+ "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-lazy-prop": "^2.0.0",
+ "is-docker": "^2.1.1",
+ "is-wsl": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/opener": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
+ "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==",
+ "dev": true,
+ "license": "(WTFPL OR MIT)",
+ "peer": true,
+ "bin": {
+ "opener": "bin/opener-bin.js"
+ }
+ },
+ "node_modules/ora": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz",
+ "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bl": "^4.1.0",
+ "chalk": "^4.1.0",
+ "cli-cursor": "^3.1.0",
+ "cli-spinners": "^2.5.0",
+ "is-interactive": "^1.0.0",
+ "is-unicode-supported": "^0.1.0",
+ "log-symbols": "^4.1.0",
+ "strip-ansi": "^6.0.0",
+ "wcwidth": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ora/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/p-finally": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+ "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/p-retry": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz",
+ "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/retry": "0.12.0",
+ "retry": "^0.13.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/param-case": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz",
+ "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "dot-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/parse-json": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-even-better-errors": "^2.3.0",
+ "lines-and-columns": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parse5": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
+ "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
+ "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "parse5": "^6.0.1"
+ }
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
+ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/pascal-case": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz",
+ "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "no-case": "^3.0.4",
+ "tslib": "^2.0.3"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/path-to-regexp": {
+ "version": "0.1.12",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
+ "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "find-up": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/portfinder": {
+ "version": "1.0.33",
+ "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.33.tgz",
+ "integrity": "sha512-+2jndHT63cL5MdQOwDm9OT2dIe11zVpjV+0GGRXdtO1wpPxv260NfVqoEXtYAi/shanmm3W4+yLduIe55ektTw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "async": "^2.6.4",
+ "debug": "^3.2.7",
+ "mkdirp": "^0.5.6"
+ },
+ "engines": {
+ "node": ">= 0.12.0"
+ }
+ },
+ "node_modules/portfinder/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.5.3",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
+ "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.8",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/postcss-calc": {
+ "version": "8.2.4",
+ "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz",
+ "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "postcss-selector-parser": "^6.0.9",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.2"
+ }
+ },
+ "node_modules/postcss-colormin": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz",
+ "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "browserslist": "^4.21.4",
+ "caniuse-api": "^3.0.0",
+ "colord": "^2.9.1",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-convert-values": {
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz",
+ "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "browserslist": "^4.21.4",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-discard-comments": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz",
+ "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-discard-duplicates": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz",
+ "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-discard-empty": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz",
+ "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-discard-overridden": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz",
+ "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-loader": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.1.tgz",
+ "integrity": "sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "cosmiconfig": "^7.0.0",
+ "klona": "^2.0.5",
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": ">= 12.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "postcss": "^7.0.0 || ^8.0.1",
+ "webpack": "^5.0.0"
+ }
+ },
+ "node_modules/postcss-loader/node_modules/cosmiconfig": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
+ "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/parse-json": "^4.0.0",
+ "import-fresh": "^3.2.1",
+ "parse-json": "^5.0.0",
+ "path-type": "^4.0.0",
+ "yaml": "^1.10.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/postcss-loader/node_modules/semver": {
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
+ "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/postcss-merge-longhand": {
+ "version": "5.1.7",
+ "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz",
+ "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0",
+ "stylehacks": "^5.1.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-merge-rules": {
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz",
+ "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "browserslist": "^4.21.4",
+ "caniuse-api": "^3.0.0",
+ "cssnano-utils": "^3.1.0",
+ "postcss-selector-parser": "^6.0.5"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-minify-font-values": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz",
+ "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-minify-gradients": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz",
+ "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "colord": "^2.9.1",
+ "cssnano-utils": "^3.1.0",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-minify-params": {
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz",
+ "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "browserslist": "^4.21.4",
+ "cssnano-utils": "^3.1.0",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-minify-selectors": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz",
+ "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "postcss-selector-parser": "^6.0.5"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-modules-extract-imports": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz",
+ "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "engines": {
+ "node": "^10 || ^12 || >= 14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/postcss-modules-local-by-default": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz",
+ "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "icss-utils": "^5.0.0",
+ "postcss-selector-parser": "^7.0.0",
+ "postcss-value-parser": "^4.1.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >= 14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/postcss-modules-local-by-default/node_modules/postcss-selector-parser": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz",
+ "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-modules-scope": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz",
+ "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "dependencies": {
+ "postcss-selector-parser": "^7.0.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >= 14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/postcss-modules-scope/node_modules/postcss-selector-parser": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz",
+ "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-modules-values": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz",
+ "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "dependencies": {
+ "icss-utils": "^5.0.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >= 14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "node_modules/postcss-normalize-charset": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz",
+ "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-normalize-display-values": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz",
+ "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-normalize-positions": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz",
+ "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-normalize-repeat-style": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz",
+ "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-normalize-string": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz",
+ "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-normalize-timing-functions": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz",
+ "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-normalize-unicode": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz",
+ "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "browserslist": "^4.21.4",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-normalize-url": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz",
+ "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "normalize-url": "^6.0.1",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-normalize-whitespace": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz",
+ "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-ordered-values": {
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz",
+ "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "cssnano-utils": "^3.1.0",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-reduce-initial": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz",
+ "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "browserslist": "^4.21.4",
+ "caniuse-api": "^3.0.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-reduce-transforms": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz",
+ "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-selector-parser": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
+ "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-svgo": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz",
+ "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0",
+ "svgo": "^2.7.0"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-unique-selectors": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz",
+ "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "postcss-selector-parser": "^6.0.5"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/postcss-value-parser": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/prettier": {
+ "version": "2.8.8",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
+ "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "bin": {
+ "prettier": "bin-prettier.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/pretty-error": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz",
+ "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "lodash": "^4.17.20",
+ "renderkid": "^3.0.0"
+ }
+ },
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/progress-webpack-plugin": {
+ "version": "1.0.16",
+ "resolved": "https://registry.npmjs.org/progress-webpack-plugin/-/progress-webpack-plugin-1.0.16.tgz",
+ "integrity": "sha512-sdiHuuKOzELcBANHfrupYo+r99iPRyOnw15qX+rNlVUqXGfjXdH4IgxriKwG1kNJwVswKQHMdj1hYZMcb9jFaA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "chalk": "^2.1.0",
+ "figures": "^2.0.0",
+ "log-update": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "peerDependencies": {
+ "webpack": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0"
+ }
+ },
+ "node_modules/progress-webpack-plugin/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/progress-webpack-plugin/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/progress-webpack-plugin/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/progress-webpack-plugin/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/progress-webpack-plugin/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/progress-webpack-plugin/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/proxy-addr/node_modules/ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/pseudomap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+ "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true
+ },
+ "node_modules/pump": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
+ "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/qs": {
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
+ "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "peer": true,
+ "dependencies": {
+ "side-channel": "^1.0.6"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "node_modules/range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/raw-body": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
+ "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/read-pkg": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
+ "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/normalize-package-data": "^2.4.0",
+ "normalize-package-data": "^2.5.0",
+ "parse-json": "^5.0.0",
+ "type-fest": "^0.6.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/read-pkg-up": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
+ "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "find-up": "^4.1.0",
+ "read-pkg": "^5.2.0",
+ "type-fest": "^0.8.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/read-pkg-up/node_modules/type-fest": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "peer": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/relateurl": {
+ "version": "0.2.7",
+ "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
+ "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/renderkid": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz",
+ "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "css-select": "^4.1.3",
+ "dom-converter": "^0.2.0",
+ "htmlparser2": "^6.1.0",
+ "lodash": "^4.17.21",
+ "strip-ansi": "^6.0.1"
+ }
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/requires-port": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/resolve": {
+ "version": "1.22.10",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
+ "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-core-module": "^2.16.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/restore-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+ "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/retry": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz",
+ "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "2.79.2",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz",
+ "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/schema-utils": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz",
+ "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/json-schema": "^7.0.5",
+ "ajv": "^6.12.4",
+ "ajv-keywords": "^3.5.2"
+ },
+ "engines": {
+ "node": ">= 8.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/select-hose": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
+ "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/selfsigned": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz",
+ "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/node-forge": "^1.3.0",
+ "node-forge": "^1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/send": {
+ "version": "0.19.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
+ "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "mime": "1.6.0",
+ "ms": "2.1.3",
+ "on-finished": "2.4.1",
+ "range-parser": "~1.2.1",
+ "statuses": "2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/send/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/send/node_modules/debug/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/send/node_modules/encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/serialize-javascript": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
+ "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "node_modules/serve-index": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
+ "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "accepts": "~1.3.4",
+ "batch": "0.6.1",
+ "debug": "2.6.9",
+ "escape-html": "~1.0.3",
+ "http-errors": "~1.6.2",
+ "mime-types": "~2.1.17",
+ "parseurl": "~1.3.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/serve-index/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/serve-index/node_modules/depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/serve-index/node_modules/http-errors": {
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+ "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.0",
+ "statuses": ">= 1.4.0 < 2"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/serve-index/node_modules/inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true
+ },
+ "node_modules/serve-index/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/serve-index/node_modules/setprototypeof": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+ "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true
+ },
+ "node_modules/serve-index/node_modules/statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/serve-static": {
+ "version": "1.16.2",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
+ "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.19.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true
+ },
+ "node_modules/shallow-clone": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
+ "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "kind-of": "^6.0.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/shell-quote": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz",
+ "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/signal-exit": {
+ "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,
+ "license": "ISC"
+ },
+ "node_modules/sirv": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz",
+ "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@polka/url": "^1.0.0-next.24",
+ "mrmime": "^2.0.0",
+ "totalist": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/sockjs": {
+ "version": "0.3.24",
+ "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz",
+ "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "faye-websocket": "^0.11.3",
+ "uuid": "^8.3.2",
+ "websocket-driver": "^0.7.4"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/spdx-correct": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
+ "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-exceptions": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
+ "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
+ "dev": true,
+ "license": "CC-BY-3.0"
+ },
+ "node_modules/spdx-expression-parse": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+ "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-license-ids": {
+ "version": "3.0.21",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz",
+ "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==",
+ "dev": true,
+ "license": "CC0-1.0"
+ },
+ "node_modules/spdy": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz",
+ "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "debug": "^4.1.0",
+ "handle-thing": "^2.0.0",
+ "http-deceiver": "^1.2.7",
+ "select-hose": "^2.0.0",
+ "spdy-transport": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/spdy-transport": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz",
+ "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "debug": "^4.1.0",
+ "detect-node": "^2.0.4",
+ "hpack.js": "^2.1.6",
+ "obuf": "^1.1.2",
+ "readable-stream": "^3.0.6",
+ "wbuf": "^1.7.3"
+ }
+ },
+ "node_modules/ssri": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
+ "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "dependencies": {
+ "minipass": "^3.1.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/stable": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz",
+ "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==",
+ "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/stackframe": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz",
+ "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/statuses": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-eof": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+ "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/strip-final-newline": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/stylehacks": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz",
+ "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "browserslist": "^4.21.4",
+ "postcss-selector-parser": "^6.0.4"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.2.15"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/svgo": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz",
+ "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@trysound/sax": "0.2.0",
+ "commander": "^7.2.0",
+ "css-select": "^4.1.3",
+ "css-tree": "^1.1.3",
+ "csso": "^4.2.0",
+ "picocolors": "^1.0.0",
+ "stable": "^0.1.8"
+ },
+ "bin": {
+ "svgo": "bin/svgo"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/svgo/node_modules/commander": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
+ "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/tapable": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
+ "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/terser": {
+ "version": "5.39.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz",
+ "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.8.2",
+ "commander": "^2.20.0",
+ "source-map-support": "~0.5.20"
+ },
+ "bin": {
+ "terser": "bin/terser"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/terser-webpack-plugin": {
+ "version": "5.3.12",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.12.tgz",
+ "integrity": "sha512-jDLYqo7oF8tJIttjXO6jBY5Hk8p3A8W4ttih7cCEq64fQFWmgJ4VqAQjKr7WwIDlmXKEc6QeoRb5ecjZ+2afcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "jest-worker": "^27.4.5",
+ "schema-utils": "^4.3.0",
+ "serialize-javascript": "^6.0.2",
+ "terser": "^5.31.1"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.1.0"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ },
+ "uglify-js": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/terser-webpack-plugin/node_modules/ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3"
+ },
+ "peerDependencies": {
+ "ajv": "^8.8.2"
+ }
+ },
+ "node_modules/terser-webpack-plugin/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,
+ "license": "MIT"
+ },
+ "node_modules/terser-webpack-plugin/node_modules/schema-utils": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz",
+ "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/json-schema": "^7.0.9",
+ "ajv": "^8.9.0",
+ "ajv-formats": "^2.1.1",
+ "ajv-keywords": "^5.1.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/terser/node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/thenify": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
+ "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "any-promise": "^1.0.0"
+ }
+ },
+ "node_modules/thenify-all": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
+ "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "thenify": ">= 3.1.0 < 4"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/thread-loader": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/thread-loader/-/thread-loader-3.0.4.tgz",
+ "integrity": "sha512-ByaL2TPb+m6yArpqQUZvP+5S1mZtXsEP7nWKKlAUTm7fCml8kB5s1uI3+eHRP2bk5mVYfRSBI7FFf+tWEyLZwA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-parse-better-errors": "^1.0.2",
+ "loader-runner": "^4.1.0",
+ "loader-utils": "^2.0.0",
+ "neo-async": "^2.6.2",
+ "schema-utils": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^4.27.0 || ^5.0.0"
+ }
+ },
+ "node_modules/thread-loader/node_modules/loader-utils": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
+ "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^2.1.2"
+ },
+ "engines": {
+ "node": ">=8.9.0"
+ }
+ },
+ "node_modules/thread-loader/node_modules/schema-utils": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
+ "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@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/thunky": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
+ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/totalist": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
+ "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ts-loader": {
+ "version": "9.5.2",
+ "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.2.tgz",
+ "integrity": "sha512-Qo4piXvOTWcMGIgRiuFa6nHNm+54HbYaZCKqc9eeZCLRy3XqafQgwX2F7mofrbJG3g7EEb+lkiR+z2Lic2s3Zw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.1.0",
+ "enhanced-resolve": "^5.0.0",
+ "micromatch": "^4.0.0",
+ "semver": "^7.3.4",
+ "source-map": "^0.7.4"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "typescript": "*",
+ "webpack": "^5.0.0"
+ }
+ },
+ "node_modules/ts-loader/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/ts-loader/node_modules/semver": {
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
+ "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/ts-loader/node_modules/source-map": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
+ "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "dev": true,
+ "license": "0BSD",
+ "peer": true
+ },
+ "node_modules/type-fest": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
+ "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.8.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz",
+ "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
+ "devOptional": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "6.20.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
+ "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/universalify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+ "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
+ "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/utila": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz",
+ "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/validate-npm-package-license": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "node_modules/vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/vite": {
+ "version": "3.2.11",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-3.2.11.tgz",
+ "integrity": "sha512-K/jGKL/PgbIgKCiJo5QbASQhFiV02X9Jh+Qq0AKCRCRKZtOTVi4t6wh75FDpGf2N9rYOnzH87OEFQNaFy6pdxQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.15.9",
+ "postcss": "^8.4.18",
+ "resolve": "^1.22.1",
+ "rollup": "^2.79.1"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ },
+ "peerDependencies": {
+ "@types/node": ">= 14",
+ "less": "*",
+ "sass": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.4.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vue": {
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.13.tgz",
+ "integrity": "sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.13",
+ "@vue/compiler-sfc": "3.5.13",
+ "@vue/runtime-dom": "3.5.13",
+ "@vue/server-renderer": "3.5.13",
+ "@vue/shared": "3.5.13"
+ },
+ "peerDependencies": {
+ "typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vue-hot-reload-api": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz",
+ "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/vue-loader": {
+ "version": "17.4.2",
+ "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-17.4.2.tgz",
+ "integrity": "sha512-yTKOA4R/VN4jqjw4y5HrynFL8AK0Z3/Jt7eOJXEitsm0GMRHDBjCfCiuTiLP7OESvsZYo2pATCWhDqxC5ZrM6w==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "chalk": "^4.1.0",
+ "hash-sum": "^2.0.0",
+ "watchpack": "^2.4.0"
+ },
+ "peerDependencies": {
+ "webpack": "^4.1.0 || ^5.0.0-0"
+ },
+ "peerDependenciesMeta": {
+ "@vue/compiler-sfc": {
+ "optional": true
+ },
+ "vue": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vue-loader/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/vue-style-loader": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz",
+ "integrity": "sha512-sFuh0xfbtpRlKfm39ss/ikqs9AbKCoXZBpHeVZ8Tx650o0k0q/YCM7FRvigtxpACezfq6af+a7JeqVTWvncqDg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "hash-sum": "^1.0.2",
+ "loader-utils": "^1.0.2"
+ }
+ },
+ "node_modules/vue-style-loader/node_modules/hash-sum": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz",
+ "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/vue-template-es2015-compiler": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz",
+ "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/watchpack": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz",
+ "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.1.2"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/wbuf": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz",
+ "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "minimalistic-assert": "^1.0.0"
+ }
+ },
+ "node_modules/wcwidth": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
+ "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "defaults": "^1.0.3"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/webpack": {
+ "version": "5.98.0",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.98.0.tgz",
+ "integrity": "sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/eslint-scope": "^3.7.7",
+ "@types/estree": "^1.0.6",
+ "@webassemblyjs/ast": "^1.14.1",
+ "@webassemblyjs/wasm-edit": "^1.14.1",
+ "@webassemblyjs/wasm-parser": "^1.14.1",
+ "acorn": "^8.14.0",
+ "browserslist": "^4.24.0",
+ "chrome-trace-event": "^1.0.2",
+ "enhanced-resolve": "^5.17.1",
+ "es-module-lexer": "^1.2.1",
+ "eslint-scope": "5.1.1",
+ "events": "^3.2.0",
+ "glob-to-regexp": "^0.4.1",
+ "graceful-fs": "^4.2.11",
+ "json-parse-even-better-errors": "^2.3.1",
+ "loader-runner": "^4.2.0",
+ "mime-types": "^2.1.27",
+ "neo-async": "^2.6.2",
+ "schema-utils": "^4.3.0",
+ "tapable": "^2.1.1",
+ "terser-webpack-plugin": "^5.3.11",
+ "watchpack": "^2.4.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/webpack-bundle-analyzer": {
+ "version": "4.10.2",
+ "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz",
+ "integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@discoveryjs/json-ext": "0.5.7",
+ "acorn": "^8.0.4",
+ "acorn-walk": "^8.0.0",
+ "commander": "^7.2.0",
+ "debounce": "^1.2.1",
+ "escape-string-regexp": "^4.0.0",
+ "gzip-size": "^6.0.0",
+ "html-escaper": "^2.0.2",
+ "opener": "^1.5.2",
+ "picocolors": "^1.0.0",
+ "sirv": "^2.0.3",
+ "ws": "^7.3.1"
+ },
+ "bin": {
+ "webpack-bundle-analyzer": "lib/bin/analyzer.js"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/webpack-bundle-analyzer/node_modules/commander": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
+ "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/webpack-bundle-analyzer/node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/webpack-chain": {
+ "version": "6.5.1",
+ "resolved": "https://registry.npmjs.org/webpack-chain/-/webpack-chain-6.5.1.tgz",
+ "integrity": "sha512-7doO/SRtLu8q5WM0s7vPKPWX580qhi0/yBHkOxNkv50f6qB76Zy9o2wRTrrPULqYTvQlVHuvbA8v+G5ayuUDsA==",
+ "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
+ "dev": true,
+ "license": "MPL-2.0",
+ "peer": true,
+ "dependencies": {
+ "deepmerge": "^1.5.2",
+ "javascript-stringify": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/webpack-chain/node_modules/deepmerge": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz",
+ "integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/webpack-dev-middleware": {
+ "version": "5.3.4",
+ "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz",
+ "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "colorette": "^2.0.10",
+ "memfs": "^3.4.3",
+ "mime-types": "^2.1.31",
+ "range-parser": "^1.2.1",
+ "schema-utils": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 12.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^4.0.0 || ^5.0.0"
+ }
+ },
+ "node_modules/webpack-dev-middleware/node_modules/ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "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",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3"
+ },
+ "peerDependencies": {
+ "ajv": "^8.8.2"
+ }
+ },
+ "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",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/webpack-dev-middleware/node_modules/schema-utils": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz",
+ "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/json-schema": "^7.0.9",
+ "ajv": "^8.9.0",
+ "ajv-formats": "^2.1.1",
+ "ajv-keywords": "^5.1.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/webpack-dev-server": {
+ "version": "4.15.2",
+ "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz",
+ "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/bonjour": "^3.5.9",
+ "@types/connect-history-api-fallback": "^1.3.5",
+ "@types/express": "^4.17.13",
+ "@types/serve-index": "^1.9.1",
+ "@types/serve-static": "^1.13.10",
+ "@types/sockjs": "^0.3.33",
+ "@types/ws": "^8.5.5",
+ "ansi-html-community": "^0.0.8",
+ "bonjour-service": "^1.0.11",
+ "chokidar": "^3.5.3",
+ "colorette": "^2.0.10",
+ "compression": "^1.7.4",
+ "connect-history-api-fallback": "^2.0.0",
+ "default-gateway": "^6.0.3",
+ "express": "^4.17.3",
+ "graceful-fs": "^4.2.6",
+ "html-entities": "^2.3.2",
+ "http-proxy-middleware": "^2.0.3",
+ "ipaddr.js": "^2.0.1",
+ "launch-editor": "^2.6.0",
+ "open": "^8.0.9",
+ "p-retry": "^4.5.0",
+ "rimraf": "^3.0.2",
+ "schema-utils": "^4.0.0",
+ "selfsigned": "^2.1.1",
+ "serve-index": "^1.9.1",
+ "sockjs": "^0.3.24",
+ "spdy": "^4.0.2",
+ "webpack-dev-middleware": "^5.3.4",
+ "ws": "^8.13.0"
+ },
+ "bin": {
+ "webpack-dev-server": "bin/webpack-dev-server.js"
+ },
+ "engines": {
+ "node": ">= 12.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^4.37.0 || ^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "webpack": {
+ "optional": true
+ },
+ "webpack-cli": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/webpack-dev-server/node_modules/ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "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",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3"
+ },
+ "peerDependencies": {
+ "ajv": "^8.8.2"
+ }
+ },
+ "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",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/webpack-dev-server/node_modules/schema-utils": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz",
+ "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/json-schema": "^7.0.9",
+ "ajv": "^8.9.0",
+ "ajv-formats": "^2.1.1",
+ "ajv-keywords": "^5.1.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/webpack-dev-server/node_modules/ws": {
+ "version": "8.18.1",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz",
+ "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==",
+ "dev": true,
+ "license": "MIT",
+ "peer": 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.10.0",
+ "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz",
+ "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "clone-deep": "^4.0.1",
+ "flat": "^5.0.2",
+ "wildcard": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/webpack-sources": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
+ "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/webpack-virtual-modules": {
+ "version": "0.4.6",
+ "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.4.6.tgz",
+ "integrity": "sha512-5tyDlKLqPfMqjT3Q9TAqf2YqjwmnUleZwzJi1A5qXnlBCdj2AtOJ6wAWdglTIDOPgOiOrXeBeFcsQ8+aGQ6QbA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/webpack/node_modules/ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/webpack/node_modules/ajv-keywords": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3"
+ },
+ "peerDependencies": {
+ "ajv": "^8.8.2"
+ }
+ },
+ "node_modules/webpack/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,
+ "license": "MIT"
+ },
+ "node_modules/webpack/node_modules/schema-utils": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz",
+ "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/json-schema": "^7.0.9",
+ "ajv": "^8.9.0",
+ "ajv-formats": "^2.1.1",
+ "ajv-keywords": "^5.1.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/webpack/node_modules/tapable": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
+ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/websocket-driver": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
+ "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "http-parser-js": ">=0.5.1",
+ "safe-buffer": ">=5.1.0",
+ "websocket-extensions": ">=0.1.1"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/websocket-extensions": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
+ "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "peer": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/whatwg-fetch": {
+ "version": "3.6.20",
+ "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz",
+ "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "node_modules/which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "which": "bin/which"
+ }
+ },
+ "node_modules/wildcard": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz",
+ "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/ws": {
+ "version": "7.5.10",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
+ "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=8.3.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": "^5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/yaml": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
+ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "20.2.9",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ }
+ }
+ }
+}
+{
+ "name": "frontend",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "type-check": "vue-tsc --noEmit",
+ "build-check": "vue-tsc --noEmit && vite build",
+ "build": "vite build",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "@xterm/addon-fit": "^0.10.0",
+ "@xterm/addon-web-links": "^0.11.0",
+ "@xterm/xterm": "^5.5.0",
+ "js-yaml": "^4.1.0",
+ "vue": "^3.2.37"
+ },
+ "devDependencies": {
+ "@types/node": "^22.13.8",
+ "@vitejs/plugin-vue": "^3.2.0",
+ "@vue/cli-plugin-typescript": "^5.0.8",
+ "@vue/runtime-core": "^3.5.13",
+ "@vue/tsconfig": "^0.7.0",
+ "typescript": "^5.8.2",
+ "vite": "^3.0.7"
+ }
+}
+578bffc0710f3ba42676abfbea4b0d3d
\ No newline at end of file
+<script lang="ts">
+import { defineComponent } from 'vue';
+import { SecretUpdateOptions } from './types/custom';
+import NavigationPane from './components/NavigationPane.vue';
+import DeploymentsList from './components/DeploymentsList.vue';
+import StatefulSetsList from './components/StatefulsetsList.vue';
+import PodsList from './components/PodsList.vue';
+import ConfigMapsList from './components/ConfigMapsList.vue';
+import IngressesList from './components/IngressesList.vue';
+import NamespacesList from './components/NamespacesList.vue';
+import SecretsList from './components/SecretsList.vue';
+import PersistentVolumeClaimsList from './components/PersistentVolumeClaimsList.vue';
+import PersistentVolumesList from './components/PersistentVolumesList.vue';
+import BottomTabs from './components/BottomTabs.vue';
+import { CustomPod } from './types/custom';
+import { KubernetesPod } from './types/kubernetes';
+import { kubernetesService } from './lib/kubernetes';
+import {
+ KubernetesCluster,
+ KubernetesDeployment,
+ KubernetesStatefulSet,
+ KubernetesConfigMap,
+ KubernetesIngress,
+ KubernetesNamespace,
+ KubernetesSecret,
+ KubernetesPersistentVolumeClaim,
+ KubernetesPersistentVolume,
+ ApiResponse,
+ } from './types/kubernetes';
+
+export default defineComponent({
+ components: {
+ NavigationPane,
+ DeploymentsList,
+ StatefulSetsList,
+ PodsList,
+ ConfigMapsList,
+ IngressesList,
+ NamespacesList,
+ SecretsList,
+ PersistentVolumeClaimsList,
+ PersistentVolumesList,
+ BottomTabs
+ },
+
+ computed: {
+ currentResourceComponent() {
+ if (this.selectedResource === 'pods') {
+ return 'PodsList';
+ } else if (this.selectedResource === 'deployments') {
+ return 'DeploymentsList';
+ } else if (this.selectedResource === 'statefulsets') {
+ return 'StatefulSetsList';
+ } else if (this.selectedResource === 'configmaps') {
+ return 'ConfigMapsList';
+ } else if (this.selectedResource === 'namespaces') {
+ return 'NamespacesList';
+ } else if (this.selectedResource === 'secrets') {
+ return 'SecretsList';
+ } else if (this.selectedResource === 'persistentvolumeclaims') {
+ return 'PersistentVolumeClaimsList';
+ } else if (this.selectedResource === 'persistentVolumes') {
+ return 'PersistentVolumesList';
+ } else {
+ return 'IngressesList';
+ }
+ }
+ },
+
+ data() {
+ return {
+ clusters: [] as KubernetesCluster[],
+ selectedCluster: null as KubernetesCluster | null,
+ selectedResource: null as string | null,
+ selectedResourceItem: null as any | null,
+ deployments: [] as KubernetesDeployment[],
+ statefulSets: [] as KubernetesStatefulSet[],
+ pods: [] as any[],
+ configMaps: [] as KubernetesConfigMap[],
+ ingresses: [] as KuberntesIngress[],
+ namespaces: [] as KubernetesNamespaces[],
+ secrets: [] as KubernetesSecret[],
+ persistentvolumeclaims: [] as KubernetesPersistentVolumeClaim[],
+ persistentVolumes: [] as KubernetesPersistentVolume[],
+ selectedTab: 'logs' as 'logs' | 'terminal' | 'describe',
+ };
+ },
+
+ async created() {
+ await this.loadClusters();
+ },
+
+ methods: {
+ handleStatefulSetSelect(statefulSet: KubernetesStatefulSet) {
+ this.selectedResourceItem = statefulSet;
+ },
+
+ handleDeploymentSelect(deployment: KubernetesDeployment) {
+ this.selectedResourceItem = deployment;
+ },
+
+ handlePodSelect(pod: any) {
+ this.selectedResourceItem = pod;
+ },
+
+ handleConfigMapSelect(configMap: KubernetesConfigMap) {
+ this.selectedResourceItem = configMap;
+ },
+
+ handleIngressSelect(ingress: KubernetesIngress) {
+ this.selectedResourceItem = ingress;
+ },
+
+ handleNamespaceSelect(namespace: KubernetesNamespace) {
+ this.selectedResourceItem = namespace;
+ },
+
+ handleSecretSelect(secret: KubernetesSecret) {
+ this.selectedResourceItem = secret;
+ },
+
+ handlePersistentVolumeClaimSelect(persistentVolumeClaim: KubernetesPersistentVolumeClaim) {
+ this.selectedResourceItem = persistentVolumeClaim;
+ },
+
+ handlePersistentVolumeSelect(persistentVolume: KubernetesPersistentVolume) {
+ this.selectedResourceItem = persistentVolume;
+ },
+
+ async loadClusters() {
+ try {
+ const response = await kubernetesService.getClusters();
+ if (response.success && response.data) {
+ this.clusters = response.data.map(cluster => ({
+ ...cluster,
+ name: cluster.name
+ }));
+ }
+ } catch (error) {
+ console.error('Failed to load clusters:', error);
+ }
+ },
+
+ getClusterName(server: string): string {
+ try {
+ const url = new URL(server);
+ return url.hostname;
+ } catch {
+ return server;
+ }
+ },
+
+ async handleUpdateSecret(opts: SecretUpdateOptions) {
+ try {
+ const response = await kubernetesService.updateSecret(opts.context, opts.definition, opts.origNamespace, opts.origName);
+ if (response.success) {
+ alert(response.msg);
+ await this.loadResources();
+ } else {
+ throw new Error(response.msg);
+ }
+ } catch (error: any) {
+ alert(`Error updating Secret: ${error}`);
+ }
+ },
+
+ async handleDeleteSecret({cluster, secret}: { cluster: KubernetesCluster, secret: KubernetesSecret}) {
+ try {
+ const response = await kubernetesService.deleteSecret(cluster.contextName, secret.metadata.namespace, secret.metadata.name);
+ if (response.success) {
+ alert(response.msg);
+ await this.loadResources();
+ } else {
+ throw new Error(response.msg);
+ }
+ } catch (error) {
+ alert(`Error deleting Secret: ${error}`);
+ }
+ },
+
+ async handleDeleteNamespace({cluster, namespace}: { cluster: KubernetesCluster, namespace: KubernetesNamespace }) {
+ try {
+ const response = await kubernetesService.deleteNamespace(cluster.contextName, namespace.metadata.name);
+ if (response.success) {
+ alert(`Namespace ${namespace.metadata.name} deleted successfully`);
+ await this.loadResources();
+ } else {
+ throw new Error(response.msg || 'Unknown error');
+ }
+ } catch (error) {
+ alert(`Error deleting Namespace: ${error}`);
+ }
+ },
+
+ async handleDeletePersistentVolume({cluster, definition}: { cluster: KubernetesCluster, definition: KubernetesPersistentVolume}) {
+ try {
+ const response = await kubernetesService.deletePersistentVolume(cluster.contextName, definition.metadata.name);
+ if (response.success) {
+ alert(response.msg);
+ await this.loadResources();
+ } else {
+ throw new Error(response.msg);
+ }
+ } catch (error) {
+ alert(`Error deleting Persistent Volume: ${error}`);
+ }
+ },
+
+ async handleCreateSecret(opts: SecretCreateOptions) {
+ try {
+ let response;
+ response = await kubernetesService.createSecret(opts.context, opts.opts);
+ if (response.success) {
+ alert(response.msg)
+ await this.loadResources();
+ } else {
+ throw new Error(response.msg);
+ }
+ } catch (error) {
+ alert(`Error creating Secret: ${error}`);
+ }
+ },
+
+ async handleCreatePersistentVolumeClaim({cluster, persistentVolumeClaim}: {cluster: KubernetesCluster, persistentVolumeClaim: KubernetesPersistentVolumeClaim}) {
+ try {
+ let response;
+ response = await kubernetesService.createPersistentVolumeClaim(cluster.contextName, persistentVolumeClaim);
+ if (response.success) {
+ alert(response.msg)
+ await this.loadResources();
+ } else {
+ throw new Error(response.msg);
+ }
+ } catch (error) {
+ alert(`Error creating Persistent Volume Claim: ${error}`);
+ }
+ },
+
+ async handleDeletePersistentVolumeClaim({cluster, persistentVolumeClaim}: { cluster: KubernetesCluster, persistentVolumeClaim: KubernetesPersistentVolumeClaim}) {
+ try {
+ const response = await kubernetesService.deletePersistentVolumeClaim(cluster.contextName, persistentVolumeClaim.metadata.namespace, persistentVolumeClaim.metadata.name);
+ if (response.success) {
+ alert(response.msg);
+ await this.loadResources();
+ } else {
+ throw new Error(response.msg);
+ }
+ } catch (error) {
+ alert(`Error deleting Persistent Volume Claim: ${error}`);
+ }
+ },
+
+ async handleCreatePersistentVolume({cluster, definition}: {cluster: KubernetesCluster, definition: KubernetesPersistentVolume}) {
+ try {
+ let response;
+ response = await kubernetesService.createPersistentVolume(cluster.contextName, definition);
+ if (response.success) {
+ alert(response.msg)
+ await this.loadResources();
+ } else {
+ throw new Error(response.msg);
+ }
+ } catch (error) {
+ alert(`Error creating Persistent Volume: ${error}`);
+ }
+ },
+
+ async handleCreateNamespace(
+ {cluster, definition, yamlContent, isYaml}:
+ {
+ cluster: { contextName: string },
+ definition?: any,
+ yamlContent?: string,
+ isYaml?: boolean,
+ }
+ ) {
+ try {
+ let response;
+ if (isYaml && yamlContent) {
+ response = await kubernetesService.createNamespaceYAML(cluster.contextName, yamlContent);
+ } else if (!isYaml && definition) {
+ response = await kubernetesService.createNamespace(cluster.contextName, definition);
+ } else {
+ throw new Error("Invalid namespace creation parameters");
+ }
+
+ if (response.success) {
+ alert(response.msg)
+ await this.loadResources();
+ } else {
+ throw new Error(response.msg);
+ }
+ } catch (error) {
+ alert(`Error creating namespace: ${error}`);
+ }
+ },
+
+ async handleCreatePod({
+ cluster,
+ podDefinition,
+ yamlContent,
+ isYaml
+ }: {
+ cluster: { contextName: string },
+ podDefinition?: any,
+ yamlContent?: string,
+ isYaml?: boolean
+ }) {
+ try {
+ let response;
+
+ if (isYaml && yamlContent) {
+ response = await kubernetesService.createPodYAML(cluster.contextName, yamlContent);
+ } else if (!isYaml && podDefinition) {
+ response = await kubernetesService.createPod(cluster.contextName, podDefinition);
+ } else {
+ throw new Error('Invalid pod creation parameters');
+ }
+
+ if (response.success) {
+ alert(response.msg)
+ await this.loadResources();
+ } else {
+ throw new Error(response.msg);
+ }
+ } catch (error) {
+ console.error('Error creating pod:', error);
+ alert(`Error creating pod: ${error}`);
+ }
+ },
+
+ async handleDeletePod({cluster, pod}: { cluster: KubernetesCluster, pod: KubernetesPod }) {
+ try {
+ const response = await kubernetesService.deletePod(cluster.contextName, pod.metadata.namespace, pod.metadata.name);
+ if (response.success) {
+ alert(`Pod ${pod.metadata.name} deleted successfully`);
+ await this.loadResources();
+ } else {
+ throw new Error(response.msg || 'Unknown error');
+ }
+ } catch (error) {
+ console.error('Error deleting pod:', error);
+ alert(`Error deleting pod: ${error}`);
+ }
+ },
+
+ async handleDeleteIngress({cluster, ingress}: { cluster: KubernetesCluster, ingress: KubernetesIngress }) {
+ try {
+ const response = await kubernetesService.deleteIngress(cluster.contextName, ingress.metadata.namespace, ingress.metadata.name);
+ if (response.success) {
+ alert(`Ingress ${ingress.metadata.name} deleted successfully`);
+ await this.loadResources();
+ } else {
+ throw new Error(response.msg);
+ }
+ } catch (error) {
+ console.error('Error deleting ingress:', error);
+ alert(`Error deleting ingress: ${error}`);
+ }
+ },
+
+ async handleRestartDeployment({ cluster, deployment }: { cluster: KubernetesCluster, deployment: KubernetesDeployment }) {
+ try {
+ const response = await kubernetesService.restartDeployment(cluster.contextName, deployment.metadata.namespace, deployment.metadata.name);
+ if (response.success) {
+ alert(`Deployment ${deployment.metadata.name} restarted successfully`);
+ await this.loadResources();
+ } else {
+ throw new Error(response.msg || 'Unknown error');
+ }
+ } catch (error) {
+ alert(`Error restarting deployment: ${error}`);
+ }
+ },
+
+ async handleRestartStatefulSet({ cluster, statefulSet }: { cluster: KubernetesCluster, statefulSet: KubernetesStatefulSet }) {
+ try {
+ const response = await kubernetesService.restartStatefulSet(cluster.contextName, statefulSet.metadata.namespace, statefulSet.metadata.name);
+ if (response.success) {
+ alert(`StatefulSet ${statefulSet.metadata.name} restarted successfully`);
+ await this.loadResources();
+ } else {
+ throw new Error(response.msg || 'Unknown error');
+ }
+ } catch (error) {
+ alert(`Error restarting statefulset: ${error}`);
+ }
+ },
+
+ handleClusterSelect(cluster: KubernetesCluster) {
+ this.selectedCluster = cluster;
+ this.selectedResource = null;
+ this.deployments = [];
+ this.pods = [];
+ this.statefulSets = [];
+ this.configMaps = [];
+ console.log("selected cluster: " + cluster.contextName);
+ },
+
+ handleResourceSelect(resource: string) {
+ this.selectedResource = resource;
+ this.selectedResourceItem = null; // Reset selected item when changing resource type
+ this.loadResources();
+ },
+
+ handleResourceItemSelect(item: any) {
+ this.selectedResourceItem = item;
+ },
+
+ handleTabChange(tab: 'logs' | 'terminal' | 'describe') {
+ this.selectedTab = tab;
+ },
+
+ async loadResources() {
+ if (!this.selectedCluster || !this.selectedResource) return;
+
+ try {
+ if (this.selectedResource === 'deployments') {
+ try {
+ const response = await kubernetesService.getDeployments(this.selectedCluster.contextName);
+ if (response.success && response.data) {
+ this.deployments = response.data;
+ }
+ } catch (error) {
+ console.error('Failed to load deployments:', error);
+ }
+ } else if (this.selectedResource === 'pods') {
+ // Clear existing pods first
+ this.pods = [];
+ try {
+ const response = await kubernetesService.getPods(this.selectedCluster.contextName);
+ if (response.success && response.data) {
+ this.pods = response.data;
+ }
+ } catch (error) {
+ console.error('Failed to load pods:', error);
+ }
+ } else if (this.selectedResource === 'statefulsets') {
+ try {
+ const response = await kubernetesService.getStatefulSets(this.selectedCluster.contextName);
+ if (response.success && response.data) {
+ this.statefulSets = response.data;
+ }
+ } catch (error) {
+ console.error('Failed to load statefulsets:', error);
+ }
+ } else if (this.selectedResource === 'configmaps') {
+ try {
+ const response = await kubernetesService.getConfigMaps(this.selectedCluster.contextName);
+ if (response.success && response.data) {
+ this.configMaps = response.data;
+ }
+ } catch (error) {
+ console.error('Failed to load configmaps:', error);
+ }
+ } else if (this.selectedResource === 'ingresses') {
+ try {
+ const response = await kubernetesService.getIngresses(this.selectedCluster.contextName);
+ if (response.success && response.data) {
+ this.ingresses = response.data;
+ }
+ } catch (error) {
+ console.error('Failed to load ingresses:', error);
+ }
+ } else if (this.selectedResource === 'namespaces') {
+ try {
+ const response = await kubernetesService.getNamespaces(this.selectedCluster.contextName);
+ if (response.success && response.data) {
+ this.namespaces = response.data;
+ }
+ } catch (error) {
+ console.error('Failed to load namespaces:', error);
+ }
+ } else if (this.selectedResource === 'secrets') {
+ try {
+ const response = await kubernetesService.listSecrets(this.selectedCluster.contextName);
+ if (response.success && response.data) {
+ this.secrets = response.data;
+ }
+ } catch (error) {
+ console.error('Failed to load Secrets:', error);
+ }
+ } else if (this.selectedResource === 'persistentvolumeclaims') {
+ try {
+ const response = await kubernetesService.listPersistentVolumeClaims(this.selectedCluster.contextName);
+ if (response.success && response.data) {
+ this.persistentvolumeclaims = response.data;
+ }
+ } catch (error) {
+ console.error('Failed to load Persistent Volume Claims:', error);
+ }
+ } else if (this.selectedResource === 'persistentVolumes') {
+ try {
+ const response = await kubernetesService.listPersistentVolumes(this.selectedCluster.contextName);
+ if (response.success && response.data) {
+ this.persistentVolumes = response.data;
+ }
+ } catch (error) {
+ console.error('Failed to load Persistent Volumes:', error);
+ }
+
+ try {
+ const response = await kubernetesService.listPersistentVolumeClaims(this.selectedCluster.contextName);
+ if (response.success && response.data) {
+ this.persistentvolumeclaims = response.data;
+ }
+ } catch (error) {
+ console.error('Failed to load Persistent Volume Claims:', error);
+ }
+ }
+ } catch (error) {
+ console.error('Failed to load resources:', error);
+ }
+ },
+ },
+});
+</script>
+
+<template>
+ <div class="app-container">
+ <NavigationPane
+ :clusters="clusters"
+ :selectedCluster="selectedCluster"
+ :selectedResource="selectedResource"
+ @select-cluster="handleClusterSelect"
+ @select-resource="handleResourceSelect"
+ />
+ <div class="right-container">
+ <component
+ :is="currentResourceComponent"
+ :selectedCluster="selectedCluster"
+ :deployments="deployments"
+ :statefulSets="statefulSets"
+ :configMaps="configMaps"
+ :pods="pods"
+ :ingresses="ingresses"
+ :namespaces="namespaces"
+ :secrets="secrets"
+ :persistentvolumeclaims="persistentvolumeclaims"
+ :persistentVolumes="persistentVolumes"
+ @create-namespace="handleCreateNamespace"
+ @create-pod="handleCreatePod"
+ @create-secret="handleCreateSecret"
+ @create-persistentvolume="handleCreatePersistentVolume"
+ @create-persistentvolumeclaim="handleCreatePersistentVolumeClaim"
+ @delete-ingress="handleDeleteIngress"
+ @delete-namespace="handleDeleteNamespace"
+ @delete-pod="handleDeletePod"
+ @delete-secret="handleDeleteSecret"
+ @delete-persistentvolume="handleDeletePersistentVolume"
+ @delete-persistentvolumeclaim="handleDeletePersistentVolumeClaim"
+ @load-resources="loadResources"
+ @restart-deployment="handleRestartDeployment"
+ @restart-statefulset="handleRestartStatefulSet"
+
+ @pod-selected="handlePodSelect"
+ @deployment-selected="handleDeploymentSelect"
+ @configmap-selected="handleConfigMapSelect"
+ @namespace-selected="handleNamespaceSelect"
+ @ingress-selected="handleIngressSelect"
+ @secret-selected="handleSecretSelect"
+ @statefulset-selected="handleStatefulSetSelect"
+ @persistentVolumeClaim-selected="handlePersistentVolumeClaimSelect"
+ @persistentVolume-selected="handlePersistentVolumeSelect"
+
+ @update-secret="handleUpdateSecret"
+ />
+ <BottomTabs
+ v-if="selectedResourceItem"
+ :selectedResource="selectedResourceItem"
+ :selectedCluster="selectedCluster"
+ :selectedTab="selectedTab"
+ @tab-changed="handleTabChange"
+ />
+ </div>
+ </div>
+</template>
+
+<style>
+.app-container {
+ display: flex;
+ height: 100vh;
+ background-color: #1e1e1e;
+ color: #ffffff;
+}
+
+.right-container {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ border-left: 1px solid #333333;
+}
+
+.right-container > :first-child {
+ flex: 1;
+ overflow-y: auto;
+}
+
+.right-container > :last-child {
+ border-top: 1px solid #333333;
+}
+</style>
+/* Style section remains the same as in the previous response */
+.bottom-tabs {
+ display: flex;
+ flex-direction: column;
+ background-color: #1e1e1e;
+ position: relative;
+ min-height: 100px;
+ max-height: 80vh;
+ width: 100%; /* Ensure it takes the full width of its container */
+ overflow: hidden; /* Prevent content from overflowing */
+}
+
+.resize-handle {
+ position: absolute;
+ top: -5px;
+ left: 0;
+ right: 0;
+ height: 10px;
+ cursor: ns-resize;
+ z-index: 10;
+}
+
+.tabs-header {
+ display: flex;
+ justify-content: space-between;
+ background-color: #252526;
+ border-bottom: 1px solid #333333;
+ width: 100%; /* Ensure it takes the full width */
+}
+
+.tabs {
+ display: flex;
+}
+
+.tabs button {
+ padding: 8px 16px;
+ background: none;
+ border: none;
+ color: #cccccc;
+ cursor: pointer;
+ font-size: 13px;
+ border-right: 1px solid #333333;
+ text-align: left;
+}
+
+.tabs button:hover {
+ background-color: #2a2d2e;
+}
+
+.tabs button.active {
+ background-color: #37373d;
+ color: #ffffff;
+}
+
+.tabs-actions {
+ display: flex;
+ align-items: center;
+ padding-right: 8px;
+}
+
+.tabs-actions button {
+ background: none;
+ border: none;
+ color: #cccccc;
+ cursor: pointer;
+ padding: 4px 8px;
+ margin-left: 8px;
+}
+
+.tabs-actions button:hover {
+ background-color: #2a2d2e;
+}
+
+.tabs-actions select {
+ background-color: #3c3c3c;
+ color: #cccccc;
+ border: 1px solid #555555;
+ padding: 4px 8px;
+ margin-left: 8px;
+ border-radius: 2px;
+}
+
+.tab-content {
+ flex: 1;
+ overflow: auto;
+ padding: 8px;
+ font-family: 'Consolas', 'Courier New', monospace;
+ font-size: 13px;
+ width: 100%; /* Ensure it takes the full width */
+ box-sizing: border-box; /* Include padding in width calculation */
+}
+
+.loading, .error, .terminal-placeholder {
+ padding: 16px;
+ color: #cccccc;
+}
+
+.error {
+ color: #f44336;
+}
+
+pre {
+ margin: 0;
+ white-space: pre-wrap; /* Allow text to wrap */
+ word-break: break-all;
+ max-width: 100%; /* Ensure it doesn't exceed container width */
+}
+
+.left-aligned {
+ text-align: left;
+}
+
+.terminal-style {
+ font-family: 'Consolas', 'Courier New', monospace;
+ background-color: #1e1e1e;
+ color: #cccccc;
+ padding: 0;
+ line-height: 1.2;
+ /* Changed from pre to pre-wrap to ensure text wrapping */
+ white-space: pre-wrap;
+ overflow-wrap: break
+}
+.configmaps-container {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ position: relative;
+ overflow: hidden;
+ width: 100%;
+ box-sizing: border-box;
+}
+
+.search-bar-container {
+ flex-shrink: 0;
+ width: 100%;
+ background-color: #2a2a2a;
+ border-bottom: 1px solid #444;
+ z-index: 10;
+ box-sizing: border-box;
+ padding: 0;
+}
+
+.table-scroll-container {
+ flex: 1;
+ overflow-y: auto;
+ overflow-x: hidden;
+ width: 100%;
+ box-sizing: border-box;
+}
+
+.table-container {
+ height: 100%;
+ overflow-y: auto;
+}
+
+table {
+ width: 100%;
+ border-collapse: collapse;
+ font-size: 13px;
+}
+
+th, td {
+ padding: 8px 16px;
+ text-align: left;
+ border-bottom: 1px solid #333333;
+}
+
+th {
+ position: sticky;
+ top: 0;
+ font-weight: 500;
+ color: #858585;
+ background-color: #252526;
+ z-index: 1;
+}
+
+td {
+ color: #cccccc;
+}
+
+tr:hover td {
+ background-color: #2a2d2e;
+}
+
+tr.selected td {
+ background-color: #37373d;
+}
+
+.empty-state {
+ padding: 24px;
+ text-align: center;
+ color: #666;
+ background-color: #f9f9f9;
+ border-radius: 4px;
+ margin-top: 16px;
+}
+.modal-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, 0.7);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 1000;
+}
+
+.modal-content {
+ background-color: #252526;
+ border-radius: 4px;
+ width: 500px;
+ max-width: 90%;
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
+ border: 1px solid #3c3c3c;
+ color: #cccccc;
+}
+
+.modal-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 12px 16px;
+ border-bottom: 1px solid #3c3c3c;
+ background-color: #2a2a2a;
+}
+
+.modal-header h3 {
+ margin: 0;
+ font-size: 16px;
+ font-weight: 500;
+ color: #cccccc;
+}
+
+.close-button {
+ background: none;
+ border: none;
+ font-size: 20px;
+ cursor: pointer;
+ color: #858585;
+ padding: 0;
+ margin: 0;
+ line-height: 1;
+}
+
+.close-button:hover {
+ color: #cccccc;
+}
+
+.modal-body {
+ padding: 16px;
+}
+
+.modal-footer {
+ padding: 12px 16px;
+ border-top: 1px solid #3c3c3c;
+ display: flex;
+ justify-content: flex-end;
+ gap: 8px;
+ background-color: #2a2a2a;
+}
+
+.form-group {
+ margin-bottom: 16px;
+ text-align: left;
+}
+
+.form-group label {
+ display: block;
+ margin-bottom: 6px;
+ font-weight: normal;
+ font-size: 13px;
+ color: #cccccc;
+ text-align: left;
+ width: 100%;
+}
+
+.form-group input {
+ width: 100%;
+ padding: 8px 10px;
+ border: 1px solid #3c3c3c;
+ border-radius: 4px;
+ font-size: 13px;
+ background-color: #1e1e1e;
+ color: #cccccc;
+ box-sizing: border-box;
+}
+
+.form-group input:focus {
+ outline: none;
+ border-color: #0e639c;
+}
+
+.namespace-display {
+ padding: 8px 10px;
+ background-color: #1e1e1e;
+ border: 1px solid #3c3c3c;
+ border-radius: 4px;
+ font-size: 13px;
+ color: #cccccc;
+}
+
+.error-message {
+ color: #f44336;
+ margin-bottom: 12px;
+ padding: 8px 12px;
+ background-color: rgba(244, 67, 54, 0.1);
+ border-radius: 4px;
+ border-left: 3px solid #f44336;
+ font-size: 13px;
+}
+
+.cancel-button {
+ padding: 6px 12px;
+ background-color: #333333;
+ border: 1px solid #3c3c3c;
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 13px;
+ color: #cccccc;
+ min-width: 80px;
+}
+
+.cancel-button:hover {
+ background-color: #3c3c3c;
+}
+
+.create-button {
+ padding: 6px 12px;
+ background-color: #0e639c;
+ color: white;
+ border: none;
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 13px;
+ min-width: 80px;
+}
+
+.create-button:hover {
+ background-color: #1177bb;
+}
+
+.create-button:disabled, .cancel-button:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+
+/* Add placeholder styling to match the dark theme */
+::placeholder {
+ color: #666666;
+ opacity: 1;
+}
+
+.modal-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, 0.7);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 1000;
+}
+
+.modal-content {
+ background-color: #252526;
+ border-radius: 4px;
+ width: 380px; /* Reduced from 500px to match screenshot */
+ max-width: 90%;
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
+ border: 1px solid #3c3c3c;
+ color: #cccccc;
+}
+
+.modal-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 8px 12px;
+ border-bottom: 1px solid #3c3c3c;
+ background-color: #2a2a2a;
+}
+
+.modal-header h3 {
+ margin: 0;
+ font-size: 14px;
+ font-weight: 500;
+ color: #cccccc;
+}
+
+.close-button {
+ background: none;
+ border: none;
+ font-size: 18px;
+ cursor: pointer;
+ color: #858585;
+ padding: 0;
+ margin: 0;
+ line-height: 1;
+}
+
+.close-button:hover {
+ color: #cccccc;
+}
+
+.modal-body {
+ padding: 8px 12px;
+}
+
+.modal-footer {
+ padding: 8px 12px;
+ border-top: 1px solid #3c3c3c;
+ display: flex;
+ justify-content: flex-end;
+ gap: 8px;
+ background-color: #2a2a2a;
+}
+
+.method-option {
+ padding: 6px 8px;
+ cursor: pointer;
+ border-radius: 2px;
+}
+
+.method-option:hover {
+ background-color: #2d2d2d;
+}
+
+.radio-container {
+ display: flex;
+ align-items: flex-start;
+}
+
+.radio-button {
+ margin-right: 8px;
+ margin-top: 2px; /* Align with first line of text */
+}
+
+.radio-outer {
+ width: 14px;
+ height: 14px;
+ border-radius: 50%;
+ border: 1px solid #858585;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.radio-inner {
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ background-color: #0e639c;
+}
+
+.method-text {
+ display: flex;
+ flex-direction: column;
+}
+
+.method-label {
+ font-size: 13px;
+ color: #cccccc;
+ margin-bottom: 2px;
+}
+
+.method-description {
+ font-size: 12px;
+ color: #858585;
+ line-height: 1.3;
+}
+
+.cancel-button {
+ padding: 4px 10px;
+ background-color: #333333;
+ border: 1px solid #3c3c3c;
+ border-radius: 2px;
+ cursor: pointer;
+ font-size: 12px;
+ color: #cccccc;
+ min-width: 70px;
+}
+
+.cancel-button:hover {
+ background-color: #3c3c3c;
+}
+
+.continue-button {
+ padding: 4px 10px;
+ background-color: #0e639c;
+ color: white;
+ border: none;
+ border-radius: 2px;
+ cursor: pointer;
+ font-size: 12px;
+ min-width: 70px;
+}
+
+.continue-button:hover {
+ background-color: #1177bb;
+}
+
+.continue-button:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+
+.modal-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, 0.7);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 1000;
+}
+
+.modal-content {
+ background-color: #252526;
+ border-radius: 4px;
+ width: 500px;
+ max-width: 90%;
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
+ border: 1px solid #3c3c3c;
+ color: #cccccc;
+ display: flex;
+ flex-direction: column;
+ max-height: 90vh;
+ overflow: hidden;
+}
+
+.yaml-editor {
+ width: 600px;
+ max-width: 90%;
+}
+
+.modal-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 8px 12px;
+ border-bottom: 1px solid #3c3c3c;
+ background-color: #2a2a2a;
+ flex-shrink: 0;
+}
+
+.modal-header h3 {
+ margin: 0;
+ font-size: 14px;
+ font-weight: 500;
+ color: #cccccc;
+}
+
+.close-button {
+ background: none;
+ border: none;
+ font-size: 18px;
+ cursor: pointer;
+ color: #858585;
+ padding: 0;
+ margin: 0;
+ line-height: 1;
+}
+
+.close-button:hover {
+ color: #cccccc;
+}
+
+.modal-body {
+ padding: 12px;
+ flex-grow: 1;
+ overflow: auto;
+}
+
+.modal-footer {
+ padding: 8px 12px;
+ border-top: 1px solid #3c3c3c;
+ display: flex;
+ justify-content: flex-end;
+ gap: 8px;
+ background-color: #2a2a2a;
+ flex-shrink: 0;
+}
+
+.yaml-container {
+ width: 100%;
+ height: 300px;
+ position: relative;
+}
+
+.yaml-textarea {
+ width: 100%;
+ height: 100%;
+ padding: 10px;
+ border: 1px solid #3c3c3c;
+ border-radius: 2px;
+ font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
+ font-size: 13px;
+ line-height: 1.5;
+ resize: none;
+ background-color: #1e1e1e;
+ color: #cccccc;
+ box-sizing: border-box;
+ overflow: auto;
+}
+
+.yaml-textarea:focus {
+ outline: none;
+ border-color: #0e639c;
+}
+
+.error-message {
+ color: #f44336;
+ margin-bottom: 12px;
+ padding: 8px 12px;
+ background-color: rgba(244, 67, 54, 0.1);
+ border-radius: 2px;
+ border-left: 3px solid #f44336;
+ font-size: 13px;
+}
+
+.cancel-button {
+ padding: 4px 10px;
+ background-color: #333333;
+ border: 1px solid #3c3c3c;
+ border-radius: 2px;
+ cursor: pointer;
+ font-size: 12px;
+ color: #cccccc;
+ min-width: 70px;
+}
+
+.cancel-button:hover {
+ background-color: #3c3c3c;
+}
+
+.create-button {
+ padding: 4px 10px;
+ background-color: #0e639c;
+ color: white;
+ border: none;
+ border-radius: 2px;
+ cursor: pointer;
+ font-size: 12px;
+ min-width: 70px;
+}
+
+.create-button:hover {
+ background-color: #1177bb;
+}
+
+.create-button:disabled, .cancel-button:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+
+/* Add placeholder styling to match the dark theme */
+.yaml-textarea::placeholder {
+ color: #666666;
+ opacity: 1;
+}
+.modal-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, 0.7);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 1000;
+}
+
+.modal-content {
+ background-color: #252526;
+ border-radius: 4px;
+ width: 380px; /* Reduced from 500px to match screenshot */
+ max-width: 90%;
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
+ border: 1px solid #3c3c3c;
+ color: #cccccc;
+}
+
+.modal-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 8px 12px;
+ border-bottom: 1px solid #3c3c3c;
+ background-color: #2a2a2a;
+}
+
+.modal-header h3 {
+ margin: 0;
+ font-size: 14px;
+ font-weight: 500;
+ color: #cccccc;
+}
+
+.method-option {
+ padding: 6px 8px;
+ cursor: pointer;
+ border-radius: 2px;
+}
+
+.method-option:hover {
+ background-color: #2d2d2d;
+}
+
+.method-text {
+ display: flex;
+ flex-direction: column;
+}
+
+.method-label {
+ font-size: 13px;
+ color: #cccccc;
+ margin-bottom: 2px;
+}
+
+.method-description {
+ font-size: 12px;
+ color: #858585;
+ line-height: 1.3;
+}
+
+.radio-container {
+ display: flex;
+ align-items: flex-start;
+}
+
+.radio-button {
+ margin-right: 8px;
+ margin-top: 2px;
+}
+
+.radio-outer {
+ width: 14px;
+ height: 14px;
+ border-radius: 50%;
+ border: 1px solid #858585;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.radio-inner {
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ background-color: #0e639c;
+}
+
+.close-button {
+ background: none;
+ border: none;
+ font-size: 20px;
+ cursor: pointer;
+ color: #858585;
+ padding: 0;
+ margin: 0;
+ line-height: 1;
+}
+
+.close-button:hover {
+ color: #cccccc;
+}
+
+.modal-body {
+ padding: 16px;
+}
+
+.modal-footer {
+ padding: 12px 16px;
+ border-top: 1px solid #3c3c3c;
+ display: flex;
+ justify-content: flex-end;
+ gap: 8px;
+ background-color: #2a2a2a;
+}
+
+.form-group {
+ margin-bottom: 16px;
+ text-align: left;
+}
+
+.form-group label {
+ display: block;
+ margin-bottom: 6px;
+ font-weight: normal;
+ font-size: 13px;
+ color: #cccccc;
+ text-align: left;
+ width: 100%;
+}
+
+.form-group input {
+ width: 100%;
+ padding: 8px 10px;
+ border: 1px solid #3c3c3c;
+ border-radius: 4px;
+ font-size: 13px;
+ background-color: #1e1e1e;
+ color: #cccccc;
+ box-sizing: border-box;
+}
+
+.form-group input:focus {
+ outline: none;
+ border-color: #0e639c;
+}
+
+.namespace-display {
+ padding: 8px 10px;
+ background-color: #1e1e1e;
+ border: 1px solid #3c3c3c;
+ border-radius: 4px;
+ font-size: 13px;
+ color: #cccccc;
+}
+
+.error-message {
+ color: #f44336;
+ margin-bottom: 12px;
+ padding: 8px 12px;
+ background-color: rgba(244, 67, 54, 0.1);
+ border-radius: 4px;
+ border-left: 3px solid #f44336;
+ font-size: 13px;
+}
+
+.cancel-button {
+ padding: 6px 12px;
+ background-color: #333333;
+ border: 1px solid #3c3c3c;
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 13px;
+ color: #cccccc;
+ min-width: 80px;
+}
+
+.cancel-button:hover {
+ background-color: #3c3c3c;
+}
+
+.create-button {
+ padding: 6px 12px;
+ background-color: #0e639c;
+ color: white;
+ border: none;
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 13px;
+ min-width: 80px;
+}
+
+.create-button:hover {
+ background-color: #1177bb;
+}
+
+.create-button:disabled, .cancel-button:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+
+.continue-button {
+ padding: 4px 10px;
+ background-color: #0e639c;
+ color: white;
+ border: none;
+ border-radius: 2px;
+ cursor: pointer;
+ font-size: 12px;
+ min-width: 70px;
+}
+
+.continue-button:hover {
+ background-color: #1177bb;
+}
+
+.continue-button:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+
+/* Add placeholder styling to match the dark theme */
+::placeholder {
+ color: #666666;
+ opacity: 1;
+}
+
+.checkbox-label {
+ display: flex;
+ align-items: center;
+ cursor: pointer;
+ color: #cccccc;
+ font-size: 13px;
+ width: auto;
+ margin-bottom: 0;
+}
+
+.checkbox-label input {
+ margin-right: 8px;
+ cursor: pointer;
+ line-height: normal;
+}
+
+/*
+ This selector is more specific than .form-group label
+ It ensures the checkbox label doesn't behave like a block element
+*/
+.form-group .checkbox-label {
+ display: flex !important;
+ align-items: center;
+ width: auto !important; /* Critical: overrides width: 100% from .form-group label */
+ color: #cccccc;
+ font-size: 13px;
+ margin-bottom: 0;
+}
+
+/*
+ This ensures the checkbox shrinks to its natural size
+ instead of stretching to fill the parent container
+*/
+.form-group .checkbox-label input {
+ width: auto !important; /* Critical: overrides width: 100% from .form-group input */
+ margin-right: 8px;
+ cursor: pointer;
+ padding: 0; /* Reset padding just in case */
+ border: none; /* Reset border just in case */
+ background: none; /* Reset background just in case */
+}
+.deployments-container {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ position: relative;
+ overflow: hidden;
+ width: 100%; /* Ensure container takes full width */
+ box-sizing: border-box; /* Include padding in width calculation */
+}
+
+.search-bar-container {
+ flex-shrink: 0;
+ width: 100%;
+ background-color: #2a2a2a;
+ border-bottom: 1px solid #444;
+ z-index: 10;
+ box-sizing: border-box; /* Include padding in width calculation */
+ padding: 0; /* Remove any padding that might be causing overflow */
+}
+
+.table-scroll-container {
+ flex: 1;
+ overflow-y: auto;
+ overflow-x: hidden;
+ width: 100%;
+ box-sizing: border-box;
+}
+
+
+/* Keep your existing table styles */
+.table-container {
+ height: 100%;
+ overflow-y: auto;
+}
+
+table {
+ width: 100%;
+ border-collapse: collapse;
+ font-size: 13px;
+}
+
+th, td {
+ padding: 8px 16px;
+ text-align: left;
+ border-bottom: 1px solid #333333;
+}
+
+th {
+ position: sticky;
+ top: 0;
+ font-weight: 500;
+ color: #858585;
+ background-color: #252526;
+ z-index: 1;
+}
+
+td {
+ color: #cccccc;
+}
+
+tr:hover td {
+ background-color: #2a2d2e;
+}
+
+tr.selected td {
+ background-color: #37373d;
+}
+
+/* Context Menu Styles */
+.context-menu {
+ position: fixed;
+ background-color: #252526;
+ border: 1px solid #333333;
+ border-radius: 4px;
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
+ z-index: 1000;
+ min-width: 150px;
+}
+
+.menu-item {
+ padding: 8px 12px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.menu-item:hover {
+ background-color: #2a2d2e;
+}
+
+.menu-icon {
+ font-size: 16px;
+}
+
+.menu-text {
+ font-size: 14px;
+}
+
+/* Add this to your existing DeploymentsList.css */
+.empty-state {
+ padding: 24px;
+ text-align: center;
+ color: #666;
+ background-color: #f9f9f9;
+ border-radius: 4px;
+ margin-top: 16px;
+}
+.modal-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, 0.7);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 1000;
+}
+
+.modal-content {
+ background-color: #252526;
+ border-radius: 4px;
+ width: 500px;
+ max-width: 90%;
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
+ border: 1px solid #3c3c3c;
+ color: #cccccc;
+ display: flex;
+ flex-direction: column;
+ max-height: 90vh;
+ overflow: hidden;
+}
+
+.yaml-editor {
+ width: 600px;
+ max-width: 90%;
+}
+
+.modal-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 8px 12px;
+ border-bottom: 1px solid #3c3c3c;
+ background-color: #2a2a2a;
+ flex-shrink: 0;
+}
+
+.modal-header h3 {
+ margin: 0;
+ font-size: 14px;
+ font-weight: 500;
+ color: #cccccc;
+}
+
+.close-button {
+ background: none;
+ border: none;
+ font-size: 18px;
+ cursor: pointer;
+ color: #858585;
+ padding: 0;
+ margin: 0;
+ line-height: 1;
+}
+
+.close-button:hover {
+ color: #cccccc;
+}
+
+.modal-body {
+ padding: 12px;
+ flex-grow: 1;
+ overflow: auto;
+}
+
+.modal-footer {
+ padding: 8px 12px;
+ border-top: 1px solid #3c3c3c;
+ display: flex;
+ justify-content: flex-end;
+ gap: 8px;
+ background-color: #2a2a2a;
+ flex-shrink: 0;
+}
+
+.yaml-container {
+ width: 100%;
+ height: 300px;
+ position: relative;
+}
+
+.yaml-textarea {
+ width: 100%;
+ height: 100%;
+ padding: 10px;
+ border: 1px solid #3c3c3c;
+ border-radius: 2px;
+ font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
+ font-size: 13px;
+ line-height: 1.5;
+ resize: none;
+ background-color: #1e1e1e;
+ color: #cccccc;
+ box-sizing: border-box;
+ overflow: auto;
+}
+
+.yaml-textarea:focus {
+ outline: none;
+ border-color: #0e639c;
+}
+
+.error-message {
+ color: #f44336;
+ margin-bottom: 12px;
+ padding: 8px 12px;
+ background-color: rgba(244, 67, 54, 0.1);
+ border-radius: 2px;
+ border-left: 3px solid #f44336;
+ font-size: 13px;
+}
+
+.loading-message {
+ color: #42a5f5;
+ margin-bottom: 12px;
+ padding: 8px 12px;
+ background-color: rgba(66, 165, 245, 0.1);
+ border-radius: 2px;
+ border-left: 3px solid #42a5f5;
+ font-size: 13px;
+ text-align: center;
+}
+
+.cancel-button {
+ padding: 4px 10px;
+ background-color: #333333;
+ border: 1px solid #3c3c3c;
+ border-radius: 2px;
+ cursor: pointer;
+ font-size: 12px;
+ color: #cccccc;
+ min-width: 70px;
+}
+
+.cancel-button:hover {
+ background-color: #3c3c3c;
+}
+
+.update-button {
+ padding: 4px 10px;
+ background-color: #0e639c;
+ color: white;
+ border: none;
+ border-radius: 2px;
+ cursor: pointer;
+ font-size: 12px;
+ min-width: 70px;
+}
+
+.update-button:hover {
+ background-color: #1177bb;
+}
+
+.update-button:disabled, .cancel-button:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+
+/* Add placeholder styling to match the dark theme */
+.yaml-textarea::placeholder {
+ color: #666666;
+ opacity: 1;
+}
+
+.ingresses-container {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ position: relative;
+ overflow: hidden;
+ width: 100%;
+ box-sizing: border-box;
+}
+
+.search-bar-container {
+ flex-shrink: 0;
+ width: 100%;
+ background-color: #2a2a2a;
+ border-bottom: 1px solid #444;
+ z-index: 10;
+ box-sizing: border-box;
+ padding: 0;
+}
+
+.table-scroll-container {
+ flex: 1;
+ overflow-y: auto;
+ overflow-x: hidden;
+ width: 100%;
+ box-sizing: border-box;
+}
+
+.table-container {
+ height: 100%;
+ overflow-y: auto;
+}
+
+table {
+ width: 100%;
+ border-collapse: collapse;
+ font-size: 13px;
+}
+
+th, td {
+ padding: 8px 16px;
+ text-align: left;
+ border-bottom: 1px solid #333333;
+}
+
+th {
+ position: sticky;
+ top: 0;
+ font-weight: 500;
+ color: #858585;
+ background-color: #252526;
+ z-index: 1;
+}
+
+td {
+ color: #cccccc;
+}
+
+tr:hover td {
+ background-color: #2a2d2e;
+}
+
+tr.selected td {
+ background-color: #37373d;
+}
+
+.empty-state {
+ padding: 24px;
+ text-align: center;
+ color: #666;
+ background-color: #f9f9f9;
+ border-radius: 4px;
+ margin-top: 16px;
+}
+
+.context-menu {
+ position: fixed;
+ background-color: #252526;
+ border: 1px solid #3c3c3c;
+ border-radius: 4px;
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
+ z-index: 1000;
+ min-width: 120px;
+}
+
+.menu-item {
+ padding: 8px 12px;
+ cursor: pointer;
+ color: #cccccc;
+ font-size: 13px;
+ text-align: left;
+}
+
+.menu-item:hover {
+ background-color: #2a2d2e;
+}
+
+.menu-item.disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+
+.menu-error {
+ padding: 8px 12px;
+ color: #f44336;
+ font-size: 12px;
+ border-top: 1px solid #3c3c3c;
+ max-width: 200px;
+ word-break: break-word;
+}
+.configmaps-container {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ position: relative;
+ overflow: hidden;
+ width: 100%;
+ box-sizing: border-box;
+}
+
+.search-bar-container {
+ flex-shrink: 0;
+ width: 100%;
+ background-color: #2a2a2a;
+ border-bottom: 1px solid #444;
+ z-index: 10;
+ box-sizing: border-box;
+ padding: 0;
+}
+
+.table-scroll-container {
+ flex: 1;
+ overflow-y: auto;
+ overflow-x: hidden;
+ width: 100%;
+ box-sizing: border-box;
+}
+
+.table-container {
+ height: 100%;
+ overflow-y: auto;
+}
+
+table {
+ width: 100%;
+ border-collapse: collapse;
+ font-size: 13px;
+}
+
+th, td {
+ padding: 8px 16px;
+ text-align: left;
+ border-bottom: 1px solid #333333;
+}
+
+th {
+ position: sticky;
+ top: 0;
+ font-weight: 500;
+ color: #858585;
+ background-color: #252526;
+ z-index: 1;
+}
+
+td {
+ color: #cccccc;
+}
+
+tr:hover td {
+ background-color: #2a2d2e;
+}
+
+tr.selected td {
+ background-color: #37373d;
+}
+
+.empty-state {
+ padding: 24px;
+ text-align: center;
+ color: #666;
+ background-color: #f9f9f9;
+ border-radius: 4px;
+ margin-top: 16px;
+}
+.context-menu {
+ position: fixed;
+ background-color: #252526;
+ border: 1px solid #333333;
+ border-radius: 4px;
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
+ z-index: 1000;
+ min-width: 150px;
+}
+
+.menu-item {
+ padding: 8px 12px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ color: #cccccc;
+ font-size: 13px;
+ text-align: left;
+}
+
+.menu-item:hover {
+ background-color: #2a2d2e;
+}
+
+.menu-icon {
+ font-size: 16px;
+}
+
+.menu-item.disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+
+.menu-text {
+ font-size: 14px;
+}
+
+.menu-error {
+ padding: 8px 12px;
+ color: #f44336;
+ font-size: 12px;
+ border-top: 1px solid #3c3c3c;
+ max-width: 200px;
+ word-break: break-word;
+}
+
+.empty-state {
+ padding: 24px;
+ text-align: center;
+ color: #666;
+ background-color: #f9f9f9;
+ border-radius: 4px;
+ margin-top: 16px;
+}
+
+.status-active {
+ color: #4caf50;
+}
+
+.status-terminating {
+ color: #f44336;
+}
+
+.status-unknown {
+ color: #9e9e9e;
+}
+
+.status-failed {
+ color: #f44336;
+}
+
+.status-unknown {
+ color: #9e9e9e;
+}
+.modal-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, 0.7);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 1000;
+}
+
+.modal-content {
+ background-color: #252526;
+ border-radius: 4px;
+ width: 500px;
+ max-width: 90%;
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
+ border: 1px solid #3c3c3c;
+ color: #cccccc;
+ display: flex;
+ flex-direction: column;
+ max-height: 90vh;
+ overflow: hidden;
+}
+
+.yaml-editor {
+ width: 600px;
+ max-width: 90%;
+}
+
+.modal-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 8px 12px;
+ border-bottom: 1px solid #3c3c3c;
+ background-color: #2a2a2a;
+ flex-shrink: 0;
+}
+
+.modal-header h3 {
+ margin: 0;
+ font-size: 16px;
+ font-weight: 500;
+ color: #cccccc;
+}
+
+.close-button {
+ background: none;
+ border: none;
+ font-size: 20px;
+ cursor: pointer;
+ color: #858585;
+ padding: 0;
+ margin: 0;
+ line-height: 1;
+}
+
+.close-button:hover {
+ color: #cccccc;
+}
+
+.modal-body {
+ padding: 16px;
+ flex-grow: 1;
+ overflow: auto;
+}
+
+.modal-footer {
+ padding: 12px 16px;
+ border-top: 1px solid #3c3c3c;
+ display: flex;
+ justify-content: flex-end;
+ gap: 8px;
+ background-color: #2a2a2a;
+ flex-shrink: 0;
+}
+
+.yaml-container {
+ width: 100%;
+ height: 300px;
+ position: relative;
+}
+
+.form-group {
+ margin-bottom: 16px;
+ text-align: left;
+}
+
+.form-group label {
+ display: block;
+ margin-bottom: 6px;
+ font-weight: normal;
+ font-size: 13px;
+ color: #cccccc;
+ text-align: left;
+ width: 100%;
+}
+
+.form-group input {
+ width: 100%;
+ padding: 8px 10px;
+ border: 1px solid #3c3c3c;
+ border-radius: 4px;
+ font-size: 13px;
+ background-color: #1e1e1e;
+ color: #cccccc;
+ box-sizing: border-box;
+}
+
+.form-group input:focus {
+ outline: none;
+ border-color: #0e639c;
+}
+
+.namespace-display {
+ padding: 8px 10px;
+ background-color: #1e1e1e;
+ border: 1px solid #3c3c3c;
+ border-radius: 4px;
+ font-size: 13px;
+ color: #cccccc;
+}
+
+.error-message {
+ color: #f44336;
+ margin-bottom: 12px;
+ padding: 8px 12px;
+ background-color: rgba(244, 67, 54, 0.1);
+ border-radius: 4px;
+ border-left: 3px solid #f44336;
+ font-size: 13px;
+}
+
+.cancel-button {
+ padding: 6px 12px;
+ background-color: #333333;
+ border: 1px solid #3c3c3c;
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 13px;
+ color: #cccccc;
+ min-width: 80px;
+}
+
+.cancel-button:hover {
+ background-color: #3c3c3c;
+}
+
+.update-button {
+ padding: 6px 12px;
+ background-color: #0e639c;
+
+ border: 1px solid #3c3c3c;
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 13px;
+ color: #cccccc;
+ min-width: 80px;
+}
+
+.update-button:hover {
+ background-color: #3c3c3c;
+}
+
+.update-button:disabled, .cancel-button:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+
+.create-button {
+ padding: 6px 12px;
+ background-color: #0e639c;
+ color: white;
+ border: none;
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 13px;
+ min-width: 80px;
+}
+
+.create-button:hover {
+ background-color: #1177bb;
+}
+
+.create-button:disabled, .cancel-button:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+
+::placeholder {
+ color: #666666;
+ opacity: 1;
+}
+
+.yaml-textarea {
+ width: 100%;
+ height: 100%;
+ padding: 10px;
+ border: 1px solid #3c3c3c;
+ border-radius: 2px;
+ font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
+ font-size: 13px;
+ line-height: 1.5;
+ resize: none;
+ background-color: #1e1e1e;
+ color: #cccccc;
+ box-sizing: border-box;
+ overflow: auto;
+}
+
+.yaml-textarea:focus {
+ outline: none;
+ border-color: #0e639c;
+}
+
+.yaml-textarea::placeholder {
+ color: #666666;
+ opacity: 1;
+}
+
+.loading-message {
+ color: #42a5f5;
+ margin-bottom: 12px;
+ padding: 8px 12px;
+ background-color: rgba(66, 165, 245, 0.1);
+ border-radius: 2px;
+ border-left: 3px solid #42a5f5;
+ font-size: 13px;
+ text-align: center;
+}
+.namespaces-container {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ position: relative;
+ overflow: hidden;
+ width: 100%;
+ box-sizing: border-box;
+}
+
+.search-bar-container {
+ flex-shrink: 0;
+ width: 100%;
+ background-color: #2a2a2a;
+ border-bottom: 1px solid #444;
+ z-index: 10;
+ box-sizing: border-box; /* Include padding in width calculation */
+ padding: 0; /* Remove any padding that might be causing overflow */
+}
+
+.table-scroll-container {
+ flex: 1;
+ overflow-y: auto;
+ overflow-x: hidden;
+ width: 100%;
+ box-sizing: border-box;
+}
+
+.no-namespaces {
+ padding: 20px;
+ text-align: center;
+ color: #cccccc;
+}
+
+table {
+ width: 100%;
+ border-collapse: collapse;
+ font-size: 13px;
+}
+
+th, td {
+ padding: 8px 16px;
+ text-align: left;
+ border-bottom: 1px solid #333333;
+}
+
+th {
+ position: sticky;
+ top: 0;
+ font-weight: 500;
+ color: #858585;
+ background-color: #252526;
+ z-index: 1;
+}
+
+td {
+ color: #cccccc;
+}
+
+tr:hover td {
+ background-color: #2a2d2e;
+}
+
+tr.selected td {
+ background-color: #37373d;
+}
+
+.status-active {
+ color: #4caf50;
+}
+
+.status-terminating {
+ color: #f44336;
+}
+
+.status-unknown {
+ color: #9e9e9e;
+}
+
+.status-failed {
+ color: #f44336;
+}
+
+.status-unknown {
+ color: #9e9e9e;
+}
+
+.context-menu {
+ position: fixed;
+ background-color: #252526;
+ border: 1px solid #3c3c3c;
+ border-radius: 4px;
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
+ z-index: 1000;
+ min-width: 120px;
+}
+
+.menu-item {
+ padding: 8px 12px;
+ cursor: pointer;
+ color: #cccccc;
+ font-size: 13px;
+ text-align: left;
+}
+
+.menu-item:hover {
+ background-color: #2a2d2e;
+}
+
+.menu-item.disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+
+.menu-error {
+ padding: 8px 12px;
+ color: #f44336;
+ font-size: 12px;
+ border-top: 1px solid #3c3c3c;
+ max-width: 200px;
+ word-break: break-word;
+}
+.nav-pane {
+ width: 250px;
+ background-color: #252526;
+ height: 100%;
+ overflow-y: auto;
+}
+
+.nav-section {
+ margin-bottom: 1rem;
+}
+
+.section-header {
+ padding: 8px 16px;
+ background-color: #333333;
+ height: 55px; /* Increased to match search container + divider */
+ display: flex;
+ align-items: center;
+ box-sizing: border-box;
+ border-bottom: 1px solid #444; /* Added divider to match search container */
+}
+
+.section-title {
+ font-size: 12px;
+ font-weight: 500;
+ color: #858585;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+}
+
+.section-content {
+ padding: 8px 0;
+}
+
+.nav-item {
+ padding: 8px 16px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ color: #cccccc;
+}
+
+.nav-item:hover {
+ background-color: #2a2d2e;
+}
+
+.nav-item.active {
+ background-color: #37373d;
+ color: #ffffff;
+}
+
+.nav-item i {
+ width: 16px;
+ text-align: center;
+ font-size: 14px;
+}
+
+/*
+ * NOTE(rene): generated from LLM inline with vuejs. I've split these out into
+ * dedicated PersistentVolume.css file but will pick and choose resources to
+ * copy back into CreateResource.css.
+ */
+.guided-creator {
+ max-width: 800px;
+ width: 95vw;
+ max-height: 90vh;
+ overflow-y: auto;
+}
+
+.volume-type-selector {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
+ gap: 1rem;
+ margin-bottom: 1rem;
+}
+
+.volume-type-option {
+ border: 2px solid #444;
+ border-radius: 8px;
+ padding: 1rem;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ background-color: #2d2d2d;
+}
+
+.volume-type-option:hover {
+ border-color: #007acc;
+ background-color: #333;
+}
+
+.volume-type-option.selected {
+ border-color: #007acc;
+ background-color: #1a3a5c;
+}
+
+.type-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 0.5rem;
+}
+
+.type-name {
+ font-weight: 600;
+ color: #ffffff;
+}
+
+.type-badge {
+ padding: 0.25rem 0.5rem;
+ border-radius: 12px;
+ font-size: 0.75rem;
+ font-weight: 500;
+ text-transform: uppercase;
+}
+
+.type-badge.local {
+ background-color: #28a745;
+ color: white;
+}
+
+.type-badge.network {
+ background-color: #007acc;
+ color: white;
+}
+
+.type-badge.cloud {
+ background-color: #6f42c1;
+ color: white;
+}
+
+.type-description {
+ color: #ccc;
+ font-size: 0.9rem;
+ margin: 0;
+ line-height: 1.4;
+}
+
+.volume-config {
+ background-color: #333;
+ border: 1px solid #444;
+ border-radius: 6px;
+ padding: 1rem;
+}
+
+.storage-input-group {
+ display: flex;
+ gap: 0.5rem;
+}
+
+.storage-input-group input {
+ flex: 1;
+}
+
+.storage-input-group select {
+ width: 80px;
+ padding: 0.5rem;
+ border: 1px solid #444;
+ border-radius: 4px;
+ background-color: #2d2d2d;
+ color: #ffffff;
+}
+
+.subsection {
+ margin-bottom: 1.5rem;
+}
+
+.subsection:last-child {
+ margin-bottom: 0;
+}
+
+.subsection h5 {
+ margin: 0 0 0.75rem 0;
+ color: #ffffff;
+ font-size: 1rem;
+}
+
+.checkbox-group,
+.radio-group {
+ display: flex;
+ flex-direction: column;
+ gap: 0.75rem;
+}
+
+.checkbox-label,
+.radio-label {
+ display: flex;
+ flex-direction: column;
+ gap: 0.25rem;
+ cursor: pointer;
+}
+
+.checkbox-label input,
+.radio-label input {
+ width: auto;
+ margin-right: 0.5rem;
+}
+
+.label-row {
+ display: flex;
+ gap: 0.5rem;
+ align-items: flex-start;
+ margin-bottom: 0.5rem;
+}
+
+.key-field,
+.value-field {
+ flex: 1;
+ margin-bottom: 0;
+}
+
+.remove-button {
+ background-color: #dc3545;
+ border: 1px solid #dc3545;
+ color: white;
+ border-radius: 4px;
+ width: 30px;
+ height: 30px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-top: 1.5rem;
+}
+
+.remove-button:hover:not(:disabled) {
+ background-color: #c82333;
+}
+
+.remove-button:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+}
+
+.add-button {
+ background-color: #28a745;
+ border: 1px solid #28a745;
+ color: white;
+ padding: 0.5rem 1rem;
+ border-radius: 4px;
+ cursor: pointer;
+ margin-top: 0.5rem;
+}
+
+.add-button:hover:not(:disabled) {
+ background-color: #218838;
+}
+
+.add-button:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+}
+
+/* Responsive design */
+@media (max-width: 768px) {
+ .volume-type-selector {
+ grid-template-columns: 1fr;
+ }
+
+ .label-row {
+ flex-direction: column;
+ gap: 0.25rem;
+ }
+
+ .remove-button {
+ margin-top: 0.5rem;
+ align-self: flex-start;
+ }
+}
+.pods-container {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ position: relative;
+ overflow: hidden;
+ width: 100%; /* Ensure container takes full width */
+ box-sizing: border-box; /* Include padding in width calculation */
+}
+
+.search-bar-container {
+ flex-shrink: 0;
+ width: 100%;
+ background-color: #2a2a2a;
+ border-bottom: 1px solid #444;
+ z-index: 10;
+ box-sizing: border-box; /* Include padding in width calculation */
+ padding: 0; /* Remove any padding that might be causing overflow */
+}
+
+.table-scroll-container {
+ flex: 1;
+ overflow-y: auto;
+ overflow-x: hidden;
+ width: 100%;
+ box-sizing: border-box;
+}
+
+.no-pods {
+ padding: 20px;
+ text-align: center;
+ color: #cccccc;
+}
+
+.table-container {
+ height: 100%;
+ overflow-y: auto;
+}
+
+table {
+ width: 100%;
+ border-collapse: collapse;
+ font-size: 13px;
+}
+
+th, td {
+ padding: 8px 16px;
+ text-align: left;
+ border-bottom: 1px solid #333333;
+}
+
+th {
+ position: sticky;
+ top: 0;
+ font-weight: 500;
+ color: #858585;
+ background-color: #252526;
+ z-index: 1;
+}
+
+td {
+ color: #cccccc;
+}
+
+tr:hover td {
+ background-color: #2a2d2e;
+}
+
+tr.selected td {
+ background-color: #37373d;
+}
+
+.status-running {
+ color: #4caf50;
+}
+
+.status-pending {
+ color: #ff9800;
+}
+
+.status-succeeded {
+ color: #2196f3;
+}
+
+.status-failed {
+ color: #f44336;
+}
+
+.status-unknown {
+ color: #9e9e9e;
+}
+
+.context-menu {
+ position: fixed;
+ background-color: #252526;
+ border: 1px solid #3c3c3c;
+ border-radius: 4px;
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
+ z-index: 1000;
+ min-width: 120px;
+}
+
+.menu-item {
+ padding: 8px 12px;
+ cursor: pointer;
+ color: #cccccc;
+ font-size: 13px;
+ text-align: left;
+}
+
+.menu-item:hover {
+ background-color: #2a2d2e;
+}
+
+.menu-item.disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+
+.menu-error {
+ padding: 8px 12px;
+ color: #f44336;
+ font-size: 12px;
+ border-top: 1px solid #3c3c3c;
+ max-width: 200px;
+ word-break: break-word;
+}
+/* SearchBar.css */
+/* Update in SearchBar.css */
+.search-container {
+ width: 100%;
+ padding: 8px;
+ background-color: #2a2a2a;
+ box-sizing: border-box; /* Include padding in width calculation */
+ max-width: 100%; /* Ensure it doesn't exceed parent width */
+ overflow: hidden; /* Prevent overflow */
+}
+
+.search-input-wrapper {
+ position: relative;
+ width: 100%;
+ display: flex;
+ align-items: center;
+ box-sizing: border-box;
+}
+
+.search-input {
+ width: 100%;
+ padding: 8px 32px 8px 12px;
+ font-size: 14px;
+ border: 1px solid #444;
+ border-radius: 4px;
+ outline: none;
+ transition: border-color 0.2s, box-shadow 0.2s;
+ background-color: #333;
+ color: #e0e0e0;
+ box-sizing: border-box; /* Include padding in width calculation */
+}
+
+.search-input:focus {
+ border-color: #4a90e2; /* Blue highlight when focused */
+ box-shadow: 0 0 0 2px rgba(74, 144, 226, 0.2);
+}
+
+.search-input::placeholder {
+ color: #888; /* Lighter placeholder text */
+}
+
+.clear-button {
+ position: absolute;
+ right: 8px;
+ background: none;
+ border: none;
+ font-size: 18px;
+ color: #888;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 24px;
+ height: 24px;
+ border-radius: 50%;
+}
+
+.clear-button:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ color: #ccc;
+}
+.statefulsets-container {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ position: relative;
+ overflow: hidden;
+ width: 100%;
+ box-sizing: border-box;
+}
+
+.search-bar-container {
+ flex-shrink: 0;
+ width: 100%;
+ background-color: #2a2a2a;
+ border-bottom: 1px solid #444;
+ z-index: 10;
+ box-sizing: border-box;
+ padding: 0;
+}
+
+.table-scroll-container {
+ flex: 1;
+ overflow-y: auto;
+ overflow-x: hidden;
+ width: 100%;
+ box-sizing: border-box;
+}
+
+.table-container {
+ height: 100%;
+ overflow-y: auto;
+}
+
+table {
+ width: 100%;
+ border-collapse: collapse;
+ font-size: 13px;
+}
+
+th, td {
+ padding: 8px 16px;
+ text-align: left;
+ border-bottom: 1px solid #333333;
+}
+
+th {
+ position: sticky;
+ top: 0;
+ font-weight: 500;
+ color: #858585;
+ background-color: #252526;
+ z-index: 1;
+}
+
+td {
+ color: #cccccc;
+}
+
+tr:hover td {
+ background-color: #2a2d2e;
+}
+
+tr.selected td {
+ background-color: #37373d;
+}
+
+.context-menu {
+ position: fixed;
+ background-color: #252526;
+ border: 1px solid #333333;
+ border-radius: 4px;
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
+ z-index: 1000;
+ min-width: 150px;
+}
+
+.menu-item {
+ padding: 8px 12px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.menu-item:hover {
+ background-color: #2a2d2e;
+}
+
+.menu-icon {
+ font-size: 16px;
+}
+
+.menu-text {
+ font-size: 14px;
+}
+
+.empty-state {
+ padding: 24px;
+ text-align: center;
+ color: #666;
+ background-color: #f9f9f9;
+ border-radius: 4px;
+ margin-top: 16px;
+}
+Copyright 2016 The Nunito Project Authors (contact@sansoxygen.com),
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
+<script lang="ts">
+import { defineComponent, PropType, ref, watch, nextTick } from 'vue';
+import { KubernetesCluster } from '../types/kubernetes';
+import { formatResourceDescription } from '../lib/lib';
+import { PodTerminal, TerminalOptions } from '../lib/terminal';
+import { logsService } from '../lib/logs';
+import { type KubernetesResourceKind, getResourceKind, isPod, isDeployment, isStatefulSet, isConfigMap } from '../lib/resources';
+import { kubernetesService } from '../lib/kubernetes';
+
+export default defineComponent({
+ name: 'BottomTabs',
+
+ props: {
+ selectedResource: {
+ type: Object as PropType<any>,
+ required: true
+ },
+ selectedCluster: {
+ type: Object as PropType<KubernetesCluster | null>,
+ required: true
+ },
+ selectedTab: {
+ type: String as PropType<'describe' | 'logs' | 'terminal'>,
+ required: true
+ }
+ },
+
+ emits: ['tab-changed'],
+
+ data() {
+ return {
+ logs: '',
+ description: '',
+ loading: false,
+ error: '',
+ isPod: false,
+ isDeployment: false,
+ isStatefulSet: false,
+ isConfigMap: false,
+ tailLines: 100,
+ selectedContainer: '',
+ containers: [] as string[],
+ panelHeight: 300, // Default height in pixels
+ isResizing: false,
+ startY: 0,
+ startHeight: 0,
+ // Terminal-related properties
+ podTerminal: null as PodTerminal | null,
+ terminalError: '',
+ // Reference to the logs container
+ logsContainerRef: null as HTMLElement | null,
+ resourceKind: null as KubernetesResourceKind,
+ };
+ },
+
+ watch: {
+ selectedResource: {
+ immediate: true,
+ handler(newResource, oldResource) {
+ // Only reload if the resource actually changed
+ if (JSON.stringify(newResource?.metadata?.uid) !== JSON.stringify(oldResource?.metadata?.uid)) {
+ this.getResourceKind();
+ this.determineResourceType();
+ this.extractContainers();
+
+ // If we're on the logs tab, we need to reconnect
+ if (this.selectedTab === 'logs') {
+ this.reconnectLogsWebSocket();
+ } else if (this.selectedTab === 'describe') {
+ this.generateDescription();
+ } else if (this.selectedTab === 'terminal') {
+ // If we're on the terminal tab but the new resource isn't a pod,
+ // switch to the describe tab
+ if (!this.isPod) {
+ this.$emit('tab-changed', 'describe');
+ } else {
+ // Otherwise, initialize the terminal for the new pod
+ this.initTerminal();
+ }
+ }
+ }
+ }
+ },
+ selectedTab: {
+ handler(newTab, oldTab) {
+ if (newTab === 'logs' && oldTab !== 'logs') {
+ this.reconnectLogsWebSocket();
+ } else if (newTab !== 'logs' && oldTab === 'logs') {
+ this.closeLogsWebSocket();
+ // If switching to describe tab, regenerate the description
+ if (newTab === 'describe') {
+ this.generateDescription();
+ }
+ } else if (newTab === 'describe' && oldTab !== 'describe') {
+ // Always regenerate description when switching to describe tab
+ this.generateDescription();
+ } else if (newTab === 'terminal' && oldTab !== 'terminal') {
+ // Initialize terminal when switching to terminal tab
+ this.$nextTick(() => {
+ this.initTerminal();
+ });
+ } else if (newTab !== 'terminal' && oldTab === 'terminal') {
+ // Dispose terminal when switching away from terminal tab
+ this.disposePodTerminal();
+ }
+ }
+ },
+ selectedContainer() {
+ if (this.selectedTab === 'logs') {
+ this.reconnectLogsWebSocket();
+ } else if (this.selectedTab === 'terminal' && this.podTerminal) {
+ // If the terminal tab is active and container changes, refresh the terminal
+ this.refreshTerminal();
+ }
+ },
+ // Watch logs changes to scroll to bottom
+ logs() {
+ if (this.selectedTab === 'logs') {
+ this.scrollToBottom();
+ }
+ }
+ },
+
+ created() {
+ this.getResourceKind();
+ this.determineResourceType();
+ this.extractContainers();
+ },
+
+ mounted() {
+ // Add event listeners for mouse events to handle resizing
+ document.addEventListener('mousemove', this.onMouseMove);
+ document.addEventListener('mouseup', this.onMouseUp);
+
+ // Try to load saved height from localStorage
+ const savedHeight = localStorage.getItem('bottomTabsHeight');
+ if (savedHeight) {
+ this.panelHeight = parseInt(savedHeight, 10);
+ }
+ },
+
+ beforeUnmount() {
+ this.closeLogsWebSocket();
+ this.disposePodTerminal();
+
+ // Remove event listeners
+ document.removeEventListener('mousemove', this.onMouseMove);
+ document.removeEventListener('mouseup', this.onMouseUp);
+ },
+
+ methods: {
+ displayTerminal(): boolean {
+ if (!this.isPod) {
+ return false;
+ }
+ return true;
+ },
+ displayLogs(): boolean {
+ if (this.isDeployment) {
+ return true;
+ } else if (this.isPod) {
+ return true;
+ } else if (this.isStatefulSet) {
+ return true;
+ } else {
+ return false;
+ }
+ },
+ getResourceKind(): void {
+ if (!this.selectedResource) {
+ this.resourceKind = null;
+ return;
+ }
+ this.resourceKind = getResourceKind(this.selectedResource);
+ },
+ determineResourceType() {
+ // Determine if the selected resource is a pod or deployment
+ if (!this.selectedResource) {
+ this.isPod = false;
+ this.isDeployment = false;
+ this.isStatefulSet = false;
+ this.isConfigMap = false;
+ return;
+ }
+
+ this.isPod = isPod(this.selectedResource);
+ this.isDeployment = isDeployment(this.selectedResource);
+ this.isStatefulSet = isStatefulSet(this.selectedResource);
+ this.isConfigMap = isConfigMap(this.selectedResource);
+ },
+
+ extractContainers() {
+ // Use the logs service to extract containers
+ this.containers = logsService.extractContainers(this.selectedResource);
+
+ // Only set selectedContainer if containers exist and it's not already set to a valid container
+ if (this.containers.length > 0) {
+ if (!this.containers.includes(this.selectedContainer)) {
+ this.selectedContainer = this.containers[0];
+ }
+ } else {
+ this.selectedContainer = '';
+ }
+ },
+
+ async reconnectLogsWebSocket() {
+ if (!this.selectedResource || !this.selectedCluster) {
+ this.logs = 'No resource selected';
+ return;
+ }
+
+ // Create options object for logs service
+ const options = {
+ selectedResource: this.selectedResource,
+ selectedCluster: this.selectedCluster,
+ selectedContainer: this.selectedContainer,
+ tailLines: this.tailLines
+ };
+
+ // Use the logs service to reconnect with callbacks
+ await logsService.reconnectLogsWebSocket(options, {
+ onMessage: (newLogs) => {
+ // Append new log lines
+ this.logs += newLogs;
+ },
+ onError: (error) => {
+ // Only show error if we're still on the logs tab
+ if (this.selectedTab === 'logs') {
+ this.error = error;
+ }
+ },
+ onOpen: () => {
+ this.logs = '';
+ this.error = '';
+ }
+ });
+ },
+
+ closeLogsWebSocket() {
+ // Use the logs service to close the WebSocket
+ return logsService.closeLogsWebSocket();
+ },
+
+ async generateDescription(): void {
+ if (!this.selectedResource) {
+ this.description = 'No resource selected';
+ return;
+ }
+
+ if (!this.selectedCluster) {
+ this.description = 'No cluster selected';
+ return;
+ }
+
+ this.loading = true;
+ this.error = '';
+
+
+ const context = this.selectedCluster.contextName;
+ const name = this.selectedResource.metadata.name;
+
+ let namespace: string | undefined;
+ try {
+ namespace = this.selectedResource.metadata.namespace;
+ if (!namespace) {
+ namespace = this.selectedResource.metadata.name;
+ }
+ if (!namespace) {
+ throw new Error("Unable to get namespace for this resource");
+ }
+ } catch (error) {
+ this.error = error;
+ this.loading = false;
+ return;
+ }
+
+ try {
+ let response;
+ switch (this.resourceKind) {
+ case 'Pod':
+ response = await kubernetesService.describePod(context, namespace, name);
+ break;
+ case 'ConfigMap':
+ response = await kubernetesService.describeConfigMap(context, namespace, name);
+ break;
+ case 'Deployment':
+ response = await kubernetesService.describeDeployment(context, namespace, name);
+ break;
+ case 'StatefulSet':
+ response = await kubernetesService.describeStatefulSet(context, namespace, name);
+ break;
+ case 'Ingress':
+ response = await kubernetesService.describeIngress(context, namespace, name);
+ break;
+ case 'Namespace':
+ response = await kubernetesService.describeNamespace(context, namespace);
+ break;
+ case 'Secret':
+ response = await kubernetesService.describeSecret(context, namespace, name);
+ break;
+ case 'PersistentVolumeClaim':
+ response = await kubernetesService.describePersistentVolumeClaim(context, namespace, name);
+ break;
+ case 'PersistentVolume':
+ response = await kubernetesService.describePersistentVolume(context, namespace, name);
+ break;
+ default:
+ throw new Error(this.resourceKind + " is an unsupported resource type");
+ }
+
+ if (response.success && response.data) {
+ this.description = response.data;
+ } else {
+ throw new Error(response.msg || "failed to get description");
+ }
+ } catch (error) {
+ console.error('Error generating description:', error);
+ this.error = `Error generating description: ${error}`;
+ return;
+ } finally {
+ this.loading = false;
+ }
+ },
+
+ changeTab(tab: 'describe' | 'logs' | 'terminal') {
+ // Clear any previous errors when changing tabs
+ this.error = '';
+
+ // If switching to describe tab, make sure we regenerate the description
+ if (tab === 'describe' && this.selectedTab !== 'describe') {
+ this.$nextTick(() => {
+ this.generateDescription();
+ });
+ }
+
+ this.$emit('tab-changed', tab);
+ },
+
+ updateTailLines(event: Event) {
+ const target = event.target as HTMLSelectElement;
+ this.tailLines = parseInt(target.value, 10);
+
+ if (this.selectedTab === 'logs') {
+ this.reconnectLogsWebSocket();
+ }
+ },
+
+ clearLogs() {
+ this.logs = '';
+ logsService.clearLogs();
+ },
+
+ // Scroll logs to bottom - using a direct DOM approach
+ scrollToBottom() {
+ // Use requestAnimationFrame to ensure we're scrolling after the browser has rendered
+ requestAnimationFrame(() => {
+ const logsContainer = document.querySelector('.logs-container');
+ if (logsContainer) {
+ logsContainer.scrollTop = logsContainer.scrollHeight;
+
+ // Double-check with a timeout to ensure it really scrolled
+ setTimeout(() => {
+ if (logsContainer) {
+ logsContainer.scrollTop = logsContainer.scrollHeight;
+ }
+ }, 100);
+ }
+ });
+ },
+
+ // Resizing methods
+ startResize(event: MouseEvent) {
+ this.isResizing = true;
+ this.startY = event.clientY;
+ this.startHeight = this.panelHeight;
+
+ // Prevent text selection during resize
+ event.preventDefault();
+ },
+
+ onMouseMove(event: MouseEvent) {
+ if (!this.isResizing) return;
+
+ // Calculate new height (resize from top)
+ const deltaY = this.startY - event.clientY;
+ const newHeight = Math.max(100, this.startHeight + deltaY); // Minimum height of 100px
+
+ this.panelHeight = newHeight;
+ },
+
+ onMouseUp() {
+ if (this.isResizing) {
+ this.isResizing = false;
+
+ // Save the height to localStorage
+ localStorage.setItem('bottomTabsHeight', this.panelHeight.toString());
+ }
+ },
+
+ // Terminal methods
+ initTerminal() {
+ if (!this.isPod || !this.selectedResource || !this.selectedCluster) {
+ this.terminalError = 'Terminal is only available for pods';
+ return;
+ }
+
+ this.terminalError = '';
+
+ // Dispose any existing terminal
+ this.disposePodTerminal();
+
+ try {
+ // Create terminal options
+ const options: TerminalOptions = {
+ contextName: this.selectedCluster.contextName,
+ namespace: this.selectedResource.metadata.namespace,
+ podName: this.selectedResource.metadata.name,
+ containerName: this.selectedContainer || ''
+ };
+
+ // Create new terminal instance
+ this.podTerminal = new PodTerminal(options);
+
+ // Initialize terminal
+ this.$nextTick(async () => {
+ try {
+ await this.podTerminal?.initialize('terminal-container');
+ } catch (error) {
+ console.error('Error initializing pod terminal:', error);
+ this.terminalError = `Error initializing terminal: ${error}`;
+ this.disposePodTerminal();
+ }
+ });
+ } catch (error) {
+ console.error('Error setting up pod terminal:', error);
+ this.terminalError = `Error setting up terminal: ${error}`;
+ }
+ },
+
+ disposePodTerminal() {
+ if (this.podTerminal) {
+ this.podTerminal.dispose();
+ this.podTerminal = null;
+ }
+ },
+
+ refreshTerminal() {
+ if (this.podTerminal) {
+ this.terminalError = '';
+
+ try {
+ // Update options if container changed
+ this.podTerminal.updateOptions({
+ containerName: this.selectedContainer || ''
+ });
+
+ // Refresh the terminal
+ this.podTerminal.refresh();
+ } catch (error) {
+ console.error('Error refreshing terminal:', error);
+ this.terminalError = `Error refreshing terminal: ${error}`;
+ }
+ } else {
+ // Initialize a new terminal if none exists
+ this.initTerminal();
+ }
+ }
+ }
+});
+</script>
+
+<template>
+ <div class="bottom-tabs" :style="{ height: `${panelHeight}px` }">
+ <div class="resize-handle" @mousedown="startResize"></div>
+
+ <div class="tabs-header">
+ <div class="tabs">
+ <button
+ :class="{ active: selectedTab === 'describe' }"
+ @click="changeTab('describe')"
+ >
+ Describe
+ </button>
+ <button
+ v-if="displayLogs()"
+ :class="{ active: selectedTab === 'logs' }"
+ @click="changeTab('logs')"
+ >
+ Logs
+ </button>
+ <button
+ v-if="displayTerminal()"
+ :class="{ active: selectedTab === 'terminal' }"
+ @click="changeTab('terminal')"
+ >
+ Terminal
+ </button>
+ </div>
+
+ <!-- Logs tab actions -->
+ <div class="tabs-actions" v-if="selectedTab === 'logs'">
+ <select
+ v-if="containers.length > 1"
+ v-model="selectedContainer"
+ title="Select container"
+ >
+ <option v-for="container in containers" :key="container" :value="container">
+ {{ container }}
+ </option>
+ </select>
+
+ <select
+ v-model="tailLines"
+ @change="updateTailLines"
+ title="Number of lines to show"
+ >
+ <option value="10">10 lines</option>
+ <option value="50">50 lines</option>
+ <option value="100">100 lines</option>
+ <option value="500">500 lines</option>
+ <option value="1000">1000 lines</option>
+ </select>
+
+ <button
+ @click="clearLogs"
+ title="Clear logs"
+ >
+ Clear
+ </button>
+ </div>
+
+ <!-- Terminal tab actions - positioned in the same place as logs actions -->
+ <div class="tabs-actions" v-if="selectedTab === 'terminal'">
+ <select
+ v-if="containers.length > 1"
+ v-model="selectedContainer"
+ @change="refreshTerminal"
+ title="Select container"
+ >
+ <option v-for="container in containers" :key="container" :value="container">
+ {{ container }}
+ </option>
+ </select>
+
+ <button
+ @click="refreshTerminal"
+ title="Refresh terminal"
+ >
+ Refresh
+ </button>
+ </div>
+ </div>
+
+ <div class="tab-content">
+ <div v-if="loading" class="loading">
+ Loading...
+ </div>
+
+ <div v-else-if="error" class="error">
+ {{ error }}
+ </div>
+
+ <div v-else-if="selectedTab === 'describe'" class="describe-container">
+ <pre class="left-aligned">{{ description }}</pre>
+ </div>
+
+ <div
+ v-else-if="selectedTab === 'logs'"
+ class="logs-container"
+ >
+ <pre class="left-aligned terminal-style">{{ logs }}</pre>
+ </div>
+
+ <div v-else-if="selectedTab === 'terminal'" class="terminal-container">
+ <div v-if="!isPod" class="error">
+ Terminal is only available for pods
+ </div>
+ <div v-else-if="terminalError" class="error">
+ {{ terminalError }}
+ </div>
+ <div v-else id="terminal-container" class="left-aligned terminal-style"></div>
+ </div>
+ </div>
+ </div>
+</template>
+
+<style src="@/assets/css/BottomTabs.css" scoped></style>
+<script lang="ts">
+import { defineComponent, PropType } from 'vue';
+import { KubernetesCluster } from '../types/kubernetes';
+
+export default defineComponent({
+ name: 'ClusterList',
+
+ props: {
+ clusters: {
+ type: Array as PropType<KubernetesCluster[]>,
+ required: true,
+ default: () => []
+ },
+ selectedCluster: {
+ type: Object as PropType<KubernetesCluster | null>,
+ required: false,
+ default: null
+ }
+ },
+
+ methods: {
+ isSelected(cluster: KubernetesCluster): boolean {
+ return this.selectedCluster?.contextName === cluster.contextName;
+ },
+
+ selectCluster(cluster: KubernetesCluster) {
+ this.$emit('select-cluster', cluster);
+ }
+ }
+});
+</script>
+
+<template>
+ <div class="cluster-list">
+ <div
+ v-for="cluster in clusters"
+ :key="cluster.server"
+ :class="['cluster-item', { active: isSelected(cluster) }]"
+ @click="selectCluster(cluster)"
+ >
+ <i class="fas fa-server"></i>
+ {{ cluster.contextName }}
+ </div>
+ </div>
+</template>
+
+<style scoped>
+.cluster-list {
+ padding: 8px 0;
+}
+
+.cluster-item {
+ padding: 8px 16px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ color: #cccccc;
+}
+
+.cluster-item:hover {
+ background-color: #2a2d2e;
+}
+
+.cluster-item.active {
+ background-color: #37373d;
+ color: #ffffff;
+}
+
+.cluster-item i {
+ width: 16px;
+ text-align: center;
+ font-size: 14px;
+}
+</style>
+
+<script lang="ts">
+import { defineComponent, ref, computed, PropType, onBeforeUnmount } from 'vue';
+import { KubernetesCluster, KubernetesConfigMap } from '../types/kubernetes';
+import SearchBar from './SearchBar.vue';
+import { formatAge } from '../lib/format';
+
+export default defineComponent({
+ name: 'ConfigMapsList',
+ components: {
+ SearchBar
+ },
+ props: {
+ selectedCluster: {
+ type: Object as PropType<KubernetesCluster>,
+ required: false,
+ default: null
+ },
+ configMaps: {
+ type: Array as PropType<KubernetesConfigMap[]>,
+ required: false,
+ default: () => []
+ }
+ },
+ emits: ['configmap-selected'],
+ data() {
+ return {
+ selectedConfigMap: null as KubernetesConfigMap | null
+ };
+ },
+ setup(props, { emit }) {
+ const searchQuery = ref('');
+ const filteredConfigMaps = computed(() => {
+ if (!searchQuery.value) {
+ return props.configMaps;
+ }
+
+ const query = searchQuery.value.toLowerCase();
+
+ const nameSpecificMatch = query.match(/^name:(.+)$/);
+ if (nameSpecificMatch) {
+ const nameQuery = nameSpecificMatch[1].trim();
+ return props.configMaps.filter(configMap => {
+ const name = configMap.metadata.name.toLowerCase();
+ return name.includes(nameQuery);
+ });
+ }
+
+ const namespaceSpecificMatch = query.match(/^namespace:(.+)$/);
+ if (namespaceSpecificMatch) {
+ const namespaceQuery = namespaceSpecificMatch[1].trim();
+ return props.configMaps.filter(configMap => {
+ const namespace = configMap.metadata.namespace.toLowerCase();
+ return namespace.includes(namespaceQuery);
+ });
+ }
+
+ return props.configMaps.filter(configMap => {
+ const name = configMap.metadata.name.toLowerCase();
+ return name.includes(query);
+ });
+ });
+
+ return {
+ searchQuery,
+ filteredConfigMaps,
+ formatAge
+ };
+ },
+ methods: {
+ isSelected(configMap: KubernetesConfigMap): boolean {
+ if (!this.selectedConfigMap) return false;
+ return this.selectedConfigMap.metadata.name === configMap.metadata.name &&
+ this.selectedConfigMap.metadata.namespace === configMap.metadata.namespace &&
+ this.selectedConfigMap.metadata.uid === configMap.metadata.uid;
+ },
+ selectConfigMap(configMap: KubernetesConfigMap): void {
+ const configMapToEmit = { ...configMap }
+ if (!configMapToEmit.kind) {
+ configMapToEmit.kind = 'ConfigMap';
+ }
+ this.selectedConfigMap = configMapToEmit;
+ this.$emit('configmap-selected', configMapToEmit);
+ },
+ getUniqueKey(configMap: KubernetesConfigMap): string {
+ const namespace = configMap.metadata.namespace || 'default';
+ let key;
+ key = namespace + '-' + configMap.metadata.name + '-' + (configMap.metadata.uid || '');
+ return key;
+ }
+ },
+});
+</script>
+
+<template>
+ <div class="configmaps-container">
+ <div class="search-bar-container">
+ <SearchBar
+ :value="searchQuery"
+ @update:value="searchQuery = $event"
+ placeholder="Search configmaps..."
+ />
+ </div>
+ <div class="table-scroll-container">
+ <table>
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Namespace</th>
+ <th>Age</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr
+ v-for="configMap in filteredConfigMaps"
+ :key="getUniqueKey(configMap)"
+ :class="{ selected: isSelected(configMap) }"
+ @click="selectConfigMap(configMap)"
+ >
+ <td>{{ configMap.metadata.name }}</td>
+ <td>{{ configMap.metadata.namespace || 'default' }}</td>
+ <td>{{ formatAge(configMap.metadata.creationTimestamp) }}</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+</template>
+
+<style src="@/assets/css/ConfigMapsList.css" scoped></style>
+<!-- CreatePodGuided.vue -->
+<script lang="ts">
+import { defineComponent, ref } from 'vue';
+
+export default defineComponent({
+ name: 'CreatePodGuided',
+
+ props: {
+ show: {
+ type: Boolean,
+ required: true
+ },
+ namespace: {
+ type: String,
+ required: true
+ }
+ },
+
+ emits: ['close', 'create-pod'],
+
+ setup(props, { emit }) {
+ const podName = ref('');
+ const podImage = ref('');
+ const namespace = ref('');
+ const command = ref('');
+ const isSubmitting = ref(false);
+ const error = ref('');
+
+ const resetForm = () => {
+ podName.value = '';
+ podImage.value = '';
+ namespace.value = '';
+ command.value = '';
+ error.value = '';
+ isSubmitting.value = false;
+ };
+
+ const closeModal = () => {
+ resetForm();
+ emit('close');
+ };
+
+ const createPod = () => {
+ // Validate form
+ if (!podName.value.trim()) {
+ error.value = 'Pod name is required';
+ return;
+ }
+
+ if (!podImage.value.trim()) {
+ error.value = 'Container image is required';
+ return;
+ }
+
+ if (!namespace.value.trim()) {
+ error.value = 'Namespace is required';
+ return;
+ }
+
+ isSubmitting.value = true;
+
+ const container = {
+ name: 'container-1',
+ image: podImage.value.trim()
+ }
+
+ if (command.value.trim()) {
+ // NOTE(rene): pass command as string within pod definition. This will
+ // be handled by go and transformed into the []string{} which is the
+ // type that corev1.Pod expects.
+ container.command = command.value.trim();
+ }
+
+ let opts = {
+ podDefinition: {
+ apiVersion: 'v1',
+ kind: 'Pod',
+ metadata: {
+ name: podName.value.trim(),
+ namespace: namespace.value.trim()
+ },
+ spec: {
+ containers: [container]
+ }
+ },
+ isYaml: false
+ }
+ emit('create-pod', opts);
+
+ // Reset and close form
+ resetForm();
+ closeModal();
+ };
+
+ return {
+ podName,
+ podImage,
+ namespace,
+ command,
+ isSubmitting,
+ error,
+ closeModal,
+ createPod
+ };
+ }
+});
+</script>
+
+<template>
+ <div v-if="show" class="modal-overlay" @click="closeModal">
+ <div class="modal-content" @click.stop>
+ <div class="modal-header">
+ <h3>Create Pod</h3>
+ <button class="close-button" @click="closeModal">×</button>
+ </div>
+
+ <div class="modal-body">
+ <div v-if="error" class="error-message">{{ error }}</div>
+
+ <div class="form-group">
+ <label for="pod-name">Pod Name:</label>
+ <input
+ id="pod-name"
+ v-model="podName"
+ type="text"
+ placeholder="test-pod-1"
+ :disabled="isSubmitting"
+ />
+ </div>
+
+ <div class="form-group">
+ <label>Namespace:</label>
+ <input
+ id="namespace"
+ v-model="namespace"
+ type="text"
+ placeholder="default"
+ :disabled="isSubmitting"
+ />
+ </div>
+
+ <div class="form-group">
+ <label for="pod-image">Container Image:</label>
+ <input
+ id="pod-image"
+ v-model="podImage"
+ type="text"
+ placeholder="busybox"
+ :disabled="isSubmitting"
+ />
+ </div>
+
+ <div class="form-group">
+ <label>Container Command:</label>
+ <input
+ id="command"
+ v-model="command"
+ type="text"
+ placeholder='sh -c sleep 3600'
+ :disabled="isSubmitting"
+ />
+ </div>
+ </div>
+
+
+ <div class="modal-footer">
+ <button
+ class="cancel-button"
+ @click="closeModal"
+ :disabled="isSubmitting"
+ >
+ Cancel
+ </button>
+ <button
+ class="create-button"
+ @click="createPod"
+ :disabled="isSubmitting"
+ >
+ {{ isSubmitting ? 'Creating...' : 'Create' }}
+ </button>
+ </div>
+ </div>
+ </div>
+</template>
+
+<style src="@/assets/css/CreatePodGuided.css" scoped></style>
+<!-- CreatePodMethodSelector.vue -->
+<template>
+ <div v-if="show" class="modal-overlay" @click="closeModal">
+ <div class="modal-content" @click.stop>
+ <div class="modal-header">
+ <h3>Create Pod</h3>
+ <button class="close-button" @click="closeModal">×</button>
+ </div>
+
+ <div class="modal-body">
+ <div class="method-option" @click="selectedMethod = 'guided'">
+ <div class="radio-container">
+ <div class="radio-button">
+ <div class="radio-outer">
+ <div class="radio-inner" v-if="selectedMethod === 'guided'"></div>
+ </div>
+ </div>
+ <div class="method-text">
+ <div class="method-label">Guided Creation</div>
+ </div>
+ </div>
+ </div>
+
+ <div class="method-option" @click="selectedMethod = 'yaml'">
+ <div class="radio-container">
+ <div class="radio-button">
+ <div class="radio-outer">
+ <div class="radio-inner" v-if="selectedMethod === 'yaml'"></div>
+ </div>
+ </div>
+ <div class="method-text">
+ <div class="method-label">YAML Creation</div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <button class="cancel-button" @click="closeModal">
+ Cancel
+ </button>
+ <button
+ class="continue-button"
+ @click="continueToSelected"
+ :disabled="!selectedMethod"
+ >
+ Continue
+ </button>
+ </div>
+ </div>
+ </div>
+</template>
+
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+
+export default defineComponent({
+ name: 'CreatePodMethodSelector',
+ props: {
+ show: {
+ type: Boolean,
+ default: false
+ },
+ namespace: {
+ type: String,
+ default: 'default'
+ }
+ },
+ data() {
+ return {
+ selectedMethod: 'guided'
+ }
+ },
+ methods: {
+ closeModal() {
+ this.$emit('close')
+ },
+ continueToSelected() {
+ this.$emit('method-selected', this.selectedMethod)
+ }
+ }
+});
+</script>
+
+<style src="@/assets/css/CreatePodMethodSelector.css" scoped></style>
+<!-- CreatePodYaml.vue -->
+<template>
+ <div v-if="show" class="modal-overlay" @click="closeModal">
+ <div class="modal-content yaml-editor" @click.stop>
+ <div class="modal-header">
+ <h3>Create Pod from YAML</h3>
+ <button class="close-button" @click="closeModal">×</button>
+ </div>
+
+ <div class="modal-body">
+ <div v-if="error" class="error-message">{{ error }}</div>
+
+ <div class="yaml-container">
+ <textarea
+ v-model="yamlContent"
+ placeholder="Paste your Pod YAML definition here..."
+ :disabled="isSubmitting"
+ class="yaml-textarea"
+ ></textarea>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <button
+ class="cancel-button"
+ @click="closeModal"
+ :disabled="isSubmitting"
+ >
+ Cancel
+ </button>
+ <button
+ class="create-button"
+ @click="createPodFromYaml"
+ :disabled="isSubmitting || !yamlContent.trim()"
+ >
+ {{ isSubmitting ? 'Creating...' : 'Create Pod' }}
+ </button>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+
+export default defineComponent({
+ name: 'CreatePodYaml',
+
+ props: {
+ show: {
+ type: Boolean,
+ default: false
+ },
+ namespace: {
+ type: String,
+ default: 'default'
+ }
+ },
+
+ emits: ['create-pod'],
+
+ data() {
+ return {
+ yamlContent: '',
+ isSubmitting: false,
+ error: ''
+ }
+ },
+ methods: {
+ closeModal() {
+ if (!this.isSubmitting) {
+ this.$emit('close')
+ }
+ },
+ async createPodFromYaml() {
+ this.isSubmitting = true;
+ this.error = '';
+
+ try {
+ let opts = {
+ yamlContent: this.yamlContent,
+ isYaml: true
+ }
+ this.$emit('create-pod', opts);
+ this.closeModal();
+ } catch (err: any) {
+ this.error = `Failed to create Pod: ${err.message || err}`;
+ } finally {
+ this.isSubmitting = false;
+ }
+ }
+ }
+});
+</script>
+
+<style src="@/assets/css/CreatePodYaml.css" scoped></style>
+<template>
+ <div class="deployment-details" v-if="selectedResource">
+ <div class="details-header">
+ <span class="details-icon">🚀</span>
+ <span class="details-name">{{ selectedResource.metadata.name }}</span>
+ </div>
+ <div class="details-content">
+ <div class="details-row">
+ <span class="label">Name:</span>
+ <span class="value">{{ selectedResource.metadata.name }}</span>
+ </div>
+ <div class="details-row">
+ <span class="label">Namespace:</span>
+ <span class="value">{{ selectedResource.metadata.namespace }}</span>
+ </div>
+ <div class="details-row">
+ <span class="label">Replicas:</span>
+ <span class="value">{{ selectedResource.spec.replicas }}</span>
+ </div>
+ <div class="details-row">
+ <span class="label">Strategy:</span>
+ <span class="value">{{ selectedResource.spec.strategy?.type }}</span>
+ </div>
+ <div class="details-row">
+ <span class="label">Created:</span>
+ <span class="value">{{ formatDateTime(selectedResource.metadata.creationTimestamp) }}</span>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script lang="ts">
+import { defineComponent, PropType } from 'vue';
+import { KubernetesDeployment } from '../types/kubernetes';
+
+export default defineComponent({
+ name: 'DeploymentDetails',
+
+ props: {
+ selectedResource: {
+ type: Object as PropType<KubernetesDeployment | null>,
+ required: false,
+ default: null
+ }
+ },
+
+ methods: {
+ formatDateTime(timestamp: string): string {
+ return new Date(timestamp).toLocaleString();
+ }
+ }
+});
+</script>
+
+<style scoped>
+.deployment-details {
+ padding: 16px;
+ height: 100%;
+ overflow-y: auto;
+ background-color: #1e1e1e;
+}
+
+.details-header {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin-bottom: 16px;
+}
+
+.details-icon {
+ font-size: 20px;
+}
+
+.details-name {
+ font-size: 16px;
+ font-weight: 500;
+ color: #ffffff;
+}
+
+.details-content {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
+ gap: 8px;
+}
+
+.details-row {
+ display: flex;
+ gap: 8px;
+}
+
+.details-row .label {
+ color: #858585;
+ min-width: 100px;
+}
+
+.details-row .value {
+ color: #cccccc;
+}
+</style>
+
+<script lang="ts">
+import { defineComponent, PropType, ref, computed } from 'vue';
+import { KubernetesCluster, KubernetesDeployment } from '../types/kubernetes';
+import SearchBar from './SearchBar.vue';
+import { formatAge } from '../lib/format';
+
+export default defineComponent({
+ name: 'DeploymentsList',
+
+ components: {
+ SearchBar
+ },
+
+ props: {
+ selectedCluster: {
+ type: Object as PropType<KubernetesCluster | null>,
+ required: false,
+ default: null
+ },
+ deployments: {
+ type: Array as PropType<KubernetesDeployment[]>,
+ required: false,
+ default: () => []
+ }
+ },
+
+ emits: ['deployment-selected', 'restart-deployment'],
+
+ setup(props) {
+ // Search functionality
+ const searchQuery = ref('');
+
+ const filteredDeployments = computed(() => {
+ if (!searchQuery.value) {
+ return props.deployments;
+ }
+
+ const query = searchQuery.value.toLowerCase();
+
+ // Check if the query is in the format "name:deployment-name"
+ const nameSpecificMatch = query.match(/^name:(.+)$/);
+ if (nameSpecificMatch) {
+ const nameQuery = nameSpecificMatch[1].trim();
+ return props.deployments.filter(deployment => {
+ const name = deployment.metadata.name.toLowerCase();
+ return name.includes(nameQuery);
+ });
+ }
+
+ // Check if the query is in the format "namespace:namespace-name"
+ const namespaceSpecificMatch = query.match(/^namespace:(.+)$/);
+ if (namespaceSpecificMatch) {
+ const namespaceQuery = namespaceSpecificMatch[1].trim();
+ return props.deployments.filter(deployment => {
+ const namespace = deployment.metadata.namespace?.toLowerCase() || '';
+ return namespace.includes(namespaceQuery);
+ });
+ }
+
+ // Check if the query is in the format "label:key=value" or "label:key"
+ const labelSpecificMatch = query.match(/^label:(.+)$/);
+ if (labelSpecificMatch) {
+ const labelQuery = labelSpecificMatch[1].trim();
+ return props.deployments.filter(deployment => {
+ const labels = deployment.metadata.labels || {};
+ for (const key in labels) {
+ const value = labels[key].toLowerCase();
+ const keyLower = key.toLowerCase();
+
+ // Check for key=value format
+ if (labelQuery.includes('=')) {
+ const [queryKey, queryValue] = labelQuery.split('=');
+ if (keyLower === queryKey.trim().toLowerCase() &&
+ value.includes(queryValue.trim().toLowerCase())) {
+ return true;
+ }
+ }
+ // Check for just key
+ else if (keyLower.includes(labelQuery)) {
+ return true;
+ }
+ }
+ return false;
+ });
+ }
+
+ // Default behavior: search only in deployment names
+ return props.deployments.filter(deployment => {
+ const name = deployment.metadata.name.toLowerCase();
+ return name.includes(query);
+ });
+ });
+
+
+ // Context menu state
+ const showMenu = ref(false);
+ const menuPosition = ref({ x: 0, y: 0 });
+ const selectedContextDeployment = ref<KubernetesDeployment | null>(null);
+
+ // Show context menu
+ const showContextMenu = (event: MouseEvent, deployment: KubernetesDeployment) => {
+ event.preventDefault();
+
+ // Position the menu
+ menuPosition.value = {
+ x: event.clientX,
+ y: event.clientY
+ };
+
+ // Store the deployment that was right-clicked
+ selectedContextDeployment.value = deployment;
+
+ // Show the menu
+ showMenu.value = true;
+
+ // Add a click event listener to hide the menu when clicking outside
+ setTimeout(() => {
+ document.addEventListener('click', hideContextMenu);
+ }, 0);
+ };
+
+ // Hide context menu
+ const hideContextMenu = () => {
+ showMenu.value = false;
+ document.removeEventListener('click', hideContextMenu);
+ };
+
+ return {
+ searchQuery,
+ filteredDeployments,
+ showMenu,
+ menuPosition,
+ selectedContextDeployment,
+ showContextMenu,
+ hideContextMenu,
+ formatAge
+ };
+ },
+
+ data() {
+ return {
+ selectedDeployment: null as KubernetesDeployment | null
+ };
+ },
+
+ methods: {
+ selectDeployment(deployment: KubernetesDeployment): void {
+ const deploymentToEmit = { ...deployment };
+ if (!deploymentToEmit.kind) {
+ deploymentToEmit.kind = 'Deployment';
+ }
+ this.selectedDeployment = deploymentToEmit;
+ this.$emit('deployment-selected', deploymentToEmit);
+ },
+
+ isSelected(deployment: KubernetesDeployment): boolean {
+ return this.selectedDeployment?.metadata.name === deployment.metadata.name;
+ },
+
+ // Menu actions
+ restartDeployment() {
+ if (this.selectedContextDeployment && this.selectedCluster) {
+ this.$emit('restart-deployment', {
+ cluster: this.selectedCluster,
+ deployment: this.selectedContextDeployment
+ });
+ }
+ this.hideContextMenu();
+ },
+
+ getUniqueKey(deployment: KubernetesDeployment): string {
+ const namespace = deployment.metadata.namespace || 'default';
+ return `${namespace}-${deployment.metadata.name}-${deployment.metadata.uid}`;
+ },
+ }
+});
+</script>
+
+<template>
+ <div class="deployments-container">
+ <div class="search-bar-container">
+ <SearchBar
+ :value="searchQuery"
+ @update:value="searchQuery = $event"
+ placeholder="Search deployments..."
+ />
+ </div>
+ <div class="table-scroll-container">
+ <table>
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Namespace</th>
+ <th>Ready</th>
+ <th>Up-to-date</th>
+ <th>Available</th>
+ <th>Age</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr
+ v-for="deployment in filteredDeployments"
+ :key="getUniqueKey(deployment)"
+ :class="{ selected: isSelected(deployment) }"
+ @click="selectDeployment(deployment)"
+ @contextmenu.prevent="showContextMenu($event, deployment)"
+ >
+ <td>{{ deployment.metadata.name }}</td>
+ <td>{{ deployment.metadata.namespace || 'default' }}</td> <!-- Display namespace -->
+ <td>{{ `${deployment.status.readyReplicas || 0}/${deployment.spec.replicas}` }}</td>
+ <td>{{ deployment.status.updatedReplicas || 0 }}</td>
+ <td>{{ deployment.status.availableReplicas || 0 }}</td>
+ <td>{{ formatAge(deployment.metadata.creationTimestamp) }}</td>
+ </tr>
+ </tbody>
+ </table>
+
+ </div>
+
+ <!-- Context Menu -->
+ <div
+ v-if="showMenu"
+ class="context-menu"
+ :style="{ top: menuPosition.y + 'px', left: menuPosition.x + 'px' }"
+ >
+ <div class="menu-item" @click="restartDeployment">
+ <span class="menu-text">Restart</span>
+ </div>
+ </div>
+ </div>
+</template>
+
+
+<style src="@/assets/css/DeploymentsList.css" scoped></style>
+<template>
+ <div v-if="show" class="modal-overlay" @click="closeModal">
+ <div class="modal-content yaml-editor" @click.stop>
+ <div class="modal-header">
+ <h3>Edit Pod YAML</h3>
+ <button class="close-button" @click="closeModal">×</button>
+ </div>
+
+ <div class="modal-body">
+ <div v-if="error" class="error-message">{{ error }}</div>
+ <div v-if="isLoading" class="loading-message">Loading pod YAML...</div>
+
+ <div v-if="!isLoading" class="yaml-container">
+ <textarea
+ v-model="yamlContent"
+ :disabled="isSubmitting"
+ class="yaml-textarea"
+ ></textarea>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <button
+ class="cancel-button"
+ @click="closeModal"
+ :disabled="isSubmitting"
+ >
+ Cancel
+ </button>
+ <button
+ class="update-button"
+ @click="updatePod"
+ :disabled="isSubmitting || isLoading || !yamlContent.trim()"
+ >
+ {{ isSubmitting ? 'Updating...' : 'Update Pod' }}
+ </button>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import { KubernetesPod } from '../types/kubernetes';
+import { kubernetesService } from '../lib/kubernetes';
+import { podJsonToYaml } from '../lib/lib';
+
+export default defineComponent({
+ name: 'EditPodYaml',
+ props: {
+ show: {
+ type: Boolean,
+ default: false
+ },
+ pod: {
+ type: Object as () => KubernetesPod | null,
+ default: null
+ },
+ cluster: {
+ type: Object,
+ default: null
+ }
+ },
+ data() {
+ return {
+ yamlContent: '',
+ isLoading: false,
+ isSubmitting: false,
+ error: '',
+ originalPodName: '',
+ originalNamespace: ''
+ }
+ },
+ watch: {
+ show(newVal) {
+ if (newVal && this.pod) {
+ this.fetchPodYaml();
+ } else {
+ this.yamlContent = '';
+ this.error = '';
+ }
+ }
+ },
+ methods: {
+ closeModal() {
+ if (!this.isSubmitting) {
+ this.$emit('close');
+ }
+ },
+ async fetchPodYaml() {
+ if (!this.pod || !this.cluster) return;
+
+ this.isLoading = true;
+ this.error = '';
+
+ this.originalPodName = this.pod.metadata.name;
+ this.originalNamespace = this.pod.metadata.namespace;
+
+ try {
+ const response = await kubernetesService.getPod(
+ this.cluster.contextName,
+ this.originalNamespace,
+ this.originalPodName
+ );
+ if (response.success) {
+ this.yamlContent = podJsonToYaml(response.data);
+ } else {
+ this.error = response.msg || 'Failed to fetch pod YAML';
+ }
+ } catch (err: any) {
+ this.error = `Error fetching pod YAML: ${err.message || err}`;
+ } finally {
+ this.isLoading = false;
+ }
+ },
+ async updatePod() {
+ if (!this.pod || !this.cluster) return;
+
+ this.isSubmitting = true;
+ this.error = '';
+
+ try {
+ const response = await kubernetesService.updatePod(
+ this.cluster.contextName,
+ this.yamlContent,
+ this.originalPodName,
+ this.originalNamespace
+ );
+
+ if (response.success) {
+ this.$emit('pod-updated', response);
+ this.closeModal();
+ } else {
+ this.error = response.msg || 'Failed to update pod';
+ }
+ } catch (err: any) {
+ this.error = `Failed to update pod: ${err.message || err}`;
+ } finally {
+ this.isSubmitting = false;
+ }
+ }
+ }
+});
+</script>
+
+<style src="@/assets/css/EditPodYaml.css" scoped></style>
+<script lang="ts">
+import { defineComponent, ref, computed, PropType, onBeforeUnmount } from 'vue';
+import { KubernetesCluster, KubernetesIngress } from '../types/kubernetes';
+import SearchBar from './SearchBar.vue';
+import { formatAge } from '../lib/format';
+
+export default defineComponent({
+ name: 'IngressesList',
+ components: {
+ SearchBar
+ },
+ props: {
+ selectedCluster: {
+ type: Object as PropType<KubernetesCluster>,
+ required: false,
+ default: null
+ },
+ ingresses: {
+ type: Array as PropType<KubernetesIngress[]>,
+ required: false,
+ default: () => []
+ }
+ },
+ emits: ['ingress-selected', 'delete-ingress'],
+ data() {
+ return {
+ selectedIngress: null as KubernetesIngress | null,
+ selectedContextIngress: null as KuberneteIngress | null,
+ showMenu: false,
+ menuPosition: { x: 0, y: 0},
+ };
+ },
+ beforeUnmount() {
+ document.removeEventListener('click', this.hideContextMenu);
+ },
+ setup(props, { emit }) {
+ const searchQuery = ref('');
+ const filteredIngresses = computed(() => {
+ if (!searchQuery.value) {
+ return props.ingresses;
+ }
+
+ const query = searchQuery.value.toLowerCase();
+
+ const nameSpecificMatch = query.match(/^name:(.+)$/);
+ if (nameSpecificMatch) {
+ const nameQuery = nameSpecificMatch[1].trim();
+ return props.ingresses.filter(ingress => {
+ const name = ingress.metadata.name.toLowerCase();
+ return name.includes(nameQuery);
+ });
+ }
+
+ const namespaceSpecificMatch = query.match(/^namespace:(.+)$/);
+ if (namespaceSpecificMatch) {
+ const namespaceQuery = namespaceSpecificMatch[1].trim();
+ return props.ingresses.filter(ingress => {
+ const namespace = ingress.metadata.namespace.toLowerCase();
+ return namespace.includes(namespaceQuery);
+ });
+ }
+
+ const classSpecificMatch = query.match(/^class:(.+)$/);
+ if (classSpecificMatch) {
+ const classQuery = classSpecificMatch[1].trim();
+ return props.ingresses.filter(ingress => {
+ if (!ingress.spec.ingressClassName) {
+ return false;
+ }
+ const classname = ingress.spec.ingressClassName.toLowerCase();
+ return classname.includes(classQuery);
+ });
+ }
+
+ return props.ingresses.filter(ingress => {
+ const name = ingress.metadata.name.toLowerCase();
+ return name.includes(query);
+ });
+ });
+
+ return {
+ searchQuery,
+ filteredIngresses,
+ formatAge
+ };
+ },
+ methods: {
+ hideContextMenu(): void {
+ this.showMenu = false;
+ document.removeEventListener('click', this.hideContextMenu);
+ },
+ showContextMenu(event: MouseEvent, ingress: KubernetesIngress): void {
+ event.preventDefault();
+
+ this.menuPosition = {
+ x: event.clientX,
+ y: event.clientY
+ };
+
+ this.selectedContextIngress = ingress;
+
+ this.selectIngress(ingress);
+
+ this.showMenu = true;
+
+ setTimeout(() => {
+ document.addEventListener('click', this.hideContextMenu);
+ }, 0);
+ },
+ isSelected(ingress: KubernetesIngress): boolean {
+ if (!this.selectedIngress) return false;
+ return this.selectedIngress.metadata.name === ingress.metadata.name &&
+ this.selectedIngress.metadata.namespace === ingress.metadata.namespace &&
+ this.selectedIngress.metadata.uid === ingress.metadata.uid;
+ },
+ selectIngress(ingress: KubernetesIngress): void {
+ const ingressToEmit = { ...ingress }
+ if (!ingressToEmit.kind) {
+ ingressToEmit.kind = 'Ingress';
+ }
+ this.selectedIngress = ingressToEmit;
+ this.$emit('ingress-selected', ingressToEmit);
+ },
+ deleteIngress(): void {
+ if (this.selectedContextIngress && this.selectedCluster) {
+ this.$emit('delete-ingress', {
+ cluster: this.selectedCluster,
+ ingress: this.selectedIngress
+ });
+ }
+ this.hideContextMenu();
+ },
+ getUniqueKey(ingress: KubernetesIngress): string {
+ const namespace = ingress.metadata.namespace || 'default';
+ let key;
+ key = namespace + '-' + ingress.metadata.name + '-' + (ingress.metadata.uid || '');
+ return key;
+ }
+ },
+});
+</script>
+
+<template>
+ <div class="ingresses-container">
+ <div class="search-bar-container">
+ <SearchBar
+ :value="searchQuery"
+ @update:value="searchQuery = $event"
+ placeholder="Search ingresses..."
+ />
+ </div>
+ <div class="table-scroll-container">
+ <table>
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Namespace</th>
+ <th>Class</th>
+ <th>Age</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr
+ v-for="ingress in filteredIngresses"
+ :key="getUniqueKey(ingress)"
+ :class="{ selected: isSelected(ingress) }"
+ @click="selectIngress(ingress)"
+ @contextmenu="showContextMenu($event, ingress)"
+ >
+ <td>{{ ingress.metadata.name }}</td>
+ <td>{{ ingress.metadata.namespace || 'default' }}</td>
+ <td>{{ ingress.spec.ingressClassName }}</td>
+ <td>{{ formatAge(ingress.metadata.creationTimestamp) }}</td>
+ </tr>
+ </tbody>
+ </table>
+ <div
+ v-if="showMenu"
+ class="context-menu"
+ :style="{ top: menuPosition.y + 'px', left: menuPosition.x + 'px' }"
+ @click.stop
+ >
+ <div class="menu-item" @click="deleteIngress">
+ Delete
+ </div>
+ </div>
+ </div>
+ </div>
+</template>
+
+<style src="@/assets/css/IngressesList.css" scoped></style>
+<template>
+ <div class="logs-container">
+ <div class="logs-header">
+ <span>Logs: {{ selectedPod?.metadata?.name }}</span>
+ <button @click="$emit('close')" class="close-btn">×</button>
+ </div>
+ <div class="logs-content" ref="logsContent">
+ <pre v-html="logContent"></pre>
+ </div>
+ </div>
+</template>
+
+<script>
+export default {
+ name: 'Logs',
+
+ props: {
+ selectedPod: {
+ type: Object,
+ required: true
+ },
+ selectedNamespace: {
+ type: Object,
+ required: true
+ },
+ selectedCluster: {
+ type: Object,
+ required: true
+ },
+ selectedContainer: {
+ type: String,
+ required: true
+ }
+ },
+
+ data() {
+ return {
+ socket: null,
+ logContent: '',
+ isConnected: false,
+ reconnectAttempts: 0,
+ maxReconnectAttempts: 3,
+ isReconnecting: false
+ }
+ },
+
+ mounted() {
+ this.connectWebSocket();
+ },
+
+ beforeUnmount() {
+ this.cleanup();
+ },
+
+ methods: {
+ connectWebSocket() {
+ if (this.isReconnecting) {
+ return;
+ }
+
+ this.isReconnecting = true;
+
+ if (this.socket) {
+ this.socket.close();
+ this.socket = null;
+ }
+
+ const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
+ const wsUrl = `${wsProtocol}//${window.location.hostname}:8081/api/pods/logs?` +
+ `cluster=${encodeURIComponent(this.selectedCluster.server)}&` +
+ `namespace=${encodeURIComponent(this.selectedNamespace.name)}&` +
+ `pod=${encodeURIComponent(this.selectedPod.metadata.name)}&` +
+ `container=${encodeURIComponent(this.selectedContainer)}`;
+
+ try {
+ this.socket = new WebSocket(wsUrl);
+
+ this.socket.onopen = () => {
+ this.isConnected = true;
+ this.reconnectAttempts = 0;
+ this.isReconnecting = false;
+ this.logContent += 'Connected to pod logs...\n';
+ this.scrollToBottom();
+ };
+
+ this.socket.onmessage = (event) => {
+ this.logContent += event.data;
+ this.scrollToBottom();
+ };
+
+ this.socket.onclose = () => {
+ this.isConnected = false;
+ this.isReconnecting = false;
+ this.logContent += '\nConnection closed\n';
+ this.scrollToBottom();
+ };
+
+ this.socket.onerror = (error) => {
+ console.error('WebSocket error:', error);
+ this.isReconnecting = false;
+ this.logContent += '\nError: Failed to connect to pod logs\n';
+ this.scrollToBottom();
+ };
+
+ } catch (error) {
+ console.error('Failed to connect to WebSocket:', error);
+ this.isReconnecting = false;
+ this.logContent += 'Failed to connect to pod logs\n';
+ this.scrollToBottom();
+ }
+ },
+
+ scrollToBottom() {
+ if (this.$refs.logsContent) {
+ this.$refs.logsContent.scrollTop = this.$refs.logsContent.scrollHeight;
+ }
+ },
+
+ cleanup() {
+ if (this.socket) {
+ this.socket.close();
+ this.socket = null;
+ }
+ this.isConnected = false;
+ this.isReconnecting = false;
+ this.reconnectAttempts = 0;
+ }
+ }
+}
+</script>
+
+<style scoped>
+.logs-container {
+ position: fixed;
+ bottom: 20px;
+ right: 20px;
+ width: 800px;
+ height: 500px;
+ background: #1e1e1e;
+ border: 1px solid #333;
+ border-radius: 6px;
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
+ z-index: 1000;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+}
+
+.logs-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 8px 12px;
+ background: #333;
+ color: white;
+ font-size: 14px;
+ user-select: none;
+}
+
+.close-btn {
+ background: none;
+ border: none;
+ color: white;
+ font-size: 20px;
+ cursor: pointer;
+ padding: 0 4px;
+ line-height: 1;
+}
+
+.close-btn:hover {
+ color: #ff5252;
+}
+
+.logs-content {
+ flex: 1;
+ padding: 12px;
+ overflow-y: auto;
+ background-color: #1e1e1e;
+ color: #ffffff;
+ font-family: monospace;
+ white-space: pre-wrap;
+ word-wrap: break-word;
+ text-align: left;
+}
+
+pre {
+ margin: 0;
+ font-size: 12px;
+ line-height: 1.4;
+}
+</style>
+
+<script lang="ts">
+import { defineComponent, ref } from 'vue';
+
+export default defineComponent({
+ name: 'ResourceNamespaceCreateGuided',
+
+ props: {
+ show: {
+ type: Boolean,
+ required: true
+ },
+ },
+
+ emits: ['close', 'create-namespace'],
+
+ setup(props, { emit }) {
+ const name = ref('');
+ const isSubmitting = ref(false);
+ const error = ref('');
+
+ const resetForm = () => {
+ name.value = '';
+ error.value = '';
+ isSubmitting.value = false;
+ };
+
+ const closeModal = () => {
+ resetForm();
+ emit('close');
+ };
+
+ const createNamespace = () => {
+ // Validate form
+ if (!name.value.trim()) {
+ error.value = 'Name is required';
+ return;
+ }
+
+ isSubmitting.value = true;
+
+ let opts = {
+ definition: {
+ apiVersion: 'v1',
+ kind: 'Namespace',
+ metadata: {
+ name: name.value.trim(),
+ }
+ },
+ isYaml: false
+ }
+ emit('create-namespace', opts);
+ resetForm();
+ closeModal();
+ };
+
+ return {
+ name,
+ isSubmitting,
+ error,
+ closeModal,
+ createNamespace
+ };
+ }
+});
+</script>
+
+<template>
+ <div v-if="show" class="modal-overlay" @click="closeModal">
+ <div class="modal-content" @click.stop>
+ <div class="modal-header">
+ <h3>Create Namespace</h3>
+ <button class="close-button" @click="closeModal">×</button>
+ </div>
+
+ <div class="modal-body">
+ <div v-if="error" class="error-message">{{ error }}</div>
+
+ <div class="form-group">
+ <label for="name">Name:</label>
+ <input
+ id="name"
+ v-model="name"
+ type="text"
+ placeholder="test-namespace-1"
+ :disabled="isSubmitting"
+ />
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <button
+ class="cancel-button"
+ @click="closeModal"
+ :disabled="isSubmitting"
+ >
+ Cancel
+ </button>
+ <button
+ class="create-button"
+ @click="createNamespace"
+ :disabled="isSubmitting"
+ >
+ {{ isSubmitting ? 'Creating...' : 'Create' }}
+ </button>
+ </div>
+ </div>
+ </div>
+</template>
+
+<style src="@/assets/css/CreateResource.css" scoped></style>
+<!-- CreateNamespaceMethodSelector.vue -->
+<template>
+ <div v-if="show" class="modal-overlay" @click="closeModal">
+ <div class="modal-content" @click.stop>
+ <div class="modal-header">
+ <h3>Create Namespace</h3>
+ <button class="close-button" @click="closeModal">×</button>
+ </div>
+
+ <div class="modal-body">
+ <div class="method-option" @click="selectedMethod = 'guided'">
+ <div class="radio-container">
+ <div class="radio-button">
+ <div class="radio-outer">
+ <div class="radio-inner" v-if="selectedMethod === 'guided'"></div>
+ </div>
+ </div>
+ <div class="method-text">
+ <div class="method-label">Guided Creation</div>
+ </div>
+ </div>
+ </div>
+
+ <div class="method-option" @click="selectedMethod = 'yaml'">
+ <div class="radio-container">
+ <div class="radio-button">
+ <div class="radio-outer">
+ <div class="radio-inner" v-if="selectedMethod === 'yaml'"></div>
+ </div>
+ </div>
+ <div class="method-text">
+ <div class="method-label">YAML Creation</div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <button class="cancel-button" @click="closeModal">
+ Cancel
+ </button>
+ <button
+ class="continue-button"
+ @click="continueToSelected"
+ :disabled="!selectedMethod"
+ >
+ Continue
+ </button>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script lang="ts">
+import { defineComponent, ref } from 'vue';
+
+export default defineComponent({
+ name: 'CreateNamespaceMethodSelector',
+
+ props: {
+ show: {
+ type: Boolean,
+ default: false
+ }
+ },
+
+ emits: ['close', 'method-selected'],
+
+ setup(props, { emit }) {
+ // State
+ const selectedMethod = ref('guided');
+
+ // Methods
+ const closeModal = () => {
+ emit('close');
+ };
+
+ const continueToSelected = () => {
+ emit('method-selected', selectedMethod.value);
+ };
+
+ return {
+ selectedMethod,
+ closeModal,
+ continueToSelected
+ };
+ }
+});
+</script>
+
+<style src="@/assets/css/CreatePodMethodSelector.css" scoped></style>
+<!-- NamespacesCreateYaml.vue -->
+<template>
+ <div v-if="show" class="modal-overlay" @click="closeModal">
+ <div class="modal-content yaml-editor" @click.stop>
+ <div class="modal-header">
+ <h3>Create Namespace from YAML</h3>
+ <button class="close-button" @click="closeModal">×</button>
+ </div>
+
+ <div class="modal-body">
+ <div v-if="error" class="error-message">{{ error }}</div>
+
+ <div class="yaml-container">
+ <textarea
+ v-model="yamlContent"
+ placeholder="Paste your Namespace YAML definition here..."
+ :disabled="isSubmitting"
+ class="yaml-textarea"
+ ></textarea>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <button
+ class="cancel-button"
+ @click="closeModal"
+ :disabled="isSubmitting"
+ >
+ Cancel
+ </button>
+ <button
+ class="create-button"
+ @click="createNamespaceFromYaml"
+ :disabled="isSubmitting || !yamlContent.trim()"
+ >
+ {{ isSubmitting ? 'Creating...' : 'Create Namespace' }}
+ </button>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script lang="ts">
+import { defineComponent, ref } from 'vue';
+
+export default defineComponent({
+ name: 'CreateNamespaceYaml',
+
+ props: {
+ show: {
+ type: Boolean,
+ default: false
+ }
+ },
+
+ emits: ['close', 'create-namespace'],
+
+ setup(props, { emit }) {
+ // State
+ const yamlContent = ref('');
+ const isSubmitting = ref(false);
+ const error = ref('');
+
+ // Methods
+ const closeModal = () => {
+ if (!isSubmitting.value) {
+ emit('close');
+ }
+ };
+
+ const createNamespaceFromYaml = async () => {
+ isSubmitting.value = true;
+ error.value = '';
+
+ try {
+ const opts = {
+ yamlContent: yamlContent.value,
+ isYaml: true
+ };
+
+ emit('create-namespace', opts);
+ closeModal();
+ } catch (err: any) {
+ error.value = `Failed to create Namespace: ${err.message || err}`;
+ } finally {
+ isSubmitting.value = false;
+ }
+ };
+
+ return {
+ yamlContent,
+ isSubmitting,
+ error,
+ closeModal,
+ createNamespaceFromYaml
+ };
+ }
+});
+</script>
+
+<style src="@/assets/css/MenuDialog.css" scoped></style>
+<!-- NamespacesEdit.vue -->
+<template>
+ <div v-if="show" class="modal-overlay" @click="closeModal">
+ <div class="modal-content yaml-editor" @click.stop>
+ <div class="modal-header">
+ <h3>Edit Namespace YAML</h3>
+ <button class="close-button" @click="closeModal">×</button>
+ </div>
+
+ <div class="modal-body">
+ <div v-if="error" class="error-message">{{ error }}</div>
+ <div v-if="isLoading" class="loading-message">Loading namespace YAML...</div>
+
+ <div v-if="!isLoading" class="yaml-container">
+ <textarea
+ v-model="yamlContent"
+ :disabled="isSubmitting"
+ class="yaml-textarea"
+ ></textarea>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <button
+ class="cancel-button"
+ @click="closeModal"
+ :disabled="isSubmitting"
+ >
+ Cancel
+ </button>
+ <button
+ class="update-button"
+ @click="updateNamespace"
+ :disabled="isSubmitting || isLoading || !yamlContent.trim()"
+ >
+ {{ isSubmitting ? 'Updating...' : 'Update Namespace' }}
+ </button>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script lang="ts">
+import { defineComponent, ref, watch, PropType } from 'vue';
+import { KubernetesNamespace, KubernetesCluster } from '../types/kubernetes';
+import { kubernetesService } from '../lib/kubernetes';
+import { namespaceJsonToYaml } from '../lib/lib';
+
+export default defineComponent({
+ name: 'ResourceNamespaceEdit',
+
+ props: {
+ show: {
+ type: Boolean,
+ default: false
+ },
+ namespace: {
+ type: Object as PropType<KubernetesNamespace | null>,
+ default: null
+ },
+ cluster: {
+ type: Object as PropType<KubernetesCluster | null>,
+ default: null
+ }
+ },
+
+ emits: ['close', 'namespace-updated'],
+
+ setup(props, { emit }) {
+ // State
+ const yamlContent = ref('');
+ const isLoading = ref(false);
+ const isSubmitting = ref(false);
+ const error = ref('');
+ const originalNamespaceName = ref('');
+
+ // Watch for changes to show prop
+ watch(() => props.show, (newVal) => {
+ if (newVal && props.namespace) {
+ fetchNamespaceYaml();
+ } else {
+ yamlContent.value = '';
+ error.value = '';
+ }
+ });
+
+ // Methods
+ const closeModal = () => {
+ if (!isSubmitting.value) {
+ emit('close');
+ }
+ };
+
+ const fetchNamespaceYaml = async () => {
+ if (!props.namespace || !props.cluster) return;
+
+ isLoading.value = true;
+ error.value = '';
+
+ originalNamespaceName.value = props.namespace.metadata.name;
+
+ try {
+ const response = await kubernetesService.getNamespace(
+ props.cluster.contextName,
+ originalNamespaceName.value
+ );
+
+ if (response.success) {
+ yamlContent.value = namespaceJsonToYaml(response.data);
+ } else {
+ error.value = response.msg || 'Failed to fetch namespace YAML';
+ }
+ } catch (err: any) {
+ error.value = `Error fetching namespace YAML: ${err.message || err}`;
+ } finally {
+ isLoading.value = false;
+ }
+ };
+
+ const updateNamespace = async () => {
+ if (!props.namespace || !props.cluster) return;
+
+ isSubmitting.value = true;
+ error.value = '';
+
+ try {
+ const response = await kubernetesService.updateNamespace(
+ props.cluster.contextName,
+ yamlContent.value,
+ originalNamespaceName.value
+ );
+
+ if (response.success) {
+ emit('namespace-updated', response);
+ closeModal();
+ } else {
+ error.value = response.msg || 'Failed to update namespace';
+ }
+ } catch (err: any) {
+ error.value = `Failed to update namespace: ${err.message || err}`;
+ } finally {
+ isSubmitting.value = false;
+ }
+ };
+
+ return {
+ yamlContent,
+ isLoading,
+ isSubmitting,
+ error,
+ originalNamespaceName,
+ closeModal,
+ fetchNamespaceYaml,
+ updateNamespace
+ };
+ }
+});
+</script>
+
+<style src="@/assets/css/MenuDialog.css" scoped></style>
+<!-- NamespacesList.vue -->
+<script lang="ts">
+import { defineComponent, ref, computed, PropType, onBeforeUnmount } from 'vue';
+import { KubernetesCluster, KubernetesNamespace } from '../types/kubernetes';
+import { formatAge } from '../lib/format';
+import SearchBar from './SearchBar.vue';
+import NamespacesCreateMethodSelector from './NamespacesCreateMethodSelector.vue';
+import NamespacesCreateGuided from './NamespacesCreateGuided.vue';
+import NamespacesCreateYaml from './NamespacesCreateYaml.vue';
+import NamespacesEdit from './NamespacesEdit.vue';
+
+export default defineComponent({
+ name: 'NamespacesList',
+
+ components: {
+ SearchBar,
+ NamespacesCreateMethodSelector,
+ NamespacesCreateGuided,
+ NamespacesCreateYaml,
+ NamespacesEdit
+ },
+
+ props: {
+ selectedCluster: {
+ type: Object as PropType<KubernetesCluster>,
+ required: false,
+ default: null
+ },
+ namespaces: {
+ type: Array as PropType<KubernetesNamespace[]>,
+ required: false,
+ default: () => []
+ }
+ },
+
+ emits: ['namespace-selected', 'delete-namespace', 'create-namespace'],
+
+ setup(props, { emit }) {
+ // State
+ const searchQuery = ref('');
+ const selectedNamespace = ref<KubernetesNamespace | null>(null);
+ const selectedContextNamespace = ref<KubernetesNamespace | null>(null);
+ const showMenu = ref(false);
+ const menuPosition = ref({ x: 0, y: 0 });
+
+ const showMethodSelector = ref(false);
+ const showCreateGuided = ref(false);
+ const showCreateYaml = ref(false);
+ const showEditYaml = ref(false);
+
+ // Computed properties
+ const filteredNamespaces = computed(() => {
+ if (!searchQuery.value) {
+ return props.namespaces;
+ }
+
+ const query = searchQuery.value.toLowerCase();
+
+ const nameSpecificMatch = query.match(/^name:(.+)$/);
+ if (nameSpecificMatch) {
+ const nameQuery = nameSpecificMatch[1].trim();
+ return props.namespaces.filter(namespace => {
+ const name = namespace.metadata.name.toLowerCase();
+ return name.includes(nameQuery);
+ });
+ }
+
+ const statusSpecificMatch = query.match(/^status:(.+)$/);
+ if (statusSpecificMatch) {
+ const statusQuery = statusSpecificMatch[1].trim();
+ return props.namespaces.filter(namespace => {
+ const status = namespace.status?.phase?.toLowerCase() || '';
+ return status.includes(statusQuery);
+ });
+ }
+
+ const labelSpecificMatch = query.match(/^label:(.+)$/);
+ if (labelSpecificMatch) {
+ const labelQuery = labelSpecificMatch[1].trim();
+ return props.namespaces.filter(namespace => {
+ const labels = namespace.metadata.labels || {};
+ for (const key in labels) {
+ const value = labels[key].toLowerCase();
+ const keyLower = key.toLowerCase();
+
+ // Check for key=value format
+ if (labelQuery.includes('=')) {
+ const [queryKey, queryValue] = labelQuery.split('=');
+ if (keyLower === queryKey.trim().toLowerCase() &&
+ value.includes(queryValue.trim().toLowerCase())) {
+ return true;
+ }
+ }
+ // Check for just key
+ else if (keyLower.includes(labelQuery)) {
+ return true;
+ }
+ }
+ return false;
+ });
+ }
+
+ // Default behavior: search only in namespace names
+ return props.namespaces.filter(namespace => {
+ const name = namespace.metadata.name.toLowerCase();
+ return name.includes(query);
+ });
+ });
+
+ // Methods
+ const hideContextMenu = () => {
+ showMenu.value = false;
+ document.removeEventListener('click', hideContextMenu);
+ };
+
+ const showContextMenu = (event: MouseEvent, namespace: KubernetesNamespace) => {
+ event.preventDefault();
+
+ menuPosition.value = {
+ x: event.clientX,
+ y: event.clientY
+ };
+
+ selectedContextNamespace.value = namespace;
+ selectNamespace(namespace);
+ showMenu.value = true;
+
+ setTimeout(() => {
+ document.addEventListener('click', hideContextMenu);
+ }, 0);
+ };
+
+ const isSelected = (namespace: KubernetesNamespace): boolean => {
+ if (!selectedNamespace.value) return false;
+ return selectedNamespace.value.metadata.name === namespace.metadata.name &&
+ selectedNamespace.value.metadata.uid === namespace.metadata.uid;
+ };
+
+ const selectNamespace = (namespace: KubernetesNamespace): void => {
+ const namespaceToEmit = { ...namespace };
+ if (!namespaceToEmit.kind) {
+ namespaceToEmit.kind = 'Namespace';
+ }
+ selectedNamespace.value = namespaceToEmit;
+ emit('namespace-selected', namespaceToEmit);
+ };
+
+ const deleteNamespace = (): void => {
+ if (selectedContextNamespace.value && props.selectedCluster) {
+ emit('delete-namespace', {
+ cluster: props.selectedCluster,
+ namespace: selectedNamespace.value
+ });
+ }
+ hideContextMenu();
+ };
+
+ const getUniqueKey = (namespace: KubernetesNamespace): string => {
+ return `${namespace.metadata.name}-${namespace.metadata.uid || ''}`;
+ };
+
+ const getNamespaceStatus = (namespace: KubernetesNamespace): string => {
+ return namespace.status?.phase || 'Unknown';
+ };
+
+ const getNamespaceStatusClass = (namespace: KubernetesNamespace): string => {
+ const status = getNamespaceStatus(namespace);
+ switch (status) {
+ case 'Active':
+ return 'status-active';
+ case 'Terminating':
+ return 'status-terminating';
+ default:
+ return 'status-unknown';
+ }
+ };
+
+ const editNamespace = (): void => {
+ showEditYaml.value = true;
+ hideContextMenu();
+ };
+
+ const createNamespace = (): void => {
+ showMethodSelector.value = true;
+ hideContextMenu();
+ };
+
+ const handleMethodSelected = (method: string): void => {
+ showMethodSelector.value = false;
+ if (method === 'guided') {
+ showCreateGuided.value = true;
+ } else if (method === 'yaml') {
+ showCreateYaml.value = true;
+ }
+ };
+
+ const handleUpdateNamespace = (): void => {
+ if (!props.selectedCluster) {
+ return
+ }
+ emit('load-resources')
+ }
+
+ const handleCreateNamespace = ({definition, yamlContent, isYaml}: { definition?: any, yamlContent?: string, isYaml?: boolean}): void => {
+ if (!props.selectedCluster) {
+ return
+ }
+
+ try {
+ let opts = {
+ cluster: props.selectedCluster,
+ isYaml: isYaml,
+ }
+ if (yamlContent) {
+ opts.yamlContent = yamlContent
+ emit('create-namespace', opts)
+ } else if (definition) {
+ opts.definition = definition
+ emit('create-namespace', opts)
+ } else {
+ throw new Error("Unable to emit create-namespace")
+ }
+ } catch (err: any) {
+ console.error('Failed to create namespace:', err)
+ } finally {
+ showCreateGuided.value = false
+ showCreateYaml.value = false
+ }
+ }
+
+ // Lifecycle hooks
+ onBeforeUnmount(() => {
+ document.removeEventListener('click', hideContextMenu);
+ });
+
+ // Return all refs, computed properties, and methods
+ return {
+ // State
+ showMethodSelector,
+ searchQuery,
+ selectedNamespace,
+ selectedContextNamespace,
+ showMenu,
+ showEditYaml,
+ menuPosition,
+ showCreateGuided,
+ showCreateYaml,
+
+ // Computed
+ filteredNamespaces,
+
+ // Methods
+ hideContextMenu,
+ showContextMenu,
+ isSelected,
+ selectNamespace,
+ deleteNamespace,
+ getUniqueKey,
+ getNamespaceStatus,
+ getNamespaceStatusClass,
+ formatAge,
+ handleMethodSelected,
+ createNamespace,
+ editNamespace,
+ handleCreateNamespace,
+ handleUpdateNamespace
+ };
+ }
+});
+</script>
+
+<template>
+ <div class="namespaces-container">
+ <div class="search-bar-container">
+ <SearchBar
+ :value="searchQuery"
+ @update:value="searchQuery = $event"
+ placeholder="Search namespaces..."
+ />
+ </div>
+
+ <div v-if="filteredNamespaces.length === 0" class="no-namespaces">
+ <p v-if="searchQuery">No namespaces found matching "{{ searchQuery }}"</p>
+ <p v-else>No namespaces found.</p>
+ </div>
+
+ <div v-else class="table-scroll-container">
+ <table>
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Status</th>
+ <th>Age</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr
+ v-for="namespace in filteredNamespaces"
+ :key="getUniqueKey(namespace)"
+ :class="{ selected: isSelected(namespace) }"
+ @click="selectNamespace(namespace)"
+ @contextmenu="showContextMenu($event, namespace)"
+ >
+ <td>{{ namespace.metadata.name }}</td>
+ <td :class="getNamespaceStatusClass(namespace)">{{ getNamespaceStatus(namespace) }}</td>
+ <td>{{ formatAge(namespace.metadata.creationTimestamp) }}</td>
+ </tr>
+ </tbody>
+ </table>
+ <div
+ v-if="showMenu"
+ class="context-menu"
+ :style="{ top: menuPosition.y + 'px', left: menuPosition.x + 'px' }"
+ @click.stop
+ >
+ <div class="menu-item" @click="createNamespace">
+ Create
+ </div>
+ <div class="menu-item" @click="editNamespace">
+ Edit
+ </div>
+ <div class="menu-item" @click="deleteNamespace">
+ Delete
+ </div>
+ </div>
+ </div>
+
+ <NamespacesCreateMethodSelector
+ :show="showMethodSelector"
+ @close="showMethodSelector = false"
+ @method-selected="handleMethodSelected"
+ />
+
+ <NamespacesCreateGuided
+ :show="showCreateGuided"
+ @close="showCreateGuided = false"
+ @create-namespace="handleCreateNamespace"
+ />
+
+ <NamespacesCreateYaml
+ :show="showCreateYaml"
+ @close="showCreateYaml = false"
+ @create-namespace="handleCreateNamespace"
+ />
+
+ <NamespacesEdit
+ :show="showEditYaml"
+ :namespace="selectedContextNamespace"
+ :cluster="selectedCluster"
+ @close="showEditYaml = false"
+ @namespace-updated="handleUpdateNamespace"
+ />
+
+ </div>
+</template>
+
+<style src="@/assets/css/NamespacesList.css" scoped></style>
+<template>
+ <div class="nav-pane">
+ <!-- Clusters Section -->
+ <div class="nav-section">
+ <div class="section-header">
+ <span class="section-title">CLUSTERS</span>
+ </div>
+ <ClusterList
+ :clusters="clusters"
+ :selectedCluster="selectedCluster"
+ @select-cluster="handleClusterSelect"
+ />
+ </div>
+
+ <div class="nav-section" v-if="selectedCluster">
+ <div class="section-header">
+ <span class="section-title">WORKLOADS</span>
+ </div>
+ <div class="section-content">
+ <div
+ :class="['nav-item', { active: selectedResource === 'deployments' }]"
+ @click="selectResource('deployments')"
+ >
+ <i class="fas fa-cubes"></i>
+ Deployments
+ </div>
+ <div
+ :class="['nav-item', { active: selectedResource === 'statefulsets' }]"
+ @click="selectResource('statefulsets')"
+ >
+ <i class="fas fa-cubes"></i>
+ StatefulSets
+ </div>
+ <div
+ :class="['nav-item', { active: selectedResource === 'pods' }]"
+ @click="selectResource('pods')"
+ >
+ <i class="fas fa-cube"></i>
+ Pods
+ </div>
+ </div>
+ </div>
+
+ <div class="nav-section" v-if="selectedCluster">
+ <div class="section-header">
+ <span class="section-title">CONFIGURATION</span>
+ </div>
+ <div class="section-content">
+ <div
+ :class="['nav-item', { active: selectedResource === 'namespaces' }]"
+ @click="selectResource('namespaces')"
+ >
+ <i class="fas fa-cubes"></i>
+ Namespaces
+ </div>
+ <div
+ :class="['nav-item', { active: selectedResource === 'configmaps' }]"
+ @click="selectResource('configmaps')"
+ >
+ <i class="fas fa-cubes"></i>
+ ConfigMaps
+ </div>
+ <div
+ :class="['nav-item', { active: selectedResource === 'secrets' }]"
+ @click="selectResource('secrets')"
+ >
+ <i class="fas fa-cubes"></i>
+ Secrets
+ </div>
+ </div>
+ </div>
+
+ <div class="nav-section" v-if="selectedCluster">
+ <div class="section-header">
+ <span class="section-title">NETWORKING</span>
+ </div>
+ <div class="section-content">
+ <div
+ :class="['nav-item', { active: selectedResource === 'ingresses' }]"
+ @click="selectResource('ingresses')"
+ >
+ <i class="fas fa-cubes"></i>
+ Ingress
+ </div>
+ </div>
+ </div>
+
+ <div class="nav-section" v-if="selectedCluster">
+ <div class="section-header">
+ <span class="section-title">STORAGE</span>
+ </div>
+ <div class="section-content">
+ <div
+ :class="['nav-item', { active: selectedResource === 'persistentvolumeclaims' }]"
+ @click="selectResource('persistentvolumeclaims')"
+ >
+ <i class="fas fa-cubes"></i>
+ Volume Claims
+ </div>
+ </div>
+ <div class="section-content">
+ <div
+ :class="['nav-item', { active: selectedResource === 'persistentVolumes' }]"
+ @click="selectResource('persistentVolumes')"
+ >
+ <i class="fas fa-cubes"></i>
+ Volumes
+ </div>
+ </div>
+ </div>
+
+ </div>
+</template>
+
+<script lang="ts">
+import { defineComponent, PropType } from 'vue';
+import { KubernetesCluster } from '../types/kubernetes';
+import ClusterList from './ClusterList.vue';
+
+export default defineComponent({
+ name: 'NavigationPane',
+
+ components: {
+ ClusterList
+ },
+
+ props: {
+ clusters: {
+ type: Array as PropType<KubernetesCluster[]>,
+ required: true,
+ default: () => []
+ },
+ selectedCluster: {
+ type: Object as PropType<KubernetesCluster | null>,
+ required: false,
+ default: null
+ },
+ selectedResource: {
+ type: String as PropType<String | null>,
+ required: false,
+ default: null
+ }
+ },
+ emits: ['select-cluster', 'select-resource'],
+ methods: {
+ handleClusterSelect(cluster: KubernetesCluster) {
+ this.$emit('select-cluster', cluster);
+ },
+
+ selectResource(resource: string) {
+ this.$emit('select-resource', resource);
+ }
+ }
+});
+</script>
+
+<style src="@/assets/css/NavigationPane.css" scoped></style>
+<!-- PersistentVolumeClaimsCreateGuided.vue -->
+<template>
+ <div v-if="show" class="modal-overlay" @click="closeModal">
+ <div class="modal-content" @click.stop>
+ <div class="modal-header">
+ <h3>Create Persistent Volume Claim</h3>
+ <button class="close-button" @click="closeModal">×</button>
+ </div>
+
+ <div class="modal-body">
+ <div v-if="error" class="error-message">{{ error }}</div>
+
+ <div class="form-group">
+ <label for="name">Name:</label>
+ <input
+ id="name"
+ v-model="name"
+ type="text"
+ placeholder="my-pvc"
+ :disabled="isSubmitting"
+ />
+ </div>
+
+ <div class="form-group">
+ <label for="namespace">Namespace:</label>
+ <input
+ id="namespace"
+ v-model="namespace"
+ type="text"
+ placeholder="default"
+ :disabled="isSubmitting"
+ />
+ </div>
+
+ <div class="form-group">
+ <label for="storageClass">Storage Class:</label>
+ <input
+ id="storageClass"
+ v-model="storageClass"
+ type="text"
+ placeholder="standard"
+ :disabled="isSubmitting"
+ />
+ <small class="field-hint">Leave empty to use default storage class</small>
+ </div>
+
+ <div class="form-group">
+ <label for="storageSize">Storage Size:</label>
+ <div class="storage-input-group">
+ <input
+ id="storageSize"
+ v-model="storageSize"
+ type="number"
+ min="1"
+ placeholder="1"
+ :disabled="isSubmitting"
+ />
+ <select v-model="storageUnit" :disabled="isSubmitting">
+ <option value="Gi">Gi</option>
+ <option value="Mi">Mi</option>
+ <option value="Ti">Ti</option>
+ </select>
+ </div>
+ </div>
+
+ <div class="form-section">
+ <h4>Access Modes</h4>
+ <div class="checkbox-group">
+ <label class="checkbox-label">
+ <input
+ type="checkbox"
+ v-model="accessModes"
+ value="ReadWriteOnce"
+ :disabled="isSubmitting"
+ />
+ ReadWriteOnce (RWO)
+ <small>Volume can be mounted as read-write by a single node</small>
+ </label>
+ <label class="checkbox-label">
+ <input
+ type="checkbox"
+ v-model="accessModes"
+ value="ReadOnlyMany"
+ :disabled="isSubmitting"
+ />
+ ReadOnlyMany (ROX)
+ <small>Volume can be mounted read-only by many nodes</small>
+ </label>
+ <label class="checkbox-label">
+ <input
+ type="checkbox"
+ v-model="accessModes"
+ value="ReadWriteMany"
+ :disabled="isSubmitting"
+ />
+ ReadWriteMany (RWX)
+ <small>Volume can be mounted as read-write by many nodes</small>
+ </label>
+ <label class="checkbox-label">
+ <input
+ type="checkbox"
+ v-model="accessModes"
+ value="ReadWriteOncePod"
+ :disabled="isSubmitting"
+ />
+ ReadWriteOncePod (RWOP)
+ <small>Volume can be mounted as read-write by a single pod</small>
+ </label>
+ </div>
+ </div>
+
+ <div class="form-section">
+ <h4>Volume Mode</h4>
+ <div class="radio-group">
+ <label class="radio-label">
+ <input
+ type="radio"
+ v-model="volumeMode"
+ value="Filesystem"
+ :disabled="isSubmitting"
+ />
+ Filesystem
+ <small>Volume is mounted into pods as a directory</small>
+ </label>
+ <label class="radio-label">
+ <input
+ type="radio"
+ v-model="volumeMode"
+ value="Block"
+ :disabled="isSubmitting"
+ />
+ Block
+ <small>Volume is used as a raw block device</small>
+ </label>
+ </div>
+ </div>
+
+ <div class="form-section">
+ <h4>Labels (Optional)</h4>
+ <div
+ v-for="(label, index) in labels"
+ :key="index"
+ class="label-row"
+ >
+ <div class="form-group key-field">
+ <input
+ v-model="label.key"
+ type="text"
+ placeholder="key"
+ :disabled="isSubmitting"
+ />
+ </div>
+ <div class="form-group value-field">
+ <input
+ v-model="label.value"
+ type="text"
+ placeholder="value"
+ :disabled="isSubmitting"
+ />
+ </div>
+ <button
+ class="remove-button"
+ @click="removeLabel(index)"
+ :disabled="isSubmitting || labels.length <= 1"
+ >
+ ×
+ </button>
+ </div>
+
+ <button
+ class="add-button"
+ @click="addLabel"
+ :disabled="isSubmitting"
+ >
+ + Add Label
+ </button>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <button
+ class="cancel-button"
+ @click="closeModal"
+ :disabled="isSubmitting"
+ >
+ Cancel
+ </button>
+ <button
+ class="create-button"
+ @click="createPvc"
+ :disabled="!isFormValid || isSubmitting"
+ >
+ {{ isSubmitting ? 'Creating...' : 'Create PVC' }}
+ </button>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script lang="ts">
+import { defineComponent, ref, computed, PropType } from 'vue';
+import { PersistentVolumeClaimCreateOptions } from '../types/custom';
+import { KubernetesCluster } from '../types/kubernetes';
+
+export default defineComponent({
+ name: 'PersistentVolumeClaimsCreateGuided',
+
+ props: {
+ show: {
+ type: Boolean,
+ required: true
+ },
+ cluster: {
+ type: Object as PropType<KubernetesCluster | null>,
+ required: false,
+ default: null
+ }
+ },
+
+ emits: ['close', 'create-pvc'],
+
+ setup(props, { emit }) {
+ const name = ref('');
+ const namespace = ref('default');
+ const storageClass = ref('');
+ const storageSize = ref(1);
+ const storageUnit = ref('Gi');
+ const accessModes = ref(['ReadWriteOnce']);
+ const volumeMode = ref('Filesystem');
+ const isSubmitting = ref(false);
+ const error = ref('');
+ const labels = ref([{ key: '', value: '' }]);
+
+ const isFormValid = computed(() => {
+ if (!name.value.trim()) return false;
+ if (!namespace.value.trim()) return false;
+ if (!storageSize.value || storageSize.value <= 0) return false;
+ if (accessModes.value.length === 0) return false;
+ return true;
+ });
+
+ const addLabel = () => {
+ labels.value.push({ key: '', value: '' });
+ };
+
+ const removeLabel = (index: number) => {
+ if (labels.value.length > 1) {
+ labels.value.splice(index, 1);
+ }
+ };
+
+ const resetForm = () => {
+ name.value = '';
+ namespace.value = 'default';
+ storageClass.value = '';
+ storageSize.value = 1;
+ storageUnit.value = 'Gi';
+ accessModes.value = ['ReadWriteOnce'];
+ volumeMode.value = 'Filesystem';
+ labels.value = [{ key: '', value: '' }];
+ error.value = '';
+ isSubmitting.value = false;
+ };
+
+ const closeModal = () => {
+ resetForm();
+ emit('close');
+ };
+
+ const createPvc = () => {
+ if (!name.value.trim()) {
+ error.value = 'Name is required';
+ return;
+ }
+
+ if (!namespace.value.trim()) {
+ error.value = 'Namespace is required';
+ return;
+ }
+
+ if (!props.cluster) {
+ error.value = 'No cluster selected';
+ return;
+ }
+
+ if (!storageSize.value || storageSize.value <= 0) {
+ error.value = 'Storage size must be greater than 0';
+ return;
+ }
+
+ if (accessModes.value.length === 0) {
+ error.value = 'At least one access mode must be selected';
+ return;
+ }
+
+ isSubmitting.value = true;
+
+ // Build labels object
+ const labelsObj = {};
+ labels.value.forEach(label => {
+ if (label.key.trim() && label.value.trim()) {
+ labelsObj[label.key.trim()] = label.value.trim();
+ }
+ });
+
+ // Build PVC spec
+ const spec: any = {
+ accessModes: accessModes.value,
+ resources: {
+ requests: {
+ storage: `${storageSize.value}${storageUnit.value}`
+ }
+ },
+ volumeMode: volumeMode.value
+ };
+
+ // Add storage class if specified
+ if (storageClass.value.trim()) {
+ spec.storageClassName = storageClass.value.trim();
+ }
+
+ // Build metadata
+ const metadata: any = {
+ name: name.value.trim(),
+ namespace: namespace.value.trim()
+ };
+
+ // Add labels if any
+ if (Object.keys(labelsObj).length > 0) {
+ metadata.labels = labelsObj;
+ }
+
+ const opts: PersistentVolumeClaimCreateOptions = {
+ context: props.cluster.contextName,
+ opts: {
+ definition: {
+ apiVersion: 'v1',
+ kind: 'PersistentVolumeClaim',
+ metadata: metadata,
+ spec: spec
+ },
+ isYaml: false
+ }
+ };
+
+ emit('create-pvc', opts);
+ resetForm();
+ closeModal();
+ };
+
+ return {
+ name,
+ namespace,
+ storageClass,
+ storageSize,
+ storageUnit,
+ accessModes,
+ volumeMode,
+ labels,
+ isSubmitting,
+ error,
+ isFormValid,
+ addLabel,
+ removeLabel,
+ closeModal,
+ createPvc
+ };
+ }
+});
+</script>
+
+<style src="@/assets/css/CreateResource.css" scoped></style>
+
+<style scoped>
+.storage-input-group {
+ display: flex;
+ gap: 0.5rem;
+}
+
+.storage-input-group input {
+ flex: 1;
+}
+
+.storage-input-group select {
+ width: 80px;
+ padding: 0.5rem;
+ border: 1px solid #444;
+ border-radius: 4px;
+ background-color: #2d2d2d;
+ color: #ffffff;
+}
+
+.checkbox-group {
+ display: flex;
+ flex-direction: column;
+ gap: 0.75rem;
+}
+
+.checkbox-label {
+ display: flex;
+ flex-direction: column;
+ gap: 0.25rem;
+ cursor: pointer;
+}
+
+.checkbox-label input[type="checkbox"] {
+ width: auto;
+ margin-right: 0.5rem;
+}
+
+.radio-group {
+ display: flex;
+ flex-direction: column;
+ gap: 0.75rem;
+}
+
+.radio-label {
+ display: flex;
+ flex-direction: column;
+ gap: 0.25rem;
+ cursor: pointer;
+}
+
+.radio-label input[type="radio"] {
+ width: auto;
+ margin-right: 0.5rem;
+}
+
+.field-hint {
+ color: #999;
+ font-size: 0.8rem;
+ margin-top: 0.25rem;
+ display: block;
+}
+
+.label-row {
+ display: flex;
+ gap: 0.5rem;
+ align-items: flex-start;
+ margin-bottom: 0.5rem;
+}
+
+.key-field,
+.value-field {
+ flex: 1;
+ margin-bottom: 0;
+}
+
+.remove-button {
+ background-color: #dc3545;
+ border: 1px solid #dc3545;
+ color: white;
+ border-radius: 4px;
+ width: 30px;
+ height: 30px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-top: 1.5rem;
+}
+
+.remove-button:hover:not(:disabled) {
+ background-color: #c82333;
+}
+
+.remove-button:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+}
+
+.add-button {
+ background-color: #28a745;
+ border: 1px solid #28a745;
+ color: white;
+ padding: 0.5rem 1rem;
+ border-radius: 4px;
+ cursor: pointer;
+ margin-top: 0.5rem;
+}
+
+.add-button:hover:not(:disabled) {
+ background-color: #218838;
+}
+
+.add-button:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+}
+</style>
+
+<!-- PersistentVolumeClaimsCreateYaml.vue -->
+<template>
+ <div v-if="show" class="modal-overlay" @click="closeModal">
+ <div class="modal-content yaml-editor" @click.stop>
+ <div class="modal-header">
+ <h3>Create Persistent Volume Claim - YAML</h3>
+ <button class="close-button" @click="closeModal">×</button>
+ </div>
+
+ <div class="modal-body">
+ <div v-if="error" class="error-message">{{ error }}</div>
+
+ <div class="yaml-container">
+ <textarea
+ v-model="yamlContent"
+ :disabled="isSubmitting"
+ class="yaml-textarea"
+ placeholder="Enter your PersistentVolumeClaim YAML here..."
+ ></textarea>
+ </div>
+
+ <div class="template-section">
+ <button
+ class="template-button"
+ @click="loadTemplate"
+ :disabled="isSubmitting"
+ >
+ Load Template
+ </button>
+ <span class="template-hint">Click to load a basic PVC template</span>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <button
+ class="cancel-button"
+ @click="closeModal"
+ :disabled="isSubmitting"
+ >
+ Cancel
+ </button>
+ <button
+ class="create-button"
+ @click="createPvc"
+ :disabled="isSubmitting || !yamlContent.trim()"
+ >
+ {{ isSubmitting ? 'Creating...' : 'Create PVC' }}
+ </button>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script lang="ts">
+import { defineComponent, ref } from 'vue';
+import { PersistentVolumeClaimCreateOptions } from '../types/custom';
+
+export default defineComponent({
+ name: 'PersistentVolumeClaimsCreateYaml',
+
+ props: {
+ show: {
+ type: Boolean,
+ required: true
+ }
+ },
+
+ emits: ['close', 'create-pvc'],
+
+ setup(props, { emit }) {
+ // State
+ const yamlContent = ref('');
+ const isSubmitting = ref(false);
+ const error = ref('');
+
+ // Template YAML for PVC
+ const pvcTemplate = `apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: my-pvc
+ namespace: default
+spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 1Gi
+ storageClassName: standard`;
+
+ // Methods
+ const closeModal = () => {
+ if (!isSubmitting.value) {
+ resetForm();
+ emit('close');
+ }
+ };
+
+ const resetForm = () => {
+ yamlContent.value = '';
+ error.value = '';
+ isSubmitting.value = false;
+ };
+
+ const loadTemplate = () => {
+ yamlContent.value = pvcTemplate;
+ error.value = '';
+ };
+
+ const validateYaml = (yaml: string): boolean => {
+ try {
+ // Basic validation - check if it looks like a PVC
+ const trimmed = yaml.trim();
+ if (!trimmed) {
+ error.value = 'YAML content cannot be empty';
+ return false;
+ }
+
+ // Check for required fields
+ if (!trimmed.includes('kind:') || !trimmed.includes('PersistentVolumeClaim')) {
+ error.value = 'YAML must contain "kind: PersistentVolumeClaim"';
+ return false;
+ }
+
+ if (!trimmed.includes('apiVersion:')) {
+ error.value = 'YAML must contain "apiVersion"';
+ return false;
+ }
+
+ if (!trimmed.includes('metadata:')) {
+ error.value = 'YAML must contain "metadata" section';
+ return false;
+ }
+
+ if (!trimmed.includes('spec:')) {
+ error.value = 'YAML must contain "spec" section';
+ return false;
+ }
+
+ return true;
+ } catch (err) {
+ error.value = 'Invalid YAML format';
+ return false;
+ }
+ };
+
+ const createPvc = () => {
+ error.value = '';
+
+ if (!yamlContent.value.trim()) {
+ error.value = 'YAML content is required';
+ return;
+ }
+
+ if (!validateYaml(yamlContent.value)) {
+ return;
+ }
+
+ isSubmitting.value = true;
+
+ try {
+ const opts: PersistentVolumeClaimCreateOptions = {
+ context: '', // This will be set by the parent component
+ opts: {
+ yamlContent: yamlContent.value.trim(),
+ isYaml: true
+ }
+ };
+
+ emit('create-pvc', opts);
+ resetForm();
+ closeModal();
+ } catch (err: any) {
+ error.value = `Failed to create PVC: ${err.message || err}`;
+ isSubmitting.value = false;
+ }
+ };
+
+ return {
+ yamlContent,
+ isSubmitting,
+ error,
+ closeModal,
+ loadTemplate,
+ createPvc
+ };
+ }
+});
+</script>
+
+<style src="@/assets/css/MenuDialog.css" scoped></style>
+
+<style scoped>
+.yaml-container {
+ margin-bottom: 1rem;
+}
+
+.yaml-textarea {
+ width: 100%;
+ height: 400px;
+ padding: 1rem;
+ border: 1px solid #444;
+ border-radius: 4px;
+ background-color: #1e1e1e;
+ color: #ffffff;
+ font-family: 'Courier New', Consolas, monospace;
+ font-size: 14px;
+ line-height: 1.4;
+ resize: vertical;
+ min-height: 300px;
+ max-height: 600px;
+}
+
+.yaml-textarea:focus {
+ outline: none;
+ border-color: #007acc;
+ box-shadow: 0 0 0 2px rgba(0, 122, 204, 0.2);
+}
+
+.yaml-textarea:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+
+.yaml-textarea::placeholder {
+ color: #666;
+ font-style: italic;
+}
+
+.template-section {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ margin-bottom: 1rem;
+ padding: 0.75rem;
+ background-color: #333;
+ border-radius: 4px;
+ border: 1px solid #444;
+}
+
+.template-button {
+ padding: 0.5rem 1rem;
+ border: 1px solid #007acc;
+ background-color: #007acc;
+ color: white;
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 0.9rem;
+ transition: all 0.2s;
+}
+
+.template-button:hover:not(:disabled) {
+ background-color: #005a9e;
+ border-color: #005a9e;
+}
+
+.template-button:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+
+.template-hint {
+ color: #ccc;
+ font-size: 0.85rem;
+ font-style: italic;
+}
+
+.error-message {
+ background-color: #4a1a1a;
+ border: 1px solid #cc4444;
+ color: #ff6b6b;
+ padding: 0.75rem;
+ border-radius: 4px;
+ margin-bottom: 1rem;
+ font-size: 0.9rem;
+}
+
+.modal-footer {
+ display: flex;
+ justify-content: flex-end;
+ gap: 0.5rem;
+ padding: 1rem 1.5rem;
+ border-top: 1px solid #444;
+}
+
+.cancel-button {
+ padding: 0.5rem 1rem;
+ border: 1px solid #666;
+ background-color: transparent;
+ color: #ccc;
+ border-radius: 4px;
+ cursor: pointer;
+ transition: all 0.2s;
+}
+
+.cancel-button:hover:not(:disabled) {
+ background-color: #444;
+ border-color: #777;
+}
+
+.create-button {
+ padding: 0.5rem 1rem;
+ border: 1px solid #28a745;
+ background-color: #28a745;
+ color: white;
+ border-radius: 4px;
+ cursor: pointer;
+ transition: all 0.2s;
+}
+
+.create-button:hover:not(:disabled) {
+ background-color: #218838;
+ border-color: #1e7e34;
+}
+
+.create-button:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+
+/* Responsive design */
+@media (max-width: 768px) {
+ .yaml-textarea {
+ height: 300px;
+ font-size: 12px;
+ }
+
+ .template-section {
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 0.5rem;
+ }
+
+ .template-button {
+ font-size: 0.8rem;
+ padding: 0.4rem 0.8rem;
+ }
+}
+</style>
+
+<!-- PersistentVolumeClaimsEdit.vue -->
+<template>
+ <div v-if="show" class="modal-overlay" @click="closeModal">
+ <div class="modal-content yaml-editor" @click.stop>
+ <div class="modal-header">
+ <h3>Edit Persistent Volume Claim</h3>
+ <button class="close-button" @click="closeModal">×</button>
+ </div>
+
+ <div class="modal-body">
+ <div v-if="error" class="error-message">{{ error }}</div>
+
+ <div v-if="pvc" class="resource-info">
+ <div class="info-item">
+ <strong>Name:</strong> {{ pvc.metadata.name }}
+ </div>
+ <div class="info-item">
+ <strong>Namespace:</strong> {{ pvc.metadata.namespace }}
+ </div>
+ <div class="info-item">
+ <strong>Status:</strong> {{ pvc.status?.phase || 'Unknown' }}
+ </div>
+ </div>
+
+ <div class="yaml-container">
+ <textarea
+ v-model="yamlContent"
+ :disabled="isSubmitting"
+ class="yaml-textarea"
+ placeholder="Loading PVC YAML..."
+ ></textarea>
+ </div>
+
+ <div class="warning-section">
+ <div class="warning-message">
+ <strong>⚠️ Warning:</strong> Editing a PVC may have limitations. Some fields like storage size can only be increased (if supported by storage class), and access modes cannot be changed after creation.
+ </div>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <button
+ class="cancel-button"
+ @click="closeModal"
+ :disabled="isSubmitting"
+ >
+ Cancel
+ </button>
+ <button
+ class="update-button"
+ @click="updatePvc"
+ :disabled="isSubmitting || !yamlContent.trim() || !hasChanges"
+ >
+ {{ isSubmitting ? 'Updating...' : 'Update PVC' }}
+ </button>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script lang="ts">
+import { defineComponent, ref, computed, watch, PropType } from 'vue';
+import { KubernetesCluster, KubernetesPersistentVolumeClaim } from '../types/kubernetes';
+import { PersistentVolumeClaimUpdateOptions } from '../types/custom';
+
+export default defineComponent({
+ name: 'PersistentVolumeClaimsEdit',
+
+ props: {
+ show: {
+ type: Boolean,
+ required: true
+ },
+ pvc: {
+ type: Object as PropType<KubernetesPersistentVolumeClaim | null>,
+ required: false,
+ default: null
+ },
+ cluster: {
+ type: Object as PropType<KubernetesCluster | null>,
+ required: false,
+ default: null
+ }
+ },
+
+ emits: ['close', 'update-pvc'],
+
+ setup(props, { emit }) {
+ // State
+ const yamlContent = ref('');
+ const originalYaml = ref('');
+ const isSubmitting = ref(false);
+ const error = ref('');
+
+ // Computed
+ const hasChanges = computed(() => {
+ return yamlContent.value.trim() !== originalYaml.value.trim();
+ });
+
+ // Methods
+ const closeModal = () => {
+ if (!isSubmitting.value) {
+ resetForm();
+ emit('close');
+ }
+ };
+
+ const resetForm = () => {
+ yamlContent.value = '';
+ originalYaml.value = '';
+ error.value = '';
+ isSubmitting.value = false;
+ };
+
+ const convertToYaml = (obj: any): string => {
+ try {
+ // Simple YAML conversion - in a real app, you'd use a proper YAML library
+ const cleanObj = JSON.parse(JSON.stringify(obj));
+
+ // Remove fields that shouldn't be edited
+ if (cleanObj.metadata) {
+ delete cleanObj.metadata.resourceVersion;
+ delete cleanObj.metadata.uid;
+ delete cleanObj.metadata.selfLink;
+ delete cleanObj.metadata.creationTimestamp;
+ delete cleanObj.metadata.generation;
+ delete cleanObj.metadata.managedFields;
+ }
+
+ // Remove status as it's read-only
+ delete cleanObj.status;
+
+ return JSON.stringify(cleanObj, null, 2)
+ .replace(/"/g, '')
+ .replace(/,$/gm, '')
+ .replace(/\{/g, '')
+ .replace(/\}/g, '')
+ .replace(/\[/g, '')
+ .replace(/\]/g, '')
+ .replace(/^\s*$/gm, '')
+ .split('\n')
+ .filter(line => line.trim())
+ .map(line => {
+ const indent = ' '.repeat((line.match(/^\s*/)?.[0]?.length || 0) / 2);
+ const content = line.trim();
+ if (content.endsWith(':')) {
+ return `${indent}${content}`;
+ }
+ const [key, ...valueParts] = content.split(':');
+ const value = valueParts.join(':').trim();
+ return value ? `${indent}${key}: ${value}` : `${indent}${key}:`;
+ })
+ .join('\n');
+ } catch (err) {
+ console.error('Error converting to YAML:', err);
+ return JSON.stringify(obj, null, 2);
+ }
+ };
+
+ const loadPvcYaml = () => {
+ if (!props.pvc) {
+ yamlContent.value = '';
+ originalYaml.value = '';
+ return;
+ }
+
+ try {
+ const yaml = convertToYaml(props.pvc);
+ yamlContent.value = yaml;
+ originalYaml.value = yaml;
+ error.value = '';
+ } catch (err: any) {
+ error.value = `Failed to load PVC YAML: ${err.message || err}`;
+ yamlContent.value = '';
+ originalYaml.value = '';
+ }
+ };
+
+ const validateYaml = (yaml: string): boolean => {
+ try {
+ const trimmed = yaml.trim();
+ if (!trimmed) {
+ error.value = 'YAML content cannot be empty';
+ return false;
+ }
+
+ // Basic validation for PVC
+ if (!trimmed.includes('kind:') || !trimmed.includes('PersistentVolumeClaim')) {
+ error.value = 'YAML must contain "kind: PersistentVolumeClaim"';
+ return false;
+ }
+
+ if (!trimmed.includes('apiVersion:')) {
+ error.value = 'YAML must contain "apiVersion"';
+ return false;
+ }
+
+ if (!trimmed.includes('metadata:')) {
+ error.value = 'YAML must contain "metadata" section';
+ return false;
+ }
+
+ if (!trimmed.includes('spec:')) {
+ error.value = 'YAML must contain "spec" section';
+ return false;
+ }
+
+ return true;
+ } catch (err) {
+ error.value = 'Invalid YAML format';
+ return false;
+ }
+ };
+
+ const updatePvc = (): void => {
+ if (!props.pvc || !props.cluster) {
+ error.value = 'Missing PVC or cluster information';
+ return;
+ }
+
+ error.value = '';
+
+ if (!yamlContent.value.trim()) {
+ error.value = 'YAML content is required';
+ return;
+ }
+
+ if (!validateYaml(yamlContent.value)) {
+ return;
+ }
+
+ if (!hasChanges.value) {
+ error.value = 'No changes detected';
+ return;
+ }
+
+ isSubmitting.value = true;
+
+ try {
+ const opts: PersistentVolumeClaimUpdateOptions = {
+ context: props.cluster.contextName,
+ definition: yamlContent.value.trim(),
+ origNamespace: props.pvc.metadata.namespace,
+ origName: props.pvc.metadata.name
+ };
+
+ emit('update-pvc', opts);
+ closeModal();
+ } catch (err: any) {
+ error.value = `Failed to update PVC: ${err.message || err}`;
+ isSubmitting.value = false;
+ }
+ };
+
+ // Watchers
+ watch(() => props.show, (newShow) => {
+ if (newShow && props.pvc) {
+ loadPvcYaml();
+ }
+ });
+
+ watch(() => props.pvc, (newPvc) => {
+ if (newPvc && props.show) {
+ loadPvcYaml();
+ }
+ });
+
+ return {
+ yamlContent,
+ isSubmitting,
+ error,
+ hasChanges,
+ closeModal,
+ updatePvc
+ };
+ }
+});
+</script>
+
+<style src="@/assets/css/MenuDialog.css" scoped></style>
+
+<style scoped>
+.resource-info {
+ background-color: #333;
+ border: 1px solid #444;
+ border-radius: 4px;
+ padding: 1rem;
+ margin-bottom: 1rem;
+}
+
+.info-item {
+ margin-bottom: 0.5rem;
+ color: #ccc;
+}
+
+.info-item:last-child {
+ margin-bottom: 0;
+}
+
+.info-item strong {
+ color: #fff;
+ margin-right: 0.5rem;
+}
+
+.yaml-container {
+ margin-bottom: 1rem;
+}
+
+.yaml-textarea {
+ width: 100%;
+ height: 400px;
+ padding: 1rem;
+ border: 1px solid #444;
+ border-radius: 4px;
+ background-color: #1e1e1e;
+ color: #ffffff;
+ font-family: 'Courier New', Consolas, monospace;
+ font-size: 14px;
+ line-height: 1.4;
+ resize: vertical;
+ min-height: 300px;
+ max-height: 600px;
+}
+
+.yaml-textarea:focus {
+ outline: none;
+ border-color: #007acc;
+ box-shadow: 0 0 0 2px rgba(0, 122, 204, 0.2);
+}
+
+.yaml-textarea:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+
+.yaml-textarea::placeholder {
+ color: #666;
+ font-style: italic;
+}
+
+.warning-section {
+ margin-bottom: 1rem;
+}
+
+.warning-message {
+ background-color: #4a3a1a;
+ border: 1px solid #cc9944;
+ color: #ffcc66;
+ padding: 0.75rem;
+ border-radius: 4px;
+ font-size: 0.9rem;
+ line-height: 1.4;
+}
+
+.error-message {
+ background-color: #4a1a1a;
+ border: 1px solid #cc4444;
+ color: #ff6b6b;
+ padding: 0.75rem;
+ border-radius: 4px;
+ margin-bottom: 1rem;
+ font-size: 0.9rem;
+}
+
+.modal-footer {
+ display: flex;
+ justify-content: flex-end;
+ gap: 0.5rem;
+ padding: 1rem 1.5rem;
+ border-top: 1px solid #444;
+}
+
+.cancel-button {
+ padding: 0.5rem 1rem;
+ border: 1px solid #666;
+ background-color: transparent;
+ color: #ccc;
+ border-radius: 4px;
+ cursor: pointer;
+ transition: all 0.2s;
+}
+
+.cancel-button:hover:not(:disabled) {
+ background-color: #444;
+ border-color: #777;
+}
+
+.update-button {
+ padding: 0.5rem 1rem;
+ border: 1px solid #007acc;
+ background-color: #007acc;
+ color: white;
+ border-radius: 4px;
+ cursor: pointer;
+ transition: all 0.2s;
+}
+
+.update-button:hover:not(:disabled) {
+ background-color: #005a9e;
+ border-color: #005a9e;
+}
+
+.update-button:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+
+/* Responsive design */
+@media (max-width: 768px) {
+ .yaml-textarea {
+ height: 300px;
+ font-size: 12px;
+ }
+
+ .resource-info {
+ padding: 0.75rem;
+ }
+
+ .info-item {
+ font-size: 0.9rem;
+ }
+}
+</style>
+
+<!-- PersistentVolumeClaimsList.vue -->
+<script lang="ts">
+import { defineComponent, ref, computed, PropType, onBeforeUnmount } from 'vue';
+import { KubernetesCluster, KubernetesPersistentVolumeClaim } from '../types/kubernetes';
+import { formatAge } from '../lib/format';
+import SearchBar from './SearchBar.vue';
+import { PersistentVolumeClaimUpdateOptions } from '../types/custom';
+
+export default defineComponent({
+ name: 'PersistentVolumeClaimsList',
+
+ components: {
+ SearchBar
+ },
+
+ props: {
+ selectedCluster: {
+ type: Object as PropType<KubernetesCluster>,
+ required: false,
+ default: null
+ },
+ persistentvolumeclaims: {
+ type: Array as PropType<KubernetesPersistentVolumeClaim[]>,
+ required: false,
+ default: () => []
+ }
+ },
+
+ emits: ['persistentVolumeClaim-selected', 'delete-persistentvolumeclaim', 'create-persistentvolumeclaim'],
+
+ setup(props, { emit }) {
+ // State
+ const showCreate = ref(false);
+ const isSubmitting = ref(false);
+ const searchQuery = ref('');
+ const selectedPersistentVolumeClaim = ref<KubernetesPersistentVolumeClaim | null>(null);
+ const selectedContextPersistentVolumeClaim = ref<KubernetesPersistentVolumeClaim | null>(null);
+ const showMenu = ref(false);
+ const menuPosition = ref({ x: 0, y: 0 });
+
+ const formName = ref('');
+ const formNamespace = ref('');
+ const formStorageClass = ref('local-path');
+ const formAccessModes = ref(['ReadWriteOnce']);
+ const formCapacity = ref('10');
+ const formCapacityUnit = ref('Gi');
+ const formError = ref('');
+
+ const resetForm = () => {
+ formName.value = '';
+ formNamespace.value = '';
+ formStorageClass.value = '';
+ formError.value = '';
+ formAccessModes.value = ['ReadWriteOnce'];
+ formCapacity.value = '';
+ formCapacityUnit.value = '';
+ isSubmitting.value = false;
+ };
+
+ const cancelForm = (): void => {
+ resetForm();
+ closeModal();
+ }
+
+ const createPersistentVolumeClaim = (): void => {
+ if (!formName.value.trim()) {
+ formError.value = 'Name is required';
+ return;
+ }
+
+ if (!formNamespace.value.trim()) {
+ formError.value = 'Namespace is required';
+ return;
+ }
+
+ if (!formStorageClass.value.trim()) {
+ formError.value = 'Storage Class is required';
+ return;
+ }
+
+ if (!formCapacity.value) {
+ formError.value = 'Capacity is required';
+ return;
+ }
+
+ if (formCapacity.value <= 0) {
+ formError.value = 'Capacity must be 1 or greater';
+ return;
+ }
+
+ if (formAccessModes.value.length === 0) {
+ formError.value = 'Access Modes is required';
+ return;
+ }
+
+ const persistentVolumeClaim: KubernetesPersistentVolumeClaim = {
+ apiVersion: 'v1',
+ kind: 'PersistentVolumeClaim',
+ metadata: {
+ name: formName.value.trim(),
+ namespace: formNamespace.value.trim(),
+ },
+ spec: {
+ storageClassName: formStorageClass.value.trim(),
+ accessModes: formAccessModes.value,
+ resources: {
+ requests: {
+ storage: `${formCapacity.value}${formCapacityUnit.value}`,
+ }
+ }
+ }
+ };
+
+ isSubmitting.value = true;
+ resetForm();
+ closeModal();
+ hideContextMenu();
+ if (props.selectedCluster) {
+ try {
+ emit('create-persistentvolumeclaim', {
+ cluster: props.selectedCluster,
+ persistentVolumeClaim: persistentVolumeClaim
+ });
+ } catch (error) {
+ alert(error);
+ }
+ } else {
+ alert("Failed to get selected cluster");
+ }
+ resetForm();
+ closeModal();
+ hideContextMenu();
+ };
+
+ const filteredPersistentVolumeClaims = computed(() => {
+ if (!searchQuery.value) {
+ return props.persistentvolumeclaims;
+ }
+
+ const query = searchQuery.value.toLowerCase();
+
+ const nameSpecificMatch = query.match(/^name:(.+)$/);
+ if (nameSpecificMatch) {
+ const nameQuery = nameSpecificMatch[1].trim();
+ return props.persistentvolumeclaims.filter(persistentvolumeclaim => {
+ const name = persistentvolumeclaim.metadata.name.toLowerCase();
+ return name.includes(nameQuery);
+ });
+ }
+
+ const namespaceSpecificMatch = query.match(/^namespace:(.+)$/);
+ if (namespaceSpecificMatch) {
+ const namespaceQuery = namespaceSpecificMatch[1].trim();
+ return props.persistentvolumeclaims.filter(persistentvolumeclaim => {
+ const namespace = persistentvolumeclaim.metadata.namespace.toLowerCase();
+ return namespace.includes(namespaceQuery);
+ });
+ }
+
+ const statusSpecificMatch = query.match(/^status:(.+)$/);
+ if (statusSpecificMatch) {
+ const statusQuery = statusSpecificMatch[1].trim();
+ return props.persistentvolumeclaims.filter(persistentvolumeclaim => {
+ const status = persistentvolumeclaim.status?.phase?.toLowerCase() || '';
+ return status.includes(statusQuery);
+ });
+ }
+
+ const labelSpecificMatch = query.match(/^label:(.+)$/);
+ if (labelSpecificMatch) {
+ const labelQuery = labelSpecificMatch[1].trim();
+ return props.persistentvolumeclaims.filter(persistentvolumeclaim => {
+ const labels = persistentvolumeclaim.metadata.labels || {};
+ for (const key in labels) {
+ const value = labels[key].toLowerCase();
+ const keyLower = key.toLowerCase();
+
+ // Check for key=value format
+ if (labelQuery.includes('=')) {
+ const [queryKey, queryValue] = labelQuery.split('=');
+ if (keyLower === queryKey.trim().toLowerCase() &&
+ value.includes(queryValue.trim().toLowerCase())) {
+ return true;
+ }
+ }
+ // Check for just key
+ else if (keyLower.includes(labelQuery)) {
+ return true;
+ }
+ }
+ return false;
+ });
+ }
+
+ // Default behavior: search only in persistentvolumeclaim names
+ return props.persistentvolumeclaims.filter(persistentvolumeclaim => {
+ const name = persistentvolumeclaim.metadata.name.toLowerCase();
+ return name.includes(query);
+ });
+ });
+
+ // Methods
+ const hideContextMenu = () => {
+ showMenu.value = false;
+ document.removeEventListener('click', hideContextMenu);
+ };
+
+ const showContextMenu = (event: MouseEvent, persistentvolumeclaim: KubernetesPersistentVolumeClaim) => {
+ event.preventDefault();
+
+ menuPosition.value = {
+ x: event.clientX,
+ y: event.clientY
+ };
+
+ selectedContextPersistentVolumeClaim.value = persistentvolumeclaim;
+ selectPersistentVolumeClaim(persistentvolumeclaim);
+ showMenu.value = true;
+
+ setTimeout(() => {
+ document.addEventListener('click', hideContextMenu);
+ }, 0);
+ };
+
+ const closeModal = () => {
+ showCreate.value = false;
+ };
+
+ const isSelected = (persistentvolumeclaim: KubernetesPersistentVolumeClaim): boolean => {
+ if (!selectedPersistentVolumeClaim.value) return false;
+ return selectedPersistentVolumeClaim.value.metadata.name === persistentvolumeclaim.metadata.name &&
+ selectedPersistentVolumeClaim.value.metadata.uid === persistentvolumeclaim.metadata.uid;
+ };
+
+ const selectPersistentVolumeClaim = (persistentVolumeClaim: KubernetesPersistentVolumeClaim): void => {
+ try {
+ const payload = { ...persistentVolumeClaim };
+ if (!payload.kind) {
+ payload.kind = 'PersistentVolumeClaim';
+ }
+ selectedPersistentVolumeClaim.value = payload;
+ emit('persistentVolumeClaim-selected', payload);
+ } catch (error) {
+ alert("Failed to select Persistent Volume Claim:", error);
+ }
+ };
+
+ const deletePersistentVolumeClaim = (): void => {
+ if (selectedContextPersistentVolumeClaim.value && props.selectedCluster) {
+ try {
+ emit('delete-persistentvolumeclaim', {
+ cluster: props.selectedCluster,
+ persistentVolumeClaim: selectedContextPersistentVolumeClaim.value
+ });
+ } catch (error) {
+ alert(error);
+ }
+ }
+ hideContextMenu();
+ };
+
+ const getUniqueKey = (persistentvolumeclaim: KubernetesPersistentVolumeClaim): string => {
+ return `${persistentvolumeclaim.metadata.name}-${persistentvolumeclaim.metadata.uid || ''}`;
+ };
+
+ const getPersistentVolumeClaimStorageClass = (persistentVolumeClaim: KubernetesPersistentVolumeClaim): string => {
+ return persistentVolumeClaim.spec?.storageClassName || 'default';
+ };
+
+ const getPersistentVolumeClaimAccessModes = (persistentVolumeClaim: KubernetesPersistentVolumeClaim): string => {
+ const accessModes = persistentVolumeClaim.spec?.accessModes?.join(', ') || 'Unknown';
+ switch (accessModes) {
+ case "ReadWriteOnce":
+ return "RWO";
+ default:
+ return accessModes;
+ }
+ };
+
+ const getPersistentVolumeClaimStatus = (persistentvolumeclaim: KubernetesPersistentVolumeClaim): string => {
+ return persistentvolumeclaim.status?.phase || 'Unknown';
+ };
+
+ const getPersistentVolumeClaimStatusClass = (persistentvolumeclaim: KubernetesPersistentVolumeClaim): string => {
+ const status = getPersistentVolumeClaimStatus(persistentvolumeclaim);
+ switch (status) {
+ case 'Bound':
+ return 'status-active';
+ case 'Pending':
+ return 'status-pending';
+ case 'Lost':
+ return 'status-error';
+ default:
+ return 'status-unknown';
+ }
+ };
+
+ const getPersistentVolumeClaimCapacity = (persistentVolumeClaim: KubernetesPersistentVolumeClaim): string => {
+ return persistentVolumeClaim.spec?.resources?.requests?.storage || 'Unknown';
+ };
+
+
+ onBeforeUnmount(() => {
+ document.removeEventListener('click', hideContextMenu);
+ });
+
+ return {
+
+ // State
+ showCreate,
+ searchQuery,
+ showMenu,
+ menuPosition,
+ cancelForm,
+ isSubmitting,
+
+ // Form
+ formError,
+ formName,
+ formNamespace,
+ formStorageClass,
+ formCapacity,
+ formCapacityUnit,
+ formAccessModes,
+
+ // Computed
+ filteredPersistentVolumeClaims,
+
+ // Methods
+ hideContextMenu,
+ showContextMenu,
+ isSelected,
+ selectPersistentVolumeClaim,
+ deletePersistentVolumeClaim,
+ createPersistentVolumeClaim,
+ getUniqueKey,
+ getPersistentVolumeClaimStorageClass,
+ getPersistentVolumeClaimAccessModes,
+ getPersistentVolumeClaimStatus,
+ getPersistentVolumeClaimStatusClass,
+ getPersistentVolumeClaimCapacity,
+ formatAge,
+ };
+ }
+});
+</script>
+
+<template>
+ <div class="persistentvolumeclaims-container">
+ <div class="search-bar-container">
+ <SearchBar
+ :value="searchQuery"
+ @update:value="searchQuery = $event"
+ placeholder="Search persistent volume claims..."
+ />
+ </div>
+
+ <div v-if="filteredPersistentVolumeClaims.length === 0" class="no-persistentvolumeclaims">
+ <p v-if="searchQuery">No persistentvolumeclaims found matching "{{ searchQuery }}"</p>
+ <p v-else>No persistentvolumeclaims found.</p>
+ </div>
+
+ <div v-else class="table-scroll-container">
+ <table>
+ <thead>
+ <tr>
+ <th>Namespace</th>
+ <th>Name</th>
+ <th>Status</th>
+ <th>Volume</th>
+ <th>Capacity</th>
+ <th>Access Modes</th>
+ <th>Storage Class</th>
+ <th>Age</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr
+ v-for="persistentVolumeClaim in filteredPersistentVolumeClaims"
+ :key="getUniqueKey(persistentVolumeClaim)"
+ :class="{ selected: isSelected(persistentVolumeClaim) }"
+ @click="selectPersistentVolumeClaim(persistentVolumeClaim)"
+ @contextmenu="showContextMenu($event, persistentVolumeClaim)"
+ >
+ <td>{{ persistentVolumeClaim.metadata.namespace }}</td>
+ <td>{{ persistentVolumeClaim.metadata.name }}</td>
+ <td :class="getPersistentVolumeClaimStatusClass(persistentVolumeClaim)">{{ getPersistentVolumeClaimStatus(persistentVolumeClaim) }}</td>
+ <td>{{ persistentVolumeClaim.spec?.volumeName || '-' }}</td>
+ <td>{{ getPersistentVolumeClaimCapacity(persistentVolumeClaim) }}</td>
+ <td>{{ getPersistentVolumeClaimAccessModes(persistentVolumeClaim) }}</td>
+ <td>{{ getPersistentVolumeClaimStorageClass(persistentVolumeClaim) }}</td>
+ <td>{{ formatAge(persistentVolumeClaim.metadata.creationTimestamp) }}</td>
+ </tr>
+ </tbody>
+ </table>
+ <div
+ v-if="showMenu"
+ class="context-menu"
+ :style="{ top: menuPosition.y + 'px', left: menuPosition.x + 'px' }"
+ @click.stop
+ >
+ <div class="menu-item" @click="showCreate = true; hideContextMenu()">
+ Create
+ </div>
+ <div class="menu-item" @click="deletePersistentVolumeClaim">
+ Delete
+ </div>
+ </div>
+
+ <div v-if="showCreate" class="modal-overlay">
+ <div class="modal-content" @click.stop>
+ <div class="modal-header">
+ <h3>Create Persistent Volume Claim</h3>
+ <button class="close-button" @click="cancelForm">x</button>
+ </div>
+
+ <div class="modal-body">
+ <div v-if="formError" class="error-message">{{ formError }}</div>
+
+ <div class="form-group">
+ <label for="name">Name:</label>
+ <input id="name" v-model="formName" type="text" placeholder="test-claim-1" :disabled="isSubmitting">
+ </div>
+
+ <div class="form-group">
+ <label for="namespace">Namespace:</label>
+ <input id="namespace" v-model="formNamespace" type="text" placeholder="default" :disabled="isSubmitting">
+ </div>
+
+ <div class="form-group">
+ <label for="storageClass">Storage Class:</label>
+ <select id="storageClass" v-model="formStorageClass" :disabled="isSubmitting">
+ <option value="local-path">local-path</option>
+ </select>
+ </div>
+
+ <div class="form-group">
+ <label for="capacity">Capacity (Gi):</label>
+ <input id="capacity" v-model="formCapacity" type="number" min="1" placeholder="10" :disabled="isSubmitting"/>
+ </div>
+
+ <div class="form-group">
+ <label for="accessModes">Access Modes:</label>
+ <div>
+ <label class="checkbox-label">
+ <input type="checkbox" v-model="formAccessModes" value="ReadWriteOnce" :disabled="isSubmitting" />
+ ReadWriteOnce
+ </label>
+ </div>
+ </div>
+
+ </div>
+
+ <div class="modal-footer">
+ <button class="cancel-button" @click="cancelForm" :disabled="isSubmitting">Cancel</button>
+ <button class="create-button" @click="createPersistentVolumeClaim" :disabled="isSubmitting">{{ isSubmitting ? 'Creating...' : 'Create' }}</button>
+ </div>
+ </div>
+
+ </div>
+
+ </div>
+ </div>
+</template>
+
+<style src="@/assets/css/CreateResource.css" scoped></style>
+<style src="@/assets/css/ListResource.css" scoped></style>
+<style src="@/assets/css/CreatePodMethodSelector.css" scoped></style>
+<!-- VolumesCreateGuided.vue -->
+<script lang="ts">
+import { defineComponent, ref, computed } from 'vue';
+import { SecretCreateOptions } from '../types/custom'
+
+export default defineComponent({
+ name: 'VolumesCreateGuided',
+
+ props: {
+ show: {
+ type: Boolean,
+ required: true
+ },
+ cluster: {
+ type: Object as PropType<KubernetesCluster | null>,
+ required: false,
+ default: null
+ }
+ },
+
+ emits: ['close', 'create-volume'],
+
+ setup(props, { emit }) {
+ const name = ref('');
+ const namespace = ref('default');
+ const isSubmitting = ref(false);
+ const error = ref('');
+ const volumeData = ref([{ key: '', value: '', showValue: false }]);
+ const accessModes = ref(['ReadWriteConce']);
+
+ const hostPath = ref({ path: '', type: ''});
+ const nfs = ref({ server: '', path: '', readOnly: false });
+ const volumeType = ref('');
+ const volumeTypes = [
+ {
+ value: 'hostPath',
+ label: 'HostPath',
+ category: 'local',
+ description: 'Mount a file or directory from the host name (development only)',
+ },
+ {
+ value: 'nfs',
+ label: 'NFS',
+ category: 'network',
+ description: 'Network File System for shared storage across multiple nodes',
+ },
+ ];
+
+ const isFormValid = computed(() => {
+ if (!name.value.trim()) return false;
+ if (!capacity.value || capacity.value <= 0) return false;
+ if (accessModes.value.length === 0)return false;
+ if (!volumeType.value) return false;
+
+ if (volumeType.value === 'hostPath') {
+ if (!hostPath.value.path.trim()) {
+ return false;
+ }
+ }
+
+ return true;
+ });
+
+ const getVolumeTypeLabel = () => {
+ const type = volumeTypes.find(t => t.value === volumeType.value);
+ return type ? type.label : '';
+ };
+
+ const selectVolumeType = (type: string) => {
+ volumeType.value = type;
+ error.value = '';
+ };
+
+ const addSecretData = () => {
+ volumeData.value.push({ key: '', value: '', showValue: false });
+ };
+
+ const removeSecretData = (index: number) => {
+ if (volumeData.value.length > 1) {
+ volumeData.value.splice(index, 1);
+ }
+ };
+
+ const resetForm = () => {
+ name.value = '';
+ namespace.value = 'default';
+ volumeData.value = [{ key: '', value: '' }];
+ error.value = '';
+ isSubmitting.value = false;
+ };
+
+ const closeModal = () => {
+ resetForm();
+ emit('close');
+ };
+
+ const toggleValueVisibility = (index: number) => {
+ volumeData.value[index].showValue = !volumeData.value[index].showValue;
+ };
+
+ const createPersistentVolume = () => {
+ if (!props.cluster) {
+ error.value = 'No cluster selected';
+ return;
+ }
+
+ if (!isFormValid.value) {
+ error.value = 'Please fill in all required fields';
+ return;
+ }
+
+ isSubmitting.value = true;
+
+ let volumeSource = {};
+ switch (volumeType.value) {
+ case 'hostPath':
+ volumeSource = {
+ hostPath: {
+ path: hostPath.value.path.trim(),
+ ...(hostPath.value.type && { type: hostPath.value.type })
+ }
+ };
+ break;
+ }
+
+ const spec: any = {
+ capacity: {
+ storage: `${capacity.value}${capacityUnit.value}`
+ },
+ accessModes: accessModes.value,
+ persistentVolumeReclaimPolicy: reclaimPolicy.value,
+ ...volumeSource
+ };
+
+ const stringData = {};
+ validData.forEach(item => {
+ stringData[item.key.trim()] = item.value;
+ });
+
+ const opts: SecretCreateOptions = {
+ context: props.cluster.contextName,
+ opts: {
+ apiVersion: 'v1',
+ kind: 'Secret',
+ metadata: {
+ name: name.value.trim(),
+ namespace: namespace.value.trim()
+ },
+ type: 'Opaque',
+ stringData: stringData
+ }
+ }
+ emit('create-volume', opts);
+ resetForm();
+ closeModal();
+ };
+
+ return {
+ name,
+ namespace,
+ volumeData,
+ isSubmitting,
+ error,
+ isFormValid,
+ addSecretData,
+ removeSecretData,
+ closeModal,
+ createSecret,
+ toggleValueVisibility,
+ getVolumeTypeLabel,
+ selectVolumeType,
+
+
+ volumeType,
+ volumeTypes,
+ hostPath,
+ nfs,
+ accessModes,
+
+ };
+ }
+});
+</script>
+
+<template>
+ <div v-if="show" class="modal-overlay" @click="closeModal">
+ <div class="modal-content" @click.stop>
+ <div class="modal-header">
+ <h3>Create Persistent Volume</h3>
+ <button class="close-button" @click="closeModal">×</button>
+ </div>
+ <div class="modal-body">
+ <div v-if="error" class="error-message">{{ error }}</div>
+ <div class="form-group">
+ <label for="name">Name:</label>
+ <input
+ id="name"
+ v-model="name"
+ type="text"
+ placeholder="my-persistent-volume"
+ :disabled="isSubmitting"
+ />
+ </div>
+ <div class="form-group">
+ <label for="storageClass">Storage Class:</label>
+ <input
+ id="storageClass"
+ v-model="storageClass"
+ type="text"
+ placeholder="standard"
+ :disabled="isSubmitting"
+ />
+ </div>
+ <div class="form-group">
+ <label for="capacity">Capacity (Gi):</label>
+ <div class="storage-input-group">
+ <input
+ id="capacity"
+ v-model="capacity"
+ type="number"
+ min="1"
+ placeholder="10"
+ :disabled="isSubmitting"
+ />
+ </div>
+ </div>
+ <div class="form-section">
+ <h4>Volume Type</h4>
+ <div class="volume-type-selector">
+ <div
+ v-for="type in volumeTypes"
+ :key="type.value"
+ class="volume-type-option"
+ :class="{ selected: volumeType === type.value }"
+ @click="selectVolumeType(type.value)"
+ >
+ <div class="type-header">
+ <span class="type-name">{{ type.label }}</span>
+ <span class="type-badge" :class="type.category">{{ type.category }}</span>
+ </div>
+ <p class="type-description">{{ type.description }}</p>
+ </div>
+ </div>
+ </div>
+ <div v-if="volumeType" class="form-section">
+ <h4>{{ getVolumeTypeLabel() }} Configuration</h4>
+ <div v-if="volumeType == 'hostPath'" class="volume-config">
+ <div class="form-group">
+ <label for="hostPath">Host Path:</label>
+ <input
+ id="hostPath"
+ v-model="hostPath.path"
+ type="text"
+ placeholder="/mnt/data"
+ :disabled="isSubmitting"
+ />
+ <small class="field-hint">Path on the host node</small>
+ </div>
+ <div class="form-group">
+ <label for="hostPathType">Path Type:</label>
+ <select id="hostPathType" v-model="hostPath.type" :disabled="isSubmitting">
+ <option value="">Default</option>
+ <option value="DirectoryOrCreate">DirectoryOrCreate</option>
+ <option value="Directory">Directory</option>
+ <option value="FileOrCreate">FileOrCreate</option>
+ <option value="File">File</option>
+ <option value="Socket">Socket</option>
+ <option value="CharDevice">CharDevice</option>
+ <option value="BlockDevice">BlockDevice</option>
+ </select>
+ </div>
+ </div>
+ </div>
+ <div class="modal-footer">
+ <button
+ class="cancel-button"
+ @click="closeModal"
+ :disabled="isSubmitting"
+ >
+ Cancel
+ </button>
+ <button
+ class="create-button"
+ @click="createPersistentVolume"
+ :disabled="!isFormValid || isSubmitting"
+ >
+ {{ isSubmitting ? 'Creating...' : 'Create' }}
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
+</template>
+
+<style src="@/assets/css/CreateResource.css" scoped></style>
+<style src="@/assets/css/PersistentVolumes.css" scoped></style>
+<!-- PersistentVolumesCreateMethodSelector.vue -->
+<template>
+ <div v-if="show" class="modal-overlay" @click="closeModal">
+ <div class="modal-content method-selector" @click.stop>
+ <div class="modal-header">
+ <h3>Create Persistent Volume</h3>
+ <button class="close-button" @click="closeModal">×</button>
+ </div>
+
+ <div class="modal-body">
+ <p class="description">
+ Choose how you would like to create your Persistent Volume:
+ </p>
+
+ <div class="method-options">
+ <div
+ class="method-option"
+ @click="selectMethod('guided')"
+ :class="{ selected: selectedMethod === 'guided' }"
+ >
+ <div class="method-icon">
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
+ <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
+ </svg>
+ </div>
+ <div class="method-content">
+ <h4>Guided Form</h4>
+ <p>Use a step-by-step form with validation and helpful hints. Recommended for beginners.</p>
+ <ul class="method-features">
+ <li>Form validation</li>
+ <li>Field descriptions</li>
+ <li>Storage type selection</li>
+ <li>Access mode guidance</li>
+ </ul>
+ </div>
+ </div>
+
+ <div
+ class="method-option"
+ @click="selectMethod('yaml')"
+ :class="{ selected: selectedMethod === 'yaml' }"
+ >
+ <div class="method-icon">
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
+ <path d="M14,17H7V15H14M17,13H7V11H17M17,9H7V7H17M19,3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3Z"/>
+ </svg>
+ </div>
+ <div class="method-content">
+ <h4>YAML Editor</h4>
+ <p>Write or paste YAML directly. Provides full control and flexibility for advanced users.</p>
+ <ul class="method-features">
+ <li>Full YAML control</li>
+ <li>Template loading</li>
+ <li>Syntax validation</li>
+ <li>Copy/paste support</li>
+ </ul>
+ </div>
+ </div>
+ </div>
+
+ <div class="volume-types-info">
+ <h4>Supported Volume Types:</h4>
+ <div class="volume-types">
+ <span class="volume-type">HostPath</span>
+ <span class="volume-type">NFS</span>
+ <span class="volume-type">AWS EBS</span>
+ <span class="volume-type">Azure Disk</span>
+ <span class="volume-type">GCE PD</span>
+ <span class="volume-type">iSCSI</span>
+ <span class="volume-type">Local</span>
+ <span class="volume-type">CSI</span>
+ </div>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <button
+ class="cancel-button"
+ @click="closeModal"
+ >
+ Cancel
+ </button>
+ <button
+ class="continue-button"
+ @click="continueWithMethod"
+ :disabled="!selectedMethod"
+ >
+ Continue
+ </button>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script lang="ts">
+import { defineComponent, ref } from 'vue';
+
+export default defineComponent({
+ name: 'PersistentVolumesCreateMethodSelector',
+
+ props: {
+ show: {
+ type: Boolean,
+ required: true
+ }
+ },
+
+ emits: ['close', 'method-selected'],
+
+ setup(props, { emit }) {
+ const selectedMethod = ref<string>('');
+
+ const selectMethod = (method: string) => {
+ selectedMethod.value = method;
+ };
+
+ const closeModal = () => {
+ selectedMethod.value = '';
+ emit('close');
+ };
+
+ const continueWithMethod = () => {
+ if (selectedMethod.value) {
+ emit('method-selected', selectedMethod.value);
+ selectedMethod.value = '';
+ }
+ };
+
+ return {
+ selectedMethod,
+ selectMethod,
+ closeModal,
+ continueWithMethod
+ };
+ }
+});
+</script>
+
+<style src="@/assets/css/MenuDialog.css" scoped></style>
+
+<style scoped>
+.method-selector {
+ max-width: 700px;
+ width: 90vw;
+}
+
+.description {
+ color: #ccc;
+ margin-bottom: 1.5rem;
+ text-align: center;
+ font-size: 1rem;
+}
+
+.method-options {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+ margin-bottom: 2rem;
+}
+
+.method-option {
+ display: flex;
+ align-items: flex-start;
+ gap: 1rem;
+ padding: 1.5rem;
+ border: 2px solid #444;
+ border-radius: 8px;
+ background-color: #2d2d2d;
+ cursor: pointer;
+ transition: all 0.2s ease;
+}
+
+.method-option:hover {
+ border-color: #007acc;
+ background-color: #333;
+}
+
+.method-option.selected {
+ border-color: #007acc;
+ background-color: #1a3a5c;
+}
+
+.method-icon {
+ flex-shrink: 0;
+ width: 48px;
+ height: 48px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background-color: #007acc;
+ border-radius: 8px;
+ color: white;
+}
+
+.method-option.selected .method-icon {
+ background-color: #0099ff;
+}
+
+.method-content {
+ flex: 1;
+}
+
+.method-content h4 {
+ margin: 0 0 0.5rem 0;
+ color: #ffffff;
+ font-size: 1.2rem;
+}
+
+.method-content p {
+ margin: 0 0 1rem 0;
+ color: #ccc;
+ line-height: 1.4;
+}
+
+.method-features {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5rem;
+}
+
+.method-features li {
+ background-color: #444;
+ color: #ccc;
+ padding: 0.25rem 0.5rem;
+ border-radius: 4px;
+ font-size: 0.85rem;
+}
+
+.method-option.selected .method-features li {
+ background-color: #007acc;
+ color: white;
+}
+
+.volume-types-info {
+ background-color: #333;
+ border: 1px solid #444;
+ border-radius: 6px;
+ padding: 1rem;
+ margin-bottom: 1rem;
+}
+
+.volume-types-info h4 {
+ margin: 0 0 0.75rem 0;
+ color: #ffffff;
+ font-size: 1rem;
+}
+
+.volume-types {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5rem;
+}
+
+.volume-type {
+ background-color: #007acc;
+ color: white;
+ padding: 0.25rem 0.75rem;
+ border-radius: 12px;
+ font-size: 0.85rem;
+ font-weight: 500;
+}
+
+.modal-footer {
+ display: flex;
+ justify-content: flex-end;
+ gap: 0.5rem;
+ padding: 1rem 1.5rem;
+ border-top: 1px solid #444;
+}
+
+.cancel-button {
+ padding: 0.5rem 1rem;
+ border: 1px solid #666;
+ background-color: transparent;
+ color: #ccc;
+ border-radius: 4px;
+ cursor: pointer;
+ transition: all 0.2s;
+}
+
+.cancel-button:hover {
+ background-color: #444;
+ border-color: #777;
+}
+
+.continue-button {
+ padding: 0.5rem 1rem;
+ border: 1px solid #007acc;
+ background-color: #007acc;
+ color: white;
+ border-radius: 4px;
+ cursor: pointer;
+ transition: all 0.2s;
+}
+
+.continue-button:hover:not(:disabled) {
+ background-color: #005a9e;
+ border-color: #005a9e;
+}
+
+.continue-button:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+
+/* Responsive design */
+@media (max-width: 768px) {
+ .method-selector {
+ width: 95vw;
+ max-width: none;
+ }
+
+ .method-options {
+ gap: 0.75rem;
+ }
+
+ .method-option {
+ padding: 1rem;
+ flex-direction: column;
+ text-align: center;
+ }
+
+ .method-icon {
+ align-self: center;
+ margin-bottom: 0.5rem;
+ }
+
+ .method-features {
+ justify-content: center;
+ }
+
+ .volume-types {
+ justify-content: center;
+ }
+}
+</style>
+
+<!-- PersistentVolumeList.vue -->
+<script lang="ts">
+import { defineComponent, ref, computed, PropType, onBeforeUnmount } from 'vue';
+import { KubernetesCluster, KubernetesPersistentVolume, KubernetesPersistentVolumeClaim } from '../types/kubernetes';
+import { formatAge } from '../lib/format';
+import SearchBar from './SearchBar.vue';
+
+export default defineComponent({
+ name: 'PersistentVolumeList',
+
+ components: {
+ SearchBar
+ },
+
+ props: {
+ selectedCluster: {
+ type: Object as PropType<KubernetesCluster>,
+ required: false,
+ default: null
+ },
+ persistentVolumes: {
+ type: Array as PropType<KubernetesPersistentVolume[]>,
+ required: false,
+ default: () => []
+ },
+ persistentVolumeClaims: {
+ type: Array as PropType<KubernetesPersistentVolumeClaim[]>,
+ required: false,
+ default: () => []
+ }
+ },
+
+ emits: ['persistentVolume-selected', 'delete-persistentvolume'],
+
+ setup(props, { emit }) {
+ // State
+ const searchQuery = ref('');
+ const selectedPersistentVolume = ref<KubernetesPersistentVolume | null>(null);
+ const selectedContextPersistentVolume = ref<KubernetesPersistentVolume | null>(null);
+ const showMenu = ref(false);
+ const menuPosition = ref({ x: 0, y: 0 });
+
+ // Computed properties
+ const filteredPersistentVolumes = computed(() => {
+ if (!searchQuery.value) {
+ return props.persistentVolumes;
+ }
+
+ const query = searchQuery.value.toLowerCase();
+
+ const nameSpecificMatch = query.match(/^name:(.+)$/);
+ if (nameSpecificMatch) {
+ const nameQuery = nameSpecificMatch[1].trim();
+ return props.persistentVolumes.filter(persistentVolume => {
+ const name = persistentVolume.metadata.name.toLowerCase();
+ return name.includes(nameQuery);
+ });
+ }
+
+ const statusSpecificMatch = query.match(/^status:(.+)$/);
+ if (statusSpecificMatch) {
+ const statusQuery = statusSpecificMatch[1].trim();
+ return props.persistentVolumes.filter(persistentVolume => {
+ const status = persistentVolume.status?.phase?.toLowerCase() || '';
+ return status.includes(statusQuery);
+ });
+ }
+
+ const claimSpecificMatch = query.match(/^claim:(.+)$/);
+ if (claimSpecificMatch) {
+ const claimQuery = claimSpecificMatch[1].trim();
+ return props.persistentVolumes.filter(persistentVolume => {
+ const claimName = persistentVolume.spec?.claimRef?.name?.toLowerCase() || '';
+ return claimName.includes(claimQuery);
+ });
+ }
+
+ const storageClassSpecificMatch = query.match(/^storageclass:(.+)$/);
+ if (storageClassSpecificMatch) {
+ const storageClassQuery = storageClassSpecificMatch[1].trim();
+ return props.persistentVolumes.filter(persistentVolume => {
+ const storageClass = persistentVolume.spec?.storageClassName?.toLowerCase() || '';
+ return storageClass.includes(storageClassQuery);
+ });
+ }
+
+ const labelSpecificMatch = query.match(/^label:(.+)$/);
+ if (labelSpecificMatch) {
+ const labelQuery = labelSpecificMatch[1].trim();
+ return props.persistentVolumes.filter(persistentVolume => {
+ const labels = persistentVolume.metadata.labels || {};
+ for (const key in labels) {
+ const value = labels[key].toLowerCase();
+ const keyLower = key.toLowerCase();
+
+ // Check for key=value format
+ if (labelQuery.includes('=')) {
+ const [queryKey, queryValue] = labelQuery.split('=');
+ if (keyLower === queryKey.trim().toLowerCase() &&
+ value.includes(queryValue.trim().toLowerCase())) {
+ return true;
+ }
+ }
+ // Check for just key
+ else if (keyLower.includes(labelQuery)) {
+ return true;
+ }
+ }
+ return false;
+ });
+ }
+
+ // Default behavior: search only in persistent volume names
+ return props.persistentVolumes.filter(persistentVolume => {
+ const name = persistentVolume.metadata.name.toLowerCase();
+ return name.includes(query);
+ });
+ });
+
+ // Methods
+ const hideContextMenu = () => {
+ showMenu.value = false;
+ document.removeEventListener('click', hideContextMenu);
+ };
+
+ const showContextMenu = (event: MouseEvent, persistentVolume: KubernetesPersistentVolume) => {
+ event.preventDefault();
+
+ menuPosition.value = {
+ x: event.clientX,
+ y: event.clientY
+ };
+
+ selectedContextPersistentVolume.value = persistentVolume;
+ selectPersistentVolume(persistentVolume);
+ showMenu.value = true;
+
+ setTimeout(() => {
+ document.addEventListener('click', hideContextMenu);
+ }, 0);
+ };
+
+ const isSelected = (persistentVolume: KubernetesPersistentVolume): boolean => {
+ if (!selectedPersistentVolume.value) return false;
+ return selectedPersistentVolume.value.metadata.name === persistentVolume.metadata.name &&
+ selectedPersistentVolume.value.metadata.uid === persistentVolume.metadata.uid;
+ };
+
+ const selectPersistentVolume = (persistentVolume: KubernetesPersistentVolume): void => {
+ try {
+ const payload = { ...persistentVolume };
+ if (!payload.kind) {
+ payload.kind = 'PersistentVolume';
+ }
+ selectedPersistentVolume.value = payload;
+ emit('persistentVolume-selected', payload);
+ } catch (error) {
+ alert("Failed to select Persistent Volume:", error);
+ }
+ };
+
+ const deletePersistentVolume = (): void => {
+ if (selectedContextPersistentVolume.value && props.selectedCluster) {
+ try {
+ emit('delete-persistentvolume', {
+ cluster: props.selectedCluster,
+ definition: selectedContextPersistentVolume.value
+ });
+ } catch (error) {
+ alert(error);
+ }
+ }
+ hideContextMenu();
+ };
+
+ const getUniqueKey = (persistentVolume: KubernetesPersistentVolume): string => {
+ return `${persistentVolume.metadata.name}-${persistentVolume.metadata.uid || ''}`;
+ };
+
+ const getPersistentVolumeStorageClass = (persistentVolume: KubernetesPersistentVolume): string => {
+ return persistentVolume.spec?.storageClassName || '-';
+ };
+
+ const getPersistentVolumeAccessModes = (persistentVolume: KubernetesPersistentVolume): string => {
+ const accessModes = persistentVolume.spec?.accessModes?.join(', ') || 'Unknown';
+ switch (accessModes) {
+ case "ReadWriteOnce":
+ return "RWO";
+ case "ReadOnlyMany":
+ return "ROX";
+ case "ReadWriteMany":
+ return "RWX";
+ case "ReadWriteOncePod":
+ return "RWOP";
+ default:
+ return accessModes;
+ }
+ };
+
+ const getPersistentVolumeStatus = (persistentVolume: KubernetesPersistentVolume): string => {
+ return persistentVolume.status?.phase || 'Unknown';
+ };
+
+ const getPersistentVolumeStatusClass = (persistentVolume: KubernetesPersistentVolume): string => {
+ const status = getPersistentVolumeStatus(persistentVolume);
+ switch (status) {
+ case 'Available':
+ return 'status-available';
+ case 'Bound':
+ return 'status-active';
+ case 'Released':
+ return 'status-warning';
+ case 'Failed':
+ return 'status-error';
+ default:
+ return 'status-unknown';
+ }
+ };
+
+ const getPersistentVolumeCapacity = (persistentVolume: KubernetesPersistentVolume): string => {
+ return persistentVolume.spec?.capacity?.storage || 'Unknown';
+ };
+
+ const getPersistentVolumeClaim = (persistentVolume: KubernetesPersistentVolume): string => {
+ const claimRef = persistentVolume.spec?.claimRef;
+ if (claimRef) {
+ return `${claimRef.namespace}/${claimRef.name}`;
+ }
+ return '-';
+ };
+
+ const getPersistentVolumeReclaimPolicy = (persistentVolume: KubernetesPersistentVolume): string => {
+ return persistentVolume.spec?.persistentVolumeReclaimPolicy || 'Retain';
+ };
+
+ onBeforeUnmount(() => {
+ document.removeEventListener('click', hideContextMenu);
+ });
+
+ // Return all refs, computed properties, and methods
+ return {
+ // State
+ searchQuery,
+ selectedPersistentVolume,
+ selectedContextPersistentVolume,
+ showMenu,
+ menuPosition,
+
+ // Props
+ persistentVolumeClaims: props.persistentVolumeClaims,
+
+ // Computed
+ filteredPersistentVolumes,
+
+ // Methods
+ hideContextMenu,
+ showContextMenu,
+ isSelected,
+ selectPersistentVolume,
+ deletePersistentVolume,
+ getUniqueKey,
+ getPersistentVolumeStorageClass,
+ getPersistentVolumeAccessModes,
+ getPersistentVolumeStatus,
+ getPersistentVolumeStatusClass,
+ getPersistentVolumeCapacity,
+ getPersistentVolumeClaim,
+ getPersistentVolumeReclaimPolicy,
+ formatAge
+ };
+ }
+});
+</script>
+
+<template>
+ <div class="persistentvolumes-container">
+ <div class="search-bar-container">
+ <SearchBar
+ :value="searchQuery"
+ @update:value="searchQuery = $event"
+ placeholder="Search persistent volumes..."
+ />
+ </div>
+
+ <div v-if="filteredPersistentVolumes.length === 0" class="no-persistentvolumes">
+ <p v-if="searchQuery">No persistent volumes found matching "{{ searchQuery }}"</p>
+ <p v-else>No persistent volumes found.</p>
+ </div>
+
+ <div v-else class="table-scroll-container">
+ <table>
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Status</th>
+ <th>Claim</th>
+ <th>Capacity</th>
+ <th>Access Modes</th>
+ <th>Reclaim Policy</th>
+ <th>Storage Class</th>
+ <th>Age</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr
+ v-for="persistentVolume in filteredPersistentVolumes"
+ :key="getUniqueKey(persistentVolume)"
+ :class="{ selected: isSelected(persistentVolume) }"
+ @click="selectPersistentVolume(persistentVolume)"
+ @contextmenu="showContextMenu($event, persistentVolume)"
+ >
+ <td>{{ persistentVolume.metadata.name }}</td>
+ <td :class="getPersistentVolumeStatusClass(persistentVolume)">{{ getPersistentVolumeStatus(persistentVolume) }}</td>
+ <td>{{ getPersistentVolumeClaim(persistentVolume) }}</td>
+ <td>{{ getPersistentVolumeCapacity(persistentVolume) }}</td>
+ <td>{{ getPersistentVolumeAccessModes(persistentVolume) }}</td>
+ <td>{{ getPersistentVolumeReclaimPolicy(persistentVolume) }}</td>
+ <td>{{ getPersistentVolumeStorageClass(persistentVolume) }}</td>
+ <td>{{ formatAge(persistentVolume.metadata.creationTimestamp) }}</td>
+ </tr>
+ </tbody>
+ </table>
+ <div
+ v-if="showMenu"
+ class="context-menu"
+ :style="{ top: menuPosition.y + 'px', left: menuPosition.x + 'px' }"
+ @click.stop
+ >
+ <div class="menu-item" @click="deletePersistentVolume">
+ Delete
+ </div>
+ </div>
+ </div>
+ </div>
+</template>
+
+<style src="@/assets/css/ListResource.css" scoped></style>
+<script lang="ts">
+import { defineComponent, PropType, ref, computed } from 'vue';
+import { KubernetesCluster, KubernetesPod } from '../types/kubernetes';
+import { formatAge } from '../lib/format';
+import SearchBar from './SearchBar.vue';
+import CreatePodGuided from './CreatePodGuided.vue';
+import CreatePodMethodSelector from './CreatePodMethodSelector.vue';
+import CreatePodYaml from './CreatePodYaml.vue';
+import EditPodYaml from './EditPodYaml.vue';
+
+export default defineComponent({
+ name: 'PodsList',
+
+ components: {
+ SearchBar,
+ CreatePodGuided,
+ CreatePodMethodSelector,
+ CreatePodYaml,
+ EditPodYaml
+ },
+
+ props: {
+ selectedCluster: {
+ type: Object as PropType<KubernetesCluster | null>,
+ required: false,
+ default: null
+ },
+ pods: {
+ type: Array as PropType<KubernetesPod[]>,
+ required: false,
+ default: () => []
+ }
+ },
+
+ emits: ['pod-selected', 'delete-pod', 'create-pod'],
+
+ setup(props) {
+ // Search functionality
+ const searchQuery = ref('');
+
+ const filteredPods = computed(() => {
+ if (!searchQuery.value) {
+ return props.pods;
+ }
+
+ const query = searchQuery.value.toLowerCase();
+
+ // Check if the query is in the format "name:pod-name"
+ const nameSpecificMatch = query.match(/^name:(.+)$/);
+ if (nameSpecificMatch) {
+ const nameQuery = nameSpecificMatch[1].trim();
+ return props.pods.filter(pod => {
+ const name = pod.metadata.name.toLowerCase();
+ return name.includes(nameQuery);
+ });
+ }
+
+ // Check if the query is in the format "namespace:namespace-name"
+ const namespaceSpecificMatch = query.match(/^namespace:(.+)$/);
+ if (namespaceSpecificMatch) {
+ const namespaceQuery = namespaceSpecificMatch[1].trim();
+ return props.pods.filter(pod => {
+ const namespace = pod.metadata.namespace?.toLowerCase() || '';
+ return namespace.includes(namespaceQuery);
+ });
+ }
+
+ // Check if the query is in the format "label:key=value" or "label:key"
+ const labelSpecificMatch = query.match(/^label:(.+)$/);
+ if (labelSpecificMatch) {
+ const labelQuery = labelSpecificMatch[1].trim();
+ return props.pods.filter(pod => {
+ const labels = pod.metadata.labels || {};
+ for (const key in labels) {
+ const value = labels[key].toLowerCase();
+ const keyLower = key.toLowerCase();
+
+ // Check for key=value format
+ if (labelQuery.includes('=')) {
+ const [queryKey, queryValue] = labelQuery.split('=');
+ if (keyLower === queryKey.trim().toLowerCase() &&
+ value.includes(queryValue.trim().toLowerCase())) {
+ return true;
+ }
+ }
+ // Check for just key
+ else if (keyLower.includes(labelQuery)) {
+ return true;
+ }
+ }
+ return false;
+ });
+ }
+
+ const statusSpecificMatch = query.match(/^status:(.+)$/);
+ if (statusSpecificMatch) {
+ const statusQuery = statusSpecificMatch[1].trim();
+ return props.pods.filter(pod => {
+ const status = pod.status.phase.toLowerCase();
+ return status.includes(statusQuery);
+ });
+ }
+
+ // Default behavior: search only in pod names
+ return props.pods.filter(pod => {
+ const name = pod.metadata.name.toLowerCase();
+ return name.includes(query);
+ });
+ });
+
+
+ return {
+ searchQuery,
+ filteredPods,
+ formatAge
+ };
+ },
+
+ data() {
+ return {
+ selectedPod: null as KubernetesPod | null,
+ showMenu: false,
+ menuPosition: { x: 0, y: 0 },
+ selectedContextPod: null as KubernetesPod | null,
+ showMethodSelector: false,
+ showCreateGuided: false,
+ showCreateYaml: false,
+ showEditYaml: false,
+ currentNamespace: 'default'
+ };
+ },
+
+ beforeUnmount() {
+ document.removeEventListener('click', this.hideContextMenu);
+ },
+
+ watch: {
+ pods: {
+ handler(newPods) {
+ console.log('Pods changed in PodsList:', newPods);
+ },
+ deep: true
+ }
+ },
+
+ methods: {
+
+ editPod(): void {
+ if (this.selectedContextPod) {
+ this.showEditYaml = true;
+ }
+ this.hideContextMenu();
+ },
+
+ handlePodUpdated(result: any): void {
+ if (this.selectedCluster) {
+ this.$emit('refresh-pods', {
+ cluster: this.selectedCluster
+ });
+ }
+ },
+
+ handleMethodSelected(method: string): void {
+ this.showMethodSelector = false;
+
+ if (method === 'guided') {
+ this.showCreateGuided = true;
+ } else if (method === 'yaml') {
+ this.showCreateYaml = true;
+ }
+ },
+
+ handleCreatePod({podDefinition, yamlContent, isYaml}: { podDefinition?: any, yamlContent?: string, isYaml?: boolean}) {
+ if (!this.selectedCluster) {
+ return
+ }
+
+ let opts = {
+ cluster: this.selectedCluster,
+ isYaml: isYaml,
+ }
+
+ if (yamlContent) {
+ opts.yamlContent = yamlContent
+ this.$emit('create-pod', opts)
+ } else if (podDefinition) {
+ opts.podDefinition = podDefinition
+ this.$emit('create-pod', opts)
+ } else {
+ alert(`Unable to emit create-pod`)
+ }
+
+ this.showCreateGuided = false;
+ this.showCreateYaml = false;
+ },
+
+ selectPod(pod: KubernetesPod): void {
+ const podToEmit = { ...pod };
+ if (!podToEmit.kind) {
+ podToEmit.kind = 'Pod';
+ }
+ this.selectedPod = podToEmit;
+ this.$emit('pod-selected', podToEmit);
+ },
+
+ isSelected(pod: KubernetesPod): boolean {
+ return this.selectedPod?.metadata.name === pod.metadata.name;
+ },
+
+ getPodStatus(pod: KubernetesPod): string {
+ if (pod.status && pod.status.phase) {
+ return pod.status.phase;
+ }
+ return 'Unknown';
+ },
+
+ getPodStatusClass(pod: KubernetesPod): string {
+ const status = this.getPodStatus(pod);
+ switch (status) {
+ case 'Running':
+ return 'status-running';
+ case 'Pending':
+ return 'status-pending';
+ case 'Succeeded':
+ return 'status-succeeded';
+ case 'Failed':
+ return 'status-failed';
+ default:
+ return 'status-unknown';
+ }
+ },
+
+ // Context menu methods
+ showContextMenu(event: MouseEvent, pod: KubernetesPod): void {
+ // Prevent the default context menu
+ event.preventDefault();
+
+ // Position the menu
+ this.menuPosition = {
+ x: event.clientX,
+ y: event.clientY
+ };
+
+ // Store the pod that was right-clicked
+ this.selectedContextPod = pod;
+
+ // Select the pod when right-clicking
+ this.selectPod(pod);
+
+ // Show the menu
+ this.showMenu = true;
+
+ // Add a click event listener to hide the menu when clicking outside
+ // Use setTimeout to avoid the current click event from immediately closing the menu
+ setTimeout(() => {
+ document.addEventListener('click', this.hideContextMenu);
+ }, 0);
+ },
+
+ hideContextMenu(): void {
+ this.showMenu = false;
+ document.removeEventListener('click', this.hideContextMenu);
+ },
+
+ deletePod(): void {
+ if (this.selectedContextPod && this.selectedCluster) {
+ this.$emit('delete-pod', {
+ cluster: this.selectedCluster,
+ pod: this.selectedContextPod
+ });
+ }
+ this.hideContextMenu();
+ },
+
+ createPod(): void {
+ this.currentNamespace = this.selectedContextPod?.metadata.namespace || 'default';
+ this.showMethodSelector = true;
+ this.hideContextMenu();
+ },
+
+ getUniqueKey(pod: KubernetesPod): string {
+ const namespace = pod.metadata.namespace || 'default';
+ return `${namespace}-${pod.metadata.name}-${pod.metadata.uid || ''}`;
+ }
+ }
+});
+</script>
+
+<template>
+ <div class="pods-container">
+ <!-- Fixed Search Bar -->
+ <div class="search-bar-container">
+ <SearchBar
+ :value="searchQuery"
+ @update:value="searchQuery = $event"
+ placeholder="Search pods..."
+ />
+ </div>
+
+ <div v-if="filteredPods.length === 0" class="no-pods">
+ <p v-if="searchQuery">No pods found matching "{{ searchQuery }}"</p>
+ <p v-else>No pods found.</p>
+ </div>
+
+ <div v-else class="table-scroll-container">
+ <table>
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Namespace</th>
+ <th>Ready</th>
+ <th>Status</th>
+ <th>Restarts</th>
+ <th>Age</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr
+ v-for="pod in filteredPods"
+ :key="getUniqueKey(pod)"
+ :class="{ selected: isSelected(pod) }"
+ @click="selectPod(pod)"
+ @contextmenu="showContextMenu($event, pod)"
+ >
+ <td>{{ pod.metadata.name }}</td>
+ <td>{{ pod.metadata.namespace }}</td>
+ <td>{{ `${pod.status && pod.status.containerStatuses ? pod.status.containerStatuses.filter(cs => cs.ready).length : 0}/${pod.spec && pod.spec.containers ? pod.spec.containers.length : 0}` }}</td>
+ <td :class="getPodStatusClass(pod)">{{ getPodStatus(pod) }}</td>
+ <td>{{ pod.status && pod.status.containerStatuses ? pod.status.containerStatuses.reduce((sum, cs) => sum + cs.restartCount, 0) : 0 }}</td>
+ <td>{{ formatAge(pod.metadata.creationTimestamp) }}</td>
+ </tr>
+ </tbody>
+ </table>
+ <div
+ v-if="showMenu"
+ class="context-menu"
+ :style="{ top: menuPosition.y + 'px', left: menuPosition.x + 'px' }"
+ @click.stop
+ >
+ <div class="menu-item" @click="createPod">
+ Create
+ </div>
+ <div class="menu-item" @click="editPod">
+ Edit
+ </div>
+ <div class="menu-item" @click="deletePod">
+ Delete
+ </div>
+ </div>
+ </div>
+
+ <!-- Method selector dialog -->
+ <CreatePodMethodSelector
+ :show="showMethodSelector"
+ :namespace="currentNamespace"
+ @close="showMethodSelector = false"
+ @method-selected="handleMethodSelected"
+ />
+
+ <!-- Guided creation form -->
+ <CreatePodGuided
+ :show="showCreateGuided"
+ :namespace="currentNamespace"
+ @close="showCreateGuided = false"
+ @create-pod="handleCreatePod"
+ />
+
+ <!-- YAML creation form -->
+ <CreatePodYaml
+ :show="showCreateYaml"
+ :namespace="currentNamespace"
+ @close="showCreateYaml = false"
+ @create-pod="handleCreatePod"
+ />
+
+ <EditPodYaml
+ :show="showEditYaml"
+ :pod="selectedContextPod"
+ :cluster="selectedCluster"
+ @close="showEditYaml = false"
+ @pod-updated="handlePodUpdated"
+ />
+
+ </div>
+</template>
+
+<style src="@/assets/css/PodsList.css" scoped></style>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+
+export default defineComponent({
+ name: 'SearchBar',
+ props: {
+ value: {
+ type: String,
+ default: ''
+ },
+ placeholder: {
+ type: String,
+ default: 'Search...'
+ }
+ },
+ emits: ['update:value'],
+ methods: {
+ updateSearch(event: Event) {
+ const target = event.target as HTMLInputElement;
+ this.$emit('update:value', target.value);
+ },
+ clearSearch() {
+ this.$emit('update:value', '');
+ }
+ }
+});
+</script>
+
+<template>
+ <div class="search-container">
+ <div class="search-input-wrapper">
+ <input
+ type="text"
+ class="search-input"
+ :placeholder="placeholder"
+ :value="value"
+ @input="updateSearch"
+ />
+ <button
+ v-if="value"
+ class="clear-button"
+ @click="clearSearch"
+ aria-label="Clear search"
+ >
+ ×
+ </button>
+ </div>
+ </div>
+</template>
+
+
+<style src="@/assets/css/SearchBar.css" scoped></style>
+<!-- SecretsCreateGuided.vue -->
+<script lang="ts">
+import { defineComponent, ref, computed } from 'vue';
+import { SecretCreateOptions } from '../types/custom'
+
+export default defineComponent({
+ name: 'SecretsCreateGuided',
+
+ props: {
+ show: {
+ type: Boolean,
+ required: true
+ },
+ cluster: {
+ type: Object as PropType<KubernetesCluster | null>,
+ required: false,
+ default: null
+ }
+ },
+
+ emits: ['close', 'create-secret'],
+
+ setup(props, { emit }) {
+ const name = ref('');
+ const namespace = ref('default');
+ const isSubmitting = ref(false);
+ const error = ref('');
+ const secretData = ref([{ key: '', value: '', showValue: false }]);
+
+ const isFormValid = computed(() => {
+ if (!name.value.trim()) return false;
+ if (!namespace.value.trim()) return false;
+
+ // Check if at least one key-value pair is valid
+ return secretData.value.some(item =>
+ item.key.trim() !== '' && item.value.trim() !== ''
+ );
+ });
+
+ const addSecretData = () => {
+ secretData.value.push({ key: '', value: '', showValue: false });
+ };
+
+ const removeSecretData = (index: number) => {
+ if (secretData.value.length > 1) {
+ secretData.value.splice(index, 1);
+ }
+ };
+
+ const resetForm = () => {
+ name.value = '';
+ namespace.value = 'default';
+ secretData.value = [{ key: '', value: '' }];
+ error.value = '';
+ isSubmitting.value = false;
+ };
+
+ const closeModal = () => {
+ resetForm();
+ emit('close');
+ };
+
+ const toggleValueVisibility = (index: number) => {
+ secretData.value[index].showValue = !secretData.value[index].showValue;
+ };
+
+
+ const createSecret = () => {
+ if (!props.cluster) {
+ error.value = 'No cluster selected';
+ return;
+ }
+
+ if (!name.value.trim()) {
+ error.value = 'Name is required';
+ return;
+ }
+
+ if (!namespace.value.trim()) {
+ error.value = 'Namespace is required';
+ return;
+ }
+
+ // Check if at least one key-value pair is valid
+ const validData = secretData.value.filter(
+ item => item.key.trim() !== '' && item.value.trim() !== ''
+ );
+
+ if (validData.length === 0) {
+ error.value = 'At least one key-value pair is required';
+ return;
+ }
+
+ isSubmitting.value = true;
+
+ const stringData = {};
+ validData.forEach(item => {
+ stringData[item.key.trim()] = item.value;
+ });
+
+ const opts: SecretCreateOptions = {
+ context: props.cluster.contextName,
+ opts: {
+ apiVersion: 'v1',
+ kind: 'Secret',
+ metadata: {
+ name: name.value.trim(),
+ namespace: namespace.value.trim()
+ },
+ type: 'Opaque',
+ stringData: stringData
+ }
+ }
+ emit('create-secret', opts);
+ resetForm();
+ closeModal();
+ };
+
+ return {
+ name,
+ namespace,
+ secretData,
+ isSubmitting,
+ error,
+ isFormValid,
+ addSecretData,
+ removeSecretData,
+ closeModal,
+ createSecret,
+ toggleValueVisibility
+ };
+ }
+});
+</script>
+
+<template>
+ <div v-if="show" class="modal-overlay" @click="closeModal">
+ <div class="modal-content" @click.stop>
+ <div class="modal-header">
+ <h3>Create Secret</h3>
+ <button class="close-button" @click="closeModal">×</button>
+ </div>
+
+ <div class="modal-body">
+ <div v-if="error" class="error-message">{{ error }}</div>
+
+ <div class="form-group">
+ <label for="name">Name:</label>
+ <input
+ id="name"
+ v-model="name"
+ type="text"
+ placeholder="test-secret-1"
+ :disabled="isSubmitting"
+ />
+ </div>
+
+ <div class="form-group">
+ <label for="namespace">Namespace:</label>
+ <input
+ id="namespace"
+ v-model="namespace"
+ type="text"
+ placeholder="default"
+ :disabled="isSubmitting"
+ />
+ </div>
+
+ <div class="form-section">
+ <h4>Secret Data</h4>
+ <div
+ v-for="(item, index) in secretData"
+ :key="index"
+ class="secret-data-row"
+ >
+ <div class="form-group key-field">
+ <label :for="`key-${index}`">Key:</label>
+ <input
+ :id="`key-${index}`"
+ v-model="item.key"
+ type="text"
+ placeholder="username"
+ :disabled="isSubmitting"
+ />
+ </div>
+ <div class="form-group value-field">
+ <label :for="`value-${index}`">Value:</label>
+ <input
+ :id="`value-${index}`"
+ v-model="item.value"
+ type="password"
+ placeholder="••••••••"
+ :disabled="isSubmitting"
+ />
+ </div>
+ <button
+ class="remove-button"
+ @click="removeSecretData(index)"
+ :disabled="isSubmitting || secretData.length <= 1"
+ >
+ ×
+ </button>
+ </div>
+
+ <!-- Single add button outside the v-for loop -->
+ <button
+ class="add-button"
+ @click="addSecretData"
+ :disabled="isSubmitting"
+ >
+ + Add Another Key-Value Pair
+ </button>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <button
+ class="cancel-button"
+ @click="closeModal"
+ :disabled="isSubmitting"
+ >
+ Cancel
+ </button>
+ <button
+ class="create-button"
+ @click="createSecret"
+ :disabled="isSubmitting"
+ >
+ {{ isSubmitting ? 'Creating...' : 'Create' }}
+ </button>
+ </div>
+ </div>
+ </div>
+</template>
+
+<style src="@/assets/css/CreateResource.css" scoped></style>
+<!-- SecretsCreateMethodSelector.vue -->
+<template>
+ <div v-if="show" class="modal-overlay" @click="closeModal">
+ <div class="modal-content" @click.stop>
+ <div class="modal-header">
+ <h3>Create Secret</h3>
+ <button class="close-button" @click="closeModal">×</button>
+ </div>
+
+ <div class="modal-body">
+ <div class="method-option" @click="selectedMethod = 'guided'">
+ <div class="radio-container">
+ <div class="radio-button">
+ <div class="radio-outer">
+ <div class="radio-inner" v-if="selectedMethod === 'guided'"></div>
+ </div>
+ </div>
+ <div class="method-text">
+ <div class="method-label">Guided Creation</div>
+ </div>
+ </div>
+ </div>
+
+ <div class="method-option" @click="selectedMethod = 'yaml'">
+ <div class="radio-container">
+ <div class="radio-button">
+ <div class="radio-outer">
+ <div class="radio-inner" v-if="selectedMethod === 'yaml'"></div>
+ </div>
+ </div>
+ <div class="method-text">
+ <div class="method-label">YAML Creation</div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <button class="cancel-button" @click="closeModal">
+ Cancel
+ </button>
+ <button
+ class="continue-button"
+ @click="continueToSelected"
+ :disabled="!selectedMethod"
+ >
+ Continue
+ </button>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script lang="ts">
+import { defineComponent, ref } from 'vue';
+
+export default defineComponent({
+ name: 'SecretsCreateMethodSelector',
+
+ props: {
+ show: {
+ type: Boolean,
+ default: false
+ }
+ },
+
+ emits: ['close', 'method-selected'],
+
+ setup(props, { emit }) {
+ const selectedMethod = ref('guided');
+ const closeModal = () => {
+ emit('close');
+ };
+ const continueToSelected = () => {
+ emit('method-selected', selectedMethod.value);
+ };
+ return {
+ selectedMethod,
+ closeModal,
+ continueToSelected
+ };
+ }
+});
+</script>
+
+<style src="@/assets/css/CreateResource.css" scoped></style>
+<!-- SecretsCreateYaml.vue -->
+<template>
+ <div v-if="show" class="modal-overlay" @click="closeModal">
+ <div class="modal-content yaml-editor" @click.stop>
+ <div class="modal-header">
+ <h3>Create Secret from YAML</h3>
+ <button class="close-button" @click="closeModal">×</button>
+ </div>
+
+ <div class="modal-body">
+ <div v-if="error" class="error-message">{{ error }}</div>
+
+ <div class="yaml-container">
+ <textarea
+ v-model="yamlContent"
+ placeholder="Paste your Secret YAML definition here..."
+ :disabled="isSubmitting"
+ class="yaml-textarea"
+ ></textarea>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <button
+ class="cancel-button"
+ @click="closeModal"
+ :disabled="isSubmitting"
+ >
+ Cancel
+ </button>
+ <button
+ class="create-button"
+ @click="createSecretFromYaml"
+ :disabled="isSubmitting || !yamlContent.trim()"
+ >
+ {{ isSubmitting ? 'Creating...' : 'Create Secret' }}
+ </button>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script lang="ts">
+import { defineComponent, ref } from 'vue';
+
+export default defineComponent({
+ name: 'CreateSecretYaml',
+
+ props: {
+ show: {
+ type: Boolean,
+ default: false
+ }
+ },
+
+ emits: ['close', 'create-secret'],
+
+ setup(props, { emit }) {
+ // State
+ const yamlContent = ref('');
+ const isSubmitting = ref(false);
+ const error = ref('');
+
+ // Methods
+ const closeModal = () => {
+ if (!isSubmitting.value) {
+ emit('close');
+ }
+ };
+
+ const createSecretFromYaml = async () => {
+ isSubmitting.value = true;
+ error.value = '';
+
+ try {
+ const opts = {
+ yamlContent: yamlContent.value,
+ isYaml: true
+ };
+
+ emit('create-secret', opts);
+ closeModal();
+ } catch (err: any) {
+ error.value = `Failed to create Secret: ${err.message || err}`;
+ } finally {
+ isSubmitting.value = false;
+ }
+ };
+
+ return {
+ yamlContent,
+ isSubmitting,
+ error,
+ closeModal,
+ createSecretFromYaml
+ };
+ }
+});
+</script>
+
+<style src="@/assets/css/MenuDialog.css" scoped></style>
+<!-- SecretsEdit.vue -->
+<script lang="ts">
+import { defineComponent, ref, watch, PropType } from 'vue';
+import { KubernetesSecret, KubernetesCluster } from '../types/kubernetes';
+import { kubernetesService } from '../lib/kubernetes';
+import { secretJsonToYaml } from '../lib/lib';
+import { SecretUpdateOptions } from '../types/custom';
+
+export default defineComponent({
+ name: 'SecretsEdit',
+
+ props: {
+ show: {
+ type: Boolean,
+ default: false
+ },
+ secret: {
+ type: Object as PropType<KubernetesSecret | null>,
+ default: null
+ },
+ cluster: {
+ type: Object as PropType<KubernetesCluster | null>,
+ default: null
+ }
+ },
+
+ emits: ['close', 'update-secret'],
+ setup(props, { emit }) {
+ // State
+ const yamlContent = ref('');
+ const isLoading = ref(false);
+ const isSubmitting = ref(false);
+ const error = ref('');
+ const originalSecretName = ref('');
+
+ // Watch for changes to show prop
+ watch(() => props.show, (newVal) => {
+ if (newVal && props.secret) {
+ fetchSecretYaml();
+ } else {
+ yamlContent.value = '';
+ error.value = '';
+ }
+ });
+
+ // Methods
+ const closeModal = () => {
+ if (!isSubmitting.value) {
+ emit('close');
+ }
+ };
+
+ const fetchSecretYaml = async () => {
+ if (!props.secret || !props.cluster) return;
+
+ isLoading.value = true;
+ error.value = '';
+
+ originalSecretName.value = props.secret.metadata.name;
+
+ try {
+ const response = await kubernetesService.getSecret(
+ props.cluster.contextName,
+ props.secret.metadata.namespace,
+ props.secret.metadata.name
+ );
+
+ if (response.success) {
+ yamlContent.value = secretJsonToYaml(response.data);
+ } else {
+ error.value = response.msg || 'Failed to fetch secret YAML';
+ }
+ } catch (err: any) {
+ error.value = `Error fetching secret YAML: ${err.message || err}`;
+ } finally {
+ isLoading.value = false;
+ }
+ };
+
+ const updateSecret = (): void => {
+ const opts: SecretUpdateOptions = {
+ context: props.cluster.contextName,
+ definition: yamlContent.value,
+ origNamespace: props.secret.metadata.namespace,
+ origName: props.secret.metadata.name
+ }
+ try {
+ emit('update-secret', opts)
+ closeModal()
+ } catch (error: any) {
+ alert(error)
+ }
+ return
+ };
+
+ return {
+ yamlContent,
+ isLoading,
+ isSubmitting,
+ error,
+ originalSecretName,
+ closeModal,
+ fetchSecretYaml,
+ updateSecret
+ };
+ }
+});
+</script>
+
+
+<template>
+ <div v-if="show" class="modal-overlay" @click="closeModal">
+ <div class="modal-content yaml-editor" @click.stop>
+ <div class="modal-header">
+ <h3>Edit Secret YAML</h3>
+ <button class="close-button" @click="closeModal">×</button>
+ </div>
+
+ <div class="modal-body">
+ <div v-if="error" class="error-message">{{ error }}</div>
+ <div v-if="isLoading" class="loading-message">Loading secret YAML...</div>
+
+ <div v-if="!isLoading" class="yaml-container">
+ <textarea
+ v-model="yamlContent"
+ :disabled="isSubmitting"
+ class="yaml-textarea"
+ ></textarea>
+ </div>
+ </div>
+
+ <div class="modal-footer">
+ <button
+ class="cancel-button"
+ @click="closeModal"
+ :disabled="isSubmitting"
+ >
+ Cancel
+ </button>
+ <button
+ class="update-button"
+ @click="updateSecret"
+ :disabled="isSubmitting || isLoading || !yamlContent.trim()"
+ >
+ {{ isSubmitting ? 'Updating...' : 'Update Secret' }}
+ </button>
+ </div>
+ </div>
+ </div>
+</template>
+
+
+<style src="@/assets/css/MenuDialog.css" scoped></style>
+<!-- SecretsList.vue -->
+<script lang="ts">
+import { defineComponent, ref, computed, PropType, onBeforeUnmount } from 'vue';
+import { KubernetesCluster, KubernetesSecret } from '../types/kubernetes';
+import { formatAge } from '../lib/format';
+import SearchBar from './SearchBar.vue';
+import SecretsCreateMethodSelector from './SecretsCreateMethodSelector.vue';
+import SecretsCreateYaml from './SecretsCreateYaml.vue';
+import SecretsCreateGuided from './SecretsCreateGuided.vue';
+import SecretsEdit from './SecretsEdit.vue';
+import { SecretUpdateOptions } from '../types/custom';
+
+export default defineComponent({
+ name: 'SecretsList',
+
+ components: {
+ SearchBar,
+ SecretsCreateMethodSelector,
+ SecretsCreateYaml,
+ SecretsCreateGuided,
+ SecretsEdit
+ },
+
+ props: {
+ selectedCluster: {
+ type: Object as PropType<KubernetesCluster>,
+ required: false,
+ default: null
+ },
+ secrets: {
+ type: Array as PropType<KubernetesSecret[]>,
+ required: false,
+ default: () => []
+ }
+ },
+
+ emits: ['secret-selected', 'delete-secret', 'create-secret', 'update-secret'],
+
+ setup(props, { emit }) {
+ // State
+ const searchQuery = ref('');
+ const selectedSecret = ref<KubernetesSecret | null>(null);
+ const selectedContextSecret = ref<KubernetesSecret | null>(null);
+ const showMenu = ref(false);
+ const menuPosition = ref({ x: 0, y: 0 });
+
+ const showMethodSelector = ref(false);
+ const showCreateGuided = ref(false);
+ const showCreateYaml = ref(false);
+ const showEditYaml = ref(false);
+
+ // Computed properties
+ const filteredSecrets = computed(() => {
+ if (!searchQuery.value) {
+ return props.secrets;
+ }
+
+ const query = searchQuery.value.toLowerCase();
+
+ const nameSpecificMatch = query.match(/^name:(.+)$/);
+ if (nameSpecificMatch) {
+ const nameQuery = nameSpecificMatch[1].trim();
+ return props.secrets.filter(secret => {
+ const name = secret.metadata.name.toLowerCase();
+ return name.includes(nameQuery);
+ });
+ }
+
+ const statusSpecificMatch = query.match(/^status:(.+)$/);
+ if (statusSpecificMatch) {
+ const statusQuery = statusSpecificMatch[1].trim();
+ return props.secrets.filter(secret => {
+ const status = secret.status?.phase?.toLowerCase() || '';
+ return status.includes(statusQuery);
+ });
+ }
+
+ const labelSpecificMatch = query.match(/^label:(.+)$/);
+ if (labelSpecificMatch) {
+ const labelQuery = labelSpecificMatch[1].trim();
+ return props.secrets.filter(secret => {
+ const labels = secret.metadata.labels || {};
+ for (const key in labels) {
+ const value = labels[key].toLowerCase();
+ const keyLower = key.toLowerCase();
+
+ // Check for key=value format
+ if (labelQuery.includes('=')) {
+ const [queryKey, queryValue] = labelQuery.split('=');
+ if (keyLower === queryKey.trim().toLowerCase() &&
+ value.includes(queryValue.trim().toLowerCase())) {
+ return true;
+ }
+ }
+ // Check for just key
+ else if (keyLower.includes(labelQuery)) {
+ return true;
+ }
+ }
+ return false;
+ });
+ }
+
+ // Default behavior: search only in secret names
+ return props.secrets.filter(secret => {
+ const name = secret.metadata.name.toLowerCase();
+ return name.includes(query);
+ });
+ });
+
+ // Methods
+ const hideContextMenu = () => {
+ showMenu.value = false;
+ document.removeEventListener('click', hideContextMenu);
+ };
+
+ const showContextMenu = (event: MouseEvent, secret: KubernetesSecret) => {
+ event.preventDefault();
+
+ menuPosition.value = {
+ x: event.clientX,
+ y: event.clientY
+ };
+
+ selectedContextSecret.value = secret;
+ selectSecret(secret);
+ showMenu.value = true;
+
+ setTimeout(() => {
+ document.addEventListener('click', hideContextMenu);
+ }, 0);
+ };
+
+ const isSelected = (secret: KubernetesSecret): boolean => {
+ if (!selectedSecret.value) return false;
+ return selectedSecret.value.metadata.name === secret.metadata.name &&
+ selectedSecret.value.metadata.uid === secret.metadata.uid;
+ };
+
+ const selectSecret = (secret: KubernetesSecret): void => {
+ try {
+ const secretToEmit = { ...secret };
+ if (!secretToEmit.kind) {
+ secretToEmit.kind = 'Secret';
+ }
+ selectedSecret.value = secretToEmit;
+ emit('secret-selected', secretToEmit);
+ } catch (error) {
+ console.error("Failed to select secret:", error);
+ }
+ };
+
+ const deleteSecret = (): void => {
+ if (selectedContextSecret.value && props.selectedCluster) {
+ try {
+ emit('delete-secret', {
+ cluster: props.selectedCluster,
+ secret: selectedContextSecret.value
+ });
+ } catch (error) {
+ alert(error);
+ }
+ }
+ hideContextMenu();
+ };
+
+ const getUniqueKey = (secret: KubernetesSecret): string => {
+ return `${secret.metadata.name}-${secret.metadata.uid || ''}`;
+ };
+
+ const getSecretStatus = (secret: KubernetesSecret): string => {
+ return secret.status?.phase || 'Unknown';
+ };
+
+ const getSecretStatusClass = (secret: KubernetesSecret): string => {
+ const status = getSecretStatus(secret);
+ switch (status) {
+ case 'Active':
+ return 'status-active';
+ case 'Terminating':
+ return 'status-terminating';
+ default:
+ return 'status-unknown';
+ }
+ };
+
+ const editSecret = (): void => {
+ showEditYaml.value = true;
+ hideContextMenu();
+ };
+
+ const createSecret = (): void => {
+ showMethodSelector.value = true;
+ hideContextMenu();
+ };
+
+ const handleMethodSelected = (method: string): void => {
+ showMethodSelector.value = false;
+ if (method === 'guided') {
+ showCreateGuided.value = true;
+ } else if (method === 'yaml') {
+ showCreateYaml.value = true;
+ }
+ };
+
+ const handleUpdateSecret = (opts: SecretUpdateOptions): void => {
+ try {
+ emit('update-secret', opts)
+ } catch (error: any) {
+ alert(error)
+ }
+ return
+ }
+
+ const handleCreateSecret = (opts: SecretCreateOptions): void => {
+ try {
+ emit('create-secret', opts)
+ } catch (err: any) {
+ console.error('Failed to create Secret:', err)
+ } finally {
+ showCreateGuided.value = false
+ showCreateYaml.value = false
+ }
+ }
+
+ // Lifecycle hooks
+ onBeforeUnmount(() => {
+ document.removeEventListener('click', hideContextMenu);
+ });
+
+ // Return all refs, computed properties, and methods
+ return {
+ // State
+ showMethodSelector,
+ searchQuery,
+ selectedSecret,
+ selectedContextSecret,
+ showMenu,
+ showEditYaml,
+ menuPosition,
+ showCreateGuided,
+ showCreateYaml,
+
+ // Computed
+ filteredSecrets,
+
+ // Methods
+ hideContextMenu,
+ showContextMenu,
+ isSelected,
+ selectSecret,
+ deleteSecret,
+ getUniqueKey,
+ getSecretStatus,
+ getSecretStatusClass,
+ formatAge,
+ handleMethodSelected,
+ createSecret,
+ editSecret,
+ handleCreateSecret,
+ handleUpdateSecret
+ };
+ }
+});
+</script>
+
+<template>
+ <div class="secrets-container">
+ <div class="search-bar-container">
+ <SearchBar
+ :value="searchQuery"
+ @update:value="searchQuery = $event"
+ placeholder="Search secrets..."
+ />
+ </div>
+
+ <div v-if="filteredSecrets.length === 0" class="no-secrets">
+ <p v-if="searchQuery">No secrets found matching "{{ searchQuery }}"</p>
+ <p v-else>No secrets found.</p>
+ </div>
+
+ <div v-else class="table-scroll-container">
+ <table>
+ <thead>
+ <tr>
+ <th>Namespace</th>
+ <th>Name</th>
+ <th>Type</th>
+ <th>Data</th>
+ <th>Age</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr
+ v-for="secret in filteredSecrets"
+ :key="getUniqueKey(secret)"
+ :class="{ selected: isSelected(secret) }"
+ @click="selectSecret(secret)"
+ @contextmenu="showContextMenu($event, secret)"
+ >
+ <td>{{ secret.metadata.namespace }}</td>
+ <td>{{ secret.metadata.name }}</td>
+ <td>{{ secret.type }}</td>
+ <td>{{ secret.data ? Object.keys(secret.data).length : 0 }}</td>
+ <td>{{ formatAge(secret.metadata.creationTimestamp) }}</td>
+ </tr>
+ </tbody>
+ </table>
+ <div
+ v-if="showMenu"
+ class="context-menu"
+ :style="{ top: menuPosition.y + 'px', left: menuPosition.x + 'px' }"
+ @click.stop
+ >
+ <div class="menu-item" @click="createSecret">
+ Create
+ </div>
+ <div class="menu-item" @click="editSecret">
+ Edit
+ </div>
+ <div class="menu-item" @click="deleteSecret">
+ Delete
+ </div>
+ </div>
+ </div>
+
+ <SecretsCreateMethodSelector
+ :show="showMethodSelector"
+ @close="showMethodSelector = false"
+ @method-selected="handleMethodSelected"
+ />
+
+ <SecretsCreateYaml
+ :show="showCreateYaml"
+ @close="showCreateYaml = false"
+ @create-secret="handleCreateSecret"
+ />
+
+ <SecretsCreateGuided
+ :show="showCreateGuided"
+ :cluster="selectedCluster"
+ @close="showCreateGuided = false"
+ @create-secret="handleCreateSecret"
+ />
+
+ <SecretsEdit
+ :show="showEditYaml"
+ :secret="selectedContextSecret"
+ :cluster="selectedCluster"
+ @close="showEditYaml = false"
+ @update-secret="handleUpdateSecret"
+ />
+
+ </div>
+</template>
+
+<style src="@/assets/css/ListResource.css" scoped></style>
+<script lang="ts">
+import { defineComponent, ref, computed, PropType, onBeforeUnmount } from 'vue';
+import { KubernetesCluster, KubernetesStatefulSet } from '../types/kubernetes';
+import SearchBar from './SearchBar.vue';
+import { formatAge } from '../lib/format';
+
+export default defineComponent({
+ name: 'StatefulSetsList',
+ components: {
+ SearchBar
+ },
+ props: {
+ selectedCluster: {
+ type: Object as PropType<KubernetesCluster>,
+ required: false,
+ default: null
+ },
+ statefulSets: {
+ type: Array as PropType<KubernetesStatefulSet[]>,
+ required: false,
+ default: () => []
+ }
+ },
+ emits: ['statefulset-selected', 'restart-statefulset'],
+ data() {
+ return {
+ selectedStatefulSet: null as KubernetesStatefulSet | null
+ };
+ },
+ setup(props, { emit }) {
+ const searchQuery = ref('');
+ const filteredStatefulSets = computed(() => {
+ if (!searchQuery.value) {
+ return props.statefulSets;
+ }
+
+ const query = searchQuery.value.toLowerCase();
+
+ const nameSpecificMatch = query.match(/^name:(.+)$/);
+ if (nameSpecificMatch) {
+ const nameQuery = nameSpecificMatch[1].trim();
+ return props.statefulSets.filter(statefulSet => {
+ const name = statefulSet.metadata.name.toLowerCase();
+ return name.includes(nameQuery);
+ });
+ }
+
+ const namespaceSpecificMatch = query.match(/^namespace:(.+)$/);
+ if (namespaceSpecificMatch) {
+ const namespaceQuery = namespaceSpecificMatch[1].trim();
+ return props.statefulSets.filter(statefulSet => {
+ const namespace = statefulSet.metadata.namespace.toLowerCase();
+ return namespace.includes(namespaceQuery);
+ });
+ }
+
+ const labelMatch = query.match(/^label:(.+)$/);
+ if (labelMatch) {
+ const labelQuery = labelMatch[1].trim();
+ return props.statefulSets.filter(statefulset => {
+ const labels = statefulset.metadata.labels || {};
+ for (const key in labels) {
+ const value = labels[key].toLowerCase();
+ const keyLower = key.toLowerCase();
+
+ if (labelQuery.includes('=')) {
+ const [queryKey, queryValue] = labelQuery.split('=');
+ if (keyLower === queryKey.trim().toLowerCase() &&
+ value.includes(queryValue.trim().toLowerCase())) {
+ return true;
+ }
+ } else if (keyLower.includes(labelQuery)) {
+ return true;
+ }
+ }
+ return false;
+ });
+ }
+
+ return props.statefulSets.filter(statefulSet => {
+ const name = statefulSet.metadata.name.toLowerCase();
+ return name.includes(query);
+ });
+ });
+
+ const showMenu = ref(false);
+ const menuPosition = ref({ x: 0, y: 0});
+ const selectedContextStatefulSet = ref<KubernetesStatefulSet | null>(null);
+
+ // Function to handle document click for hiding context menu
+ const handleDocumentClick = () => {
+ showMenu.value = false;
+ };
+
+ const showContextMenu = (event: MouseEvent, statefulSet: KubernetesStatefulSet) => {
+ event.preventDefault();
+ event.stopPropagation();
+
+ // Hide any existing menu first
+ showMenu.value = false;
+
+ // Set new menu position and selected item
+ menuPosition.value = {
+ x: event.clientX,
+ y: event.clientY
+ };
+
+ selectedContextStatefulSet.value = statefulSet;
+
+ // Show the menu after a small delay to avoid immediate closing
+ setTimeout(() => {
+ showMenu.value = true;
+ document.addEventListener('click', handleDocumentClick);
+ }, 10);
+ };
+
+ const hideContextMenu = () => {
+ showMenu.value = false;
+ document.removeEventListener('click', handleDocumentClick);
+ };
+
+ // Proper lifecycle cleanup
+ onBeforeUnmount(() => {
+ document.removeEventListener('click', handleDocumentClick);
+ });
+
+ return {
+ searchQuery,
+ filteredStatefulSets,
+ showMenu,
+ menuPosition,
+ selectedContextStatefulSet,
+ showContextMenu,
+ hideContextMenu,
+ formatAge
+ };
+ },
+ methods: {
+ isSelected(statefulSet: KubernetesStatefulSet): boolean {
+ return this.selectedStatefulSet?.metadata.name === statefulSet.metadata.name;
+ },
+ selectStatefulSet(statefulSet: KubernetesStatefulSet): void {
+ const statefulSetToEmit = { ...statefulSet };
+ if (!statefulSetToEmit.kind) {
+ statefulSetToEmit.kind = 'StatefulSet'
+ }
+ this.selectedStatefulSet = statefulSetToEmit;
+ this.$emit('statefulset-selected', statefulSetToEmit);
+ },
+ getUniqueKey(statefulSet: KubernetesStatefulSet): string {
+ let uniqueKey;
+ const namespace = statefulSet.metadata.namespace || 'default';
+ uniqueKey = namespace + '-' + statefulSet.metadata.name + '-' + (statefulSet.metadata.uid || '');
+ return uniqueKey;
+ },
+ restartStatefulSet() {
+ if (this.selectedContextStatefulSet && this.selectedCluster) {
+ this.$emit('restart-statefulset', {
+ cluster: this.selectedCluster,
+ statefulSet: this.selectedContextStatefulSet
+ });
+ }
+ this.hideContextMenu();
+ },
+ getReadyReplicas(statefulSet: KubernetesStatefulSet): string {
+ return (statefulSet.status.readyReplicas || 0) + '/' + statefulSet.spec.replicas;
+ }
+ },
+});
+</script>
+
+<template>
+ <div class="statefulsets-container">
+ <div class="search-bar-container">
+ <SearchBar
+ :value="searchQuery"
+ @update:value="searchQuery = $event"
+ placeholder="Search statefulsets..."
+ />
+ </div>
+ <div class="table-scroll-container">
+ <table>
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Namespace</th>
+ <th>Ready</th>
+ <th>Up-to-date</th>
+ <th>Available</th>
+ <th>Age</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr
+ v-for="statefulSet in filteredStatefulSets"
+ :key="getUniqueKey(statefulSet)"
+ :class="{ selected: isSelected(statefulSet) }"
+ @click="selectStatefulSet(statefulSet)"
+ @contextmenu.prevent="showContextMenu($event, statefulSet)"
+ >
+ <td>{{ statefulSet.metadata.name }}</td>
+ <td>{{ statefulSet.metadata.namespace || 'default' }}</td>
+ <td>{{ getReadyReplicas(statefulSet) }}</td>
+ <td>{{ statefulSet.status.updatedReplicas || 0 }}</td>
+ <td>{{ statefulSet.status.availableReplicas || 0 }}</td>
+ <td>{{ formatAge(statefulSet.metadata.creationTimestamp) }}</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div
+ v-if="showMenu"
+ class="context-menu"
+ :style="{ top: menuPosition.y + 'px', left: menuPosition.x + 'px' }"
+ >
+ <div class="menu-item" @click="restartStatefulSet">
+ <span class="menu-text">Restart</span>
+ </div>
+ </div>
+ </div>
+</template>
+
+<style src="@/assets/css/StatefulSetsList.css" scoped></style>
+
+<script>
+import { Terminal } from '@xterm/xterm';
+import { FitAddon } from '@xterm/addon-fit';
+import { WebLinksAddon } from '@xterm/addon-web-links';
+import '@xterm/xterm/css/xterm.css';
+
+export default {
+ name: 'Terminal',
+
+ props: {
+ selectedPod: {
+ type: Object,
+ required: true
+ },
+ selectedNamespace: {
+ type: Object,
+ required: true
+ },
+ selectedCluster: {
+ type: Object,
+ required: true
+ }
+ },
+
+ data() {
+ return {
+ terminal: null,
+ fitAddon: null,
+ socket: null,
+ isConnected: false,
+ reconnectAttempts: 0,
+ maxReconnectAttempts: 3
+ }
+ },
+
+ mounted() {
+ this.initializeTerminal();
+ window.addEventListener('resize', this.onResize);
+ },
+
+ beforeUnmount() {
+ this.cleanup();
+ window.removeEventListener('resize', this.onResize);
+ },
+
+ methods: {
+ initializeTerminal() {
+ // Initialize xterm.js terminal
+ this.terminal = new Terminal({
+ cursorBlink: true,
+ fontSize: 14,
+ fontFamily: 'Menlo, Monaco, "Courier New", monospace',
+ theme: {
+ background: '#1e1e1e',
+ foreground: '#ffffff',
+ cursor: '#ffffff',
+ selection: 'rgba(255, 255, 255, 0.3)',
+ black: '#000000',
+ blue: '#2472c8',
+ brightBlue: '#3b8eea',
+ brightCyan: '#29b8db',
+ brightGreen: '#23d18b',
+ brightMagenta: '#d670d6',
+ brightRed: '#f14c4c',
+ brightWhite: '#e5e5e5',
+ brightYellow: '#f5f543',
+ cyan: '#11a8cd',
+ green: '#0dbc79',
+ magenta: '#bc3fbc',
+ red: '#cd3131',
+ white: '#e5e5e5',
+ yellow: '#e5e510'
+ }
+ });
+
+ // Add the fit addon
+ this.fitAddon = new FitAddon();
+ this.terminal.loadAddon(this.fitAddon);
+
+ // Add web links addon
+ this.terminal.loadAddon(new WebLinksAddon());
+
+ // Open terminal in the container
+ this.terminal.open(this.$refs.terminal);
+
+ // Initial fit
+ setTimeout(() => {
+ this.fitAddon.fit();
+ }, 100);
+
+ // Connect to WebSocket
+ this.connectWebSocket();
+ },
+
+ connectWebSocket() {
+ // If already connecting, don't try again
+ if (this.isReconnecting) {
+ return;
+ }
+
+ this.isReconnecting = true;
+
+ // Close existing socket if any
+ if (this.socket) {
+ this.socket.close();
+ this.socket = null;
+ }
+
+ const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
+ const wsUrl = `${wsProtocol}//${window.location.hostname}:8081/api/pods/exec?` +
+ `cluster=${encodeURIComponent(this.selectedCluster.server)}&` +
+ `namespace=${encodeURIComponent(this.selectedNamespace.name)}&` +
+ `pod=${encodeURIComponent(this.selectedPod.metadata.name)}`;
+
+ try {
+ this.socket = new WebSocket(wsUrl);
+
+ this.socket.onopen = () => {
+ this.isConnected = true;
+ this.reconnectAttempts = 0;
+ this.isReconnecting = false;
+ this.terminal.writeln('Connected to pod shell...');
+ this.terminal.focus();
+ };
+
+ this.socket.onmessage = (event) => {
+ if (this.terminal) {
+ this.terminal.write(event.data);
+ }
+ };
+
+ this.socket.onclose = () => {
+ this.isConnected = false;
+ this.isReconnecting = false;
+ if (this.terminal) {
+ this.terminal.writeln('\r\nConnection closed');
+ }
+ };
+
+ this.socket.onerror = (error) => {
+ console.error('WebSocket error:', error);
+ this.isReconnecting = false;
+ if (this.terminal) {
+ this.terminal.writeln('\r\nError: Failed to connect to pod shell');
+ }
+ };
+
+ // Handle terminal input
+ if (!this.terminal._initialized) {
+ this.terminal.onData(data => {
+ if (this.isConnected && this.socket?.readyState === WebSocket.OPEN) {
+ this.socket.send(data);
+ }
+ });
+ this.terminal._initialized = true;
+ }
+
+ } catch (error) {
+ console.error('Failed to connect to WebSocket:', error);
+ this.isReconnecting = false;
+ if (this.terminal) {
+ this.terminal.writeln('Failed to connect to pod shell');
+ }
+ }
+ },
+
+ attemptReconnect() {
+ if (this.reconnectAttempts < this.maxReconnectAttempts) {
+ this.reconnectAttempts++;
+ this.terminal.writeln(`\r\nAttempting to reconnect (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`);
+ setTimeout(() => {
+ this.connectWebSocket();
+ }, 2000);
+ }
+ },
+
+ onResize() {
+ if (this.fitAddon) {
+ this.fitAddon.fit();
+ }
+ },
+
+
+ cleanup() {
+ if (this.socket) {
+ this.socket.close();
+ this.socket = null;
+ }
+
+ if (this.terminal) {
+ if (this.fitAddon) {
+ try {
+ this.fitAddon.dispose();
+ } catch (e) {
+ console.log('FitAddon cleanup:', e);
+ }
+ this.fitAddon = null;
+ }
+
+ try {
+ this.terminal.dispose();
+ } catch (e) {
+ console.log('Terminal cleanup:', e);
+ }
+ this.terminal = null;
+ }
+
+ this.isConnected = false;
+ this.isReconnecting = false;
+ this.reconnectAttempts = 0;
+ },
+
+ closeTerminal() {
+ this.cleanup();
+ this.$emit('close');
+ }
+
+ }
+}
+</script>
+
+<template>
+ <div class="terminal-container">
+ <div class="terminal-header">
+ <span>Terminal: {{ selectedPod?.metadata?.name }}</span>
+ <button @click="closeTerminal" class="close-btn">×</button>
+ </div>
+ <div id="terminal" ref="terminal" class="terminal-content"></div>
+ </div>
+</template>
+
+
+<style scoped>
+.terminal-container {
+ position: fixed;
+ bottom: 20px;
+ right: 20px;
+ width: 800px;
+ height: 500px;
+ background: #1e1e1e;
+ border: 1px solid #333;
+ border-radius: 6px;
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
+ z-index: 1000;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+}
+
+.terminal-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 8px 12px;
+ background: #333;
+ color: white;
+ font-size: 14px;
+ user-select: none;
+}
+
+.close-btn {
+ background: none;
+ border: none;
+ color: white;
+ font-size: 20px;
+ cursor: pointer;
+ padding: 0 4px;
+ line-height: 1;
+}
+
+.close-btn:hover {
+ color: #ff5252;
+}
+
+.terminal-content {
+ flex: 1;
+ padding: 4px;
+ background-color: #1e1e1e;
+ text-align: left; /* Add this */
+}
+
+:deep(.xterm) {
+ padding: 8px;
+ height: 100%;
+ text-align: left; /* Add this */
+}
+
+:deep(.xterm-viewport) {
+ background-color: #1e1e1e !important;
+}
+
+/* Add these new styles */
+:deep(.xterm-screen) {
+ text-align: left !important;
+}
+
+:deep(.xterm-rows) {
+ text-align: left !important;
+}
+</style>
+
+/**
+ * Formats a timestamp into a human-readable age string (e.g., "3h" or "2d5h")
+ *
+ * @param timestamp - ISO 8601 timestamp string
+ * @returns Formatted age string
+ */
+export function formatAge(timestamp: string): string {
+ const created = new Date(timestamp);
+ const now = new Date();
+ const diffHours = Math.floor((now.getTime() - created.getTime()) / (1000 * 60 * 60));
+ if (diffHours < 24) {
+ return `${diffHours}h`;
+ }
+ const diffDays = Math.floor(diffHours / 24);
+ return `${diffDays}d${diffHours % 24}h`;
+}
+import {
+ GetClusters,
+ GetDeployments,
+ GetPods,
+ GetPod,
+ GetStatefulSets,
+ GetNamespace,
+ RestartDeployment,
+ RestartStatefulSet,
+ DeletePod,
+ DescribePod,
+ GetConfigMaps,
+ DescribeConfigMap,
+ DescribeDeployment,
+ DescribeStatefulSet,
+ GetIngresses,
+ DescribeIngress,
+ DescribeNamespace,
+ DeleteIngress,
+ DeleteNamespace,
+ CreatePod,
+ CreatePodYAML,
+ CreateNamespace,
+ CreateNamespaceYAML,
+ UpdatePodFromYaml,
+ UpdateNamespaceFromYaml,
+ GetNamespaces
+} from '../../wailsjs/go/services/clusterService';
+import {
+ Get as GetSecret,
+ List as ListSecrets,
+ Describe as DescribeSecret,
+ Create as CreateSecret,
+ Delete as DeleteSecret,
+ Update as UpdateSecret
+} from '../../wailsjs/go/services/secretsService';
+import {
+ List as ListPersistentVolumeClaims,
+ Describe as DescribePersistentVolumeClaim,
+ Create as CreatePersistentVolumeClaim,
+ Delete as DeletePersistentVolumeClaim,
+} from '../../wailsjs/go/services/persistentVolumeClaimsService';
+import {
+ List as ListPersistentVolumes,
+ Describe as DescribePersistentVolume,
+ Create as CreatePersistentVolume,
+ Delete as DeletePersistentVolume,
+} from '../../wailsjs/go/services/persistentVolumesService';
+import {
+ ApiResponse,
+ KubernetesCluster,
+ KubernetesConfigMap,
+ KubernetesDeployment,
+ KubernetesIngress,
+ KubernetesNamespace
+} from '../types/kubernetes';
+
+export interface KubernetesService {
+ getClusters(): Promise<ApiResponse<KubernetesCluster[]>>;
+
+ getDeployments(contextName: string, namespace?: string): Promise<ApiResponse<any[]>>;
+ getStatefulSets(contextName: string, namespace?: string): Promise<ApiResponse<KubernetesDeployment[]>>;
+ getPods(clusterName: string, namespace?: string): Promise<ApiResponse<any[]>>;
+ getPod(context: string, namespace: string, name: string): Promise<ApiResponse<any>>;
+ getConfigMaps(contextName: string, namespace: string): Promise<ApiResponse<KubernetesConfigMap[]>>;
+ getIngresses(context: string, namespace: string): Promise<ApiResponse<KubernetesIngress[]>>;
+ getNamespaces(context: string): Promise<ApiResponse<KubernetesNamespace[]>>;
+ getNamespace(context: string, name: string): Promise<ApiResponse<any>>;
+ getSecret(context: string, namespace: string, name: string): Promise<ApiResponse<any>>;
+
+ listSecrets(context: string, namespace: string): Promise<ApiResponse<any>>;
+ listPersistentVolumeClaims(context: string, namespace: string): Promise<ApiResponse<any>>;
+ listPersistentVolumes(context: string, namespace: string): Promise<ApiResponse<any>>;
+
+ restartDeployment(clusterName: string, namespace: string, name: string): Promise<ApiResponse<any>>;
+ restartStatefulSet(clusterName: string, namespace: string, name: string): Promise<ApiResponse<any>>;
+
+ describePod(clusterName: string, namespace: string, name: string): Promise<ApiResponse<string>>;
+ describeDeployment(context: string, namespace: string, name: string): Promise<ApiResponse<string>>;
+ describeConfigMap(context: string, namespace: string, name: string): Promise<ApiResponse<string>>;
+ describeStatefulSet(context: string, namespace: string, name: string): Promise<ApiResponse<string>>;
+ describeIngress(context: string, namespace: string, name: string): Promise<ApiResponse<string>>;
+ describeNamespace(context: string, namespace: string): Promise<ApiResponse<string>>;
+ describeSecret(context: string, namespace: string, name: string): Promise<ApiResponse<string>>;
+ describePersistentVolumeClaim(context: string, namespace: string, name: string): Promise<ApiResponse<string>>;
+ describePersistentVolume(context: string, namespace: string, name: string): Promise<ApiResponse<string>>;
+
+ deletePod(clusterName: string, namespace: string, name: string): Promise<ApiResponse<any>>;
+ deleteIngress(context: string, namespace: string, name: string): Promise<ApiResponse<string>>;
+ deleteNamespace(context: string, name: string): Promise<ApiResponse<any>>;
+ deleteSecret(context: string, namespace: string, name: string): Promise<ApiResponse<any>>;
+ deletePersistentVolume(context: string, name: string): Promise<ApiResponse<any>>;
+ deletePersistentVolumeClaim(context: string, namespace: string, name: string): Promise<ApiResponse<any>>;
+
+ createPod(context: string, podDefinition: any): Promise<ApiResponse<any>>;
+ createPodYAML(context: string, s: string): Promise<ApiResponse<any>>;
+ createNamespace(context: string, definition: any): Promise<ApiResponse<KubernetesNamespace>>;
+ createNamespaceYAML(context: string, definition: any): Promise<ApiResponse<any>>;
+ createSecret(context: string, definition: any): Promise<ApiResponse<any>>;
+ createPersistentVolume(context: string, definition: any): Promise<ApiResponse<any>>;
+ createPersistentVolumeClaim(context: string, definition: any): Promise<ApiResponse<any>>;
+
+ updatePod(context: string, s: string, originalPodname: string, originalNamespace: string): Promise<ApiResponse<any>>;
+ updateNamespace(context: string, s: string, originalName: string): Promise<ApiResponse<any>>;
+ updateSecret(context: string, input: string, originalNamespace: string, originalName: string): Promise<ApiResponse<any>>;
+}
+
+class KubernetesServiceImpl implements KubernetesService {
+
+ async getClusters(): Promise<ApiResponse<KubernetesCluster[]>> {
+ return GetClusters();
+ }
+
+ async getDeployments(contextName: string, namespace?: string): Promise<ApiResponse<any[]>> {
+ return GetDeployments(contextName, namespace || '');
+ }
+
+ async getPods(clusterName: string, namespace?: string): Promise<ApiResponse<any[]>> {
+ return GetPods(clusterName, namespace || '');
+ }
+
+ async getPod(context: string, namespace: string, name: string): Promise<ApiResponse<any>> {
+ return GetPod(context, namespace, name);
+ }
+
+ async getIngresses(context: string, namespace?: string): Promise<ApiResponse<KubernetesIngress[]>> {
+ return GetIngresses(context, namespace || '');
+ }
+
+ async getNamespaces(context: string): Promise<ApiResponse<any>> {
+ return GetNamespaces(context);
+ }
+
+ async getNamespace(context: string, name: string): Promise<ApiResponse<any>> {
+ return GetNamespace(context, name);
+ }
+
+ async getSecret(context: string, namespace: string, name: string): Promise<ApiResponse<any>> {
+ return GetSecret(context, namespace, name);
+ }
+
+ async describePod(clusterName: string, namespace: string, name: string): Promise<ApiResponse<any>> {
+ return DescribePod(clusterName, namespace, name);
+ }
+
+ async describeDeployment(context: string, namespace: string, name: string): Promise<ApiResponse<string>> {
+ return DescribeDeployment(context, namespace, name);
+ }
+
+ async describeConfigMap(context: string, namespace: string, name: string): Promise<ApiResponse<string>> {
+ return DescribeConfigMap(context, namespace, name);
+ }
+
+ async describeStatefulSet(context: string, namespace: string, name: string): Promise<ApiResponse<string>> {
+ return DescribeStatefulSet(context, namespace, name);
+ }
+
+ async describeIngress(context: string, namespace: string, name: string): Promise<ApiResponse<string>> {
+ return DescribeIngress(context, namespace, name);
+ }
+
+ async describeNamespace(context: string, namespace: string): Promise<ApiResponse<string>> {
+ return DescribeNamespace(context, namespace);
+ }
+
+ async describeSecret(context: string, namespace: string, name: string): Promise<ApiResponse<string>> {
+ return DescribeSecret(context, namespace, name);
+ }
+
+ async describePersistentVolumeClaim(context: string, namespace: string, name: string): Promise<ApiResponse<string>> {
+ return DescribePersistentVolumeClaim(context, namespace, name);
+ }
+
+ async describePersistentVolume(context: string, namespace: string, name: string): Promise<ApiResponse<string>> {
+ return DescribePersistentVolume(context, namespace, name);
+ }
+
+ async getStatefulSets(contextName: string, namespace?: string): Promise<ApiResponse<any[]>> {
+ return GetStatefulSets(contextName, namespace || '');
+ }
+
+ async restartDeployment(clusterName: string, namespace: string, name: string): Promise<ApiResponse<any>> {
+ return RestartDeployment(clusterName, namespace, name);
+ }
+
+ async restartStatefulSet(clusterName: string, namespace: string, name: string): Promise<ApiResponse<any>> {
+ return RestartStatefulSet(clusterName, namespace, name);
+ }
+
+ async getConfigMaps(contextName: string, namespace?: string): Promise<ApiResponse<KubernetesConfigMap[]>> {
+ return GetConfigMaps(contextName, namespace || '');
+ }
+
+ async deletePod(clusterName: string, namespace: string, name: string): Promise<ApiResponse<any>> {
+ return DeletePod(clusterName, namespace, name);
+ }
+
+ async deleteIngress(context: string, namespace: string, name: string): Promise<ApiResponse<string>> {
+ return DeleteIngress(context, namespace, name);
+ }
+
+ async deleteNamespace(context: string, name: string): Promise<ApiResponse<string>> {
+ return DeleteNamespace(context, name);
+ }
+
+ async deleteSecret(context: string, namespace: string, name: string): Promise<ApiResponse<string>> {
+ return DeleteSecret(context, namespace, name);
+ }
+
+ async deletePersistentVolume(context: string, name: string): Promise<ApiResponse<any>> {
+ return DeletePersistentVolume(context, name);
+ }
+
+ async deletePersistentVolumeClaim(context: string, namespace: string, name: string): Promise<ApiResponse<any>> {
+ return DeletePersistentVolumeClaim(context, namespace, name);
+ }
+
+ async createPod(context: string, podDefinition: any): Promise<ApiResponse<string>> {
+ return CreatePod(context, podDefinition);
+ }
+
+ async createPodYAML(context: string, s: string): Promise<ApiResponse<string>> {
+ return CreatePodYAML(context, s);
+ }
+
+ async createNamespace(context: string, definition: any): Promise<ApiResponse<any>> {
+ return CreateNamespace(context, definition);
+ }
+
+ async createNamespaceYAML(context: string, s: string): Promise<ApiResponse<any>> {
+ return CreateNamespaceYAML(context, s);
+ }
+
+ async createSecret(context: string, input: any): Promise<ApiResponse<any>> {
+ return CreateSecret(context, input);
+ }
+
+ async createPersistentVolume(context: string, definition: any): Promise<ApiResponse<any>> {
+ return CreatePersistentVolume(context, definition);
+ }
+
+ async createPersistentVolumeClaim(context: string, definition: any): Promise<ApiResponse<any>> {
+ return CreatePersistentVolumeClaim(context, definition);
+ }
+
+ async updatePod(context: string, s: string, originalPodname: string, originalNamespace: string): Promise<ApiResponse<any>> {
+ return UpdatePodFromYaml(context, s, originalPodname, originalNamespace);
+ }
+
+ async updateNamespace(context: string, s: string, originalName: string): Promise<ApiResponse<any>> {
+ return UpdateNamespaceFromYaml(context, s, originalName);
+ }
+
+ async updateSecret(context: string, input: string, originalNamespace: string, originalName: string): Promise<ApiResponse<any>> {
+ return UpdateSecret(context, input, originalNamespace, originalName);
+ }
+
+ async listSecrets(context: string, namespace?: string): Promise<ApiResponse<any>> {
+ return ListSecrets(context, namespace || '');
+ }
+
+ async listPersistentVolumeClaims(context: string, namespace?: string): Promise<ApiResponse<any>> {
+ return ListPersistentVolumeClaims(context, namespace || '');
+ }
+
+ async listPersistentVolumes(context: string): Promise<ApiResponse<any>> {
+ return ListPersistentVolumes(context);
+ }
+}
+
+export const kubernetesService: KubernetesService = new KubernetesServiceImpl();
+import jsYaml from 'js-yaml';
+
+/**
+ * Formats a Kubernetes resource into a human-readable description
+ * @param resource The Kubernetes resource to format
+ * @returns A formatted description string
+ */
+export function formatResourceDescription(resource: any): string {
+ if (!resource) {
+ return 'No resource data available';
+ }
+
+ let result = '';
+
+ // Extract metadata
+ const metadata = resource.metadata || {};
+ const spec = resource.spec || {};
+ const status = resource.status || {};
+
+ // Basic metadata
+ result += `Name: ${metadata.name || '<unknown>'}\n`;
+ result += `Namespace: ${metadata.namespace || '<unknown>'}\n`;
+ result += `Kind: ${resource.kind || '<unknown>'}\n`;
+ result += `API Version: ${resource.apiVersion || '<unknown>'}\n`;
+
+ // Creation timestamp
+ if (metadata.creationTimestamp) {
+ const creationDate = new Date(metadata.creationTimestamp);
+ result += `Created: ${creationDate.toUTCString()}\n`;
+ }
+
+ // Labels
+ result += 'Labels: ';
+ if (metadata.labels && Object.keys(metadata.labels).length > 0) {
+ result += '\n';
+ for (const [key, value] of Object.entries(metadata.labels)) {
+ result += ` ${key}=${value}\n`;
+ }
+ } else {
+ result += '<none>\n';
+ }
+
+ // Annotations
+ result += 'Annotations: ';
+ if (metadata.annotations && Object.keys(metadata.annotations).length > 0) {
+ result += '\n';
+ for (const [key, value] of Object.entries(metadata.annotations)) {
+ result += ` ${key}=${value}\n`;
+ }
+ } else {
+ result += '<none>\n';
+ }
+
+ // Check if it's a Pod
+ const isPod = resource.kind === 'Pod';
+
+ // Check if it's a Deployment
+ const isDeployment = resource.kind === 'Deployment';
+
+ // Pod-specific information
+ if (isPod) {
+ // Pod status
+ const phase = status.phase || '<unknown>';
+ const podIP = status.podIP || '<none>';
+ const nodeName = spec.nodeName || '<none>';
+
+ result += `Status: ${phase}\n`;
+ result += `IP: ${podIP}\n`;
+ result += `Node: ${nodeName}\n`;
+
+ // Containers
+ result += 'Containers:\n';
+ const containers = spec.containers || [];
+ if (containers.length > 0) {
+ for (const container of containers) {
+ result += ` ${container.name}:\n`;
+ result += ` Image: ${container.image || '<none>'}\n`;
+
+ // Container ports
+ result += ' Ports: ';
+ const ports = container.ports || [];
+ if (ports.length > 0) {
+ result += '\n';
+ for (const port of ports) {
+ const protocol = port.protocol || 'TCP';
+ const portStr = ` ${protocol}:${port.containerPort}`;
+ if (port.name) {
+ result += `${portStr} (${port.name})\n`;
+ } else {
+ result += `${portStr}\n`;
+ }
+ }
+ } else {
+ result += '<none>\n';
+ }
+
+ // Container environment variables
+ result += ' Environment:';
+ const env = container.env || [];
+ if (env.length > 0) {
+ result += '\n';
+ for (const envVar of env) {
+ let envStr = ` ${envVar.name}=`;
+ if (envVar.value !== undefined) {
+ envStr += envVar.value;
+ } else if (envVar.valueFrom) {
+ envStr += '<set from source>';
+ } else {
+ envStr += '<unset>';
+ }
+ result += `${envStr}\n`;
+ }
+ } else {
+ result += ' <none>\n';
+ }
+
+ // Container resources
+ result += ' Resources: ';
+ const resources = container.resources || {};
+ if ((resources.limits && Object.keys(resources.limits).length > 0) ||
+ (resources.requests && Object.keys(resources.requests).length > 0)) {
+ result += '\n';
+
+ // Limits
+ if (resources.limits && Object.keys(resources.limits).length > 0) {
+ result += ' Limits:\n';
+ for (const [key, value] of Object.entries(resources.limits)) {
+ result += ` ${key}: ${value}\n`;
+ }
+ }
+
+ // Requests
+ if (resources.requests && Object.keys(resources.requests).length > 0) {
+ result += ' Requests:\n';
+ for (const [key, value] of Object.entries(resources.requests)) {
+ result += ` ${key}: ${value}\n`;
+ }
+ }
+ } else {
+ result += '<none>\n';
+ }
+
+ // Container status
+ const containerStatuses = status.containerStatuses || [];
+ for (const containerStatus of containerStatuses) {
+ if (containerStatus.name === container.name) {
+ result += ` Ready: ${containerStatus.ready}\n`;
+ result += ` Restarts: ${containerStatus.restartCount}\n`;
+
+ // Container state
+ result += ' State: ';
+ const state = containerStatus.state || {};
+ if (state.running) {
+ const startedAt = state.running.startedAt;
+ if (startedAt) {
+ const startDate = new Date(startedAt);
+ result += `Running since ${startDate.toUTCString()}\n`;
+ } else {
+ result += 'Running\n';
+ }
+ } else if (state.waiting) {
+ const reason = state.waiting.reason || '';
+ const message = state.waiting.message || '';
+ result += `Waiting: ${reason} - ${message}\n`;
+ } else if (state.terminated) {
+ const reason = state.terminated.reason || '';
+ const exitCode = state.terminated.exitCode || 0;
+ result += `Terminated: ${reason} (exit code: ${exitCode})\n`;
+ } else {
+ result += 'Unknown\n';
+ }
+ break;
+ }
+ }
+ }
+ } else {
+ result += ' <none>\n';
+ }
+
+ // Pod conditions
+ result += 'Conditions:\n';
+ const conditions = status.conditions || [];
+ if (conditions.length > 0) {
+ for (const condition of conditions) {
+ let condStr = ` ${condition.type}: ${condition.status}`;
+ if (condition.reason) {
+ condStr += ` (${condition.reason})`;
+ }
+ if (condition.message) {
+ condStr += ` - ${condition.message}`;
+ }
+ result += `${condStr}\n`;
+ }
+ } else {
+ result += ' <none>\n';
+ }
+ }
+
+ // Deployment-specific information
+ if (isDeployment) {
+ // Replicas
+ const replicas = spec.replicas !== undefined ? spec.replicas : 0;
+ result += `Replicas: ${replicas} desired`;
+
+ if (status) {
+ const updatedReplicas = status.updatedReplicas !== undefined ? status.updatedReplicas : 0;
+ const totalReplicas = status.replicas !== undefined ? status.replicas : 0;
+ const availableReplicas = status.availableReplicas !== undefined ? status.availableReplicas : 0;
+ const unavailableReplicas = status.unavailableReplicas !== undefined ? status.unavailableReplicas : 0;
+
+ result += ` | ${updatedReplicas} updated`;
+ result += ` | ${totalReplicas} total`;
+ result += ` | ${availableReplicas} available`;
+ result += ` | ${unavailableReplicas} unavailable`;
+ }
+ result += '\n';
+
+ // Strategy
+ let strategyType = 'Unknown';
+ if (spec.strategy && spec.strategy.type) {
+ strategyType = spec.strategy.type;
+ }
+ result += `Strategy: ${strategyType}\n`;
+
+ // Selector
+ result += 'Selector: ';
+ if (spec.selector && spec.selector.matchLabels && Object.keys(spec.selector.matchLabels).length > 0) {
+ result += '\n';
+ for (const [key, value] of Object.entries(spec.selector.matchLabels)) {
+ result += ` ${key}=${value}\n`;
+ }
+ } else {
+ result += '<none>\n';
+ }
+
+ // Pod template
+ if (spec.template) {
+ result += 'Pod Template:\n';
+
+ // Template labels
+ result += ' Labels: ';
+ if (spec.template.metadata && spec.template.metadata.labels &&
+ Object.keys(spec.template.metadata.labels).length > 0) {
+ result += '\n';
+ for (const [key, value] of Object.entries(spec.template.metadata.labels)) {
+ result += ` ${key}=${value}\n`;
+ }
+ } else {
+ result += '<none>\n';
+ }
+
+ // Template containers
+ result += ' Containers:\n';
+ if (spec.template.spec && spec.template.spec.containers && spec.template.spec.containers.length > 0) {
+ for (const container of spec.template.spec.containers) {
+ result += ` ${container.name}:\n`;
+ result += ` Image: ${container.image || '<none>'}\n`;
+
+ // Container ports
+ result += ' Ports: ';
+ const ports = container.ports || [];
+ if (ports.length > 0) {
+ result += '\n';
+ for (const port of ports) {
+ const protocol = port.protocol || 'TCP';
+ const portStr = ` ${protocol}:${port.containerPort}`;
+ if (port.name) {
+ result += `${portStr} (${port.name})\n`;
+ } else {
+ result += `${portStr}\n`;
+ }
+ }
+ } else {
+ result += '<none>\n';
+ }
+
+ // Container environment variables
+ result += ' Environment:';
+ const env = container.env || [];
+ if (env.length > 0) {
+ result += '\n';
+ for (const envVar of env) {
+ let envStr = ` ${envVar.name}=`;
+ if (envVar.value !== undefined) {
+ envStr += envVar.value;
+ } else if (envVar.valueFrom) {
+ envStr += '<set from source>';
+ } else {
+ envStr += '<unset>';
+ }
+ result += `${envStr}\n`;
+ }
+ } else {
+ result += ' <none>\n';
+ }
+
+ // Container resources
+ result += ' Resources: ';
+ const resources = container.resources || {};
+ if ((resources.limits && Object.keys(resources.limits).length > 0) ||
+ (resources.requests && Object.keys(resources.requests).length > 0)) {
+ result += '\n';
+
+ // Limits
+ if (resources.limits && Object.keys(resources.limits).length > 0) {
+ result += ' Limits:\n';
+ for (const [key, value] of Object.entries(resources.limits)) {
+ result += ` ${key}: ${value}\n`;
+ }
+ }
+
+ // Requests
+ if (resources.requests && Object.keys(resources.requests).length > 0) {
+ result += ' Requests:\n';
+ for (const [key, value] of Object.entries(resources.requests)) {
+ result += ` ${key}: ${value}\n`;
+ }
+ }
+ } else {
+ result += '<none>\n';
+ }
+ }
+ } else {
+ result += ' <none>\n';
+ }
+ }
+
+ // Deployment conditions
+ result += 'Conditions:\n';
+ const conditions = status.conditions || [];
+ if (conditions.length > 0) {
+ for (const condition of conditions) {
+ let condStr = ` ${condition.type}: ${condition.status}`;
+ if (condition.reason) {
+ condStr += ` (${condition.reason})`;
+ }
+ if (condition.message) {
+ condStr += ` - ${condition.message}`;
+ }
+ result += `${condStr}\n`;
+ }
+ } else {
+ result += ' <none>\n';
+ }
+ }
+
+ return result;
+}
+
+/**
+ * Determines if a resource is a Pod
+ * @param resource The Kubernetes resource to check
+ * @returns True if the resource is a Pod
+ */
+export function isPod(resource: any): boolean {
+ if (!resource) return false;
+
+ // Check if it's explicitly a Pod
+ if (resource.kind === 'Pod') return true;
+
+ // Check if it has containers in spec (Pod-like)
+ return !!(resource.spec && Array.isArray(resource.spec.containers));
+}
+
+/**
+ * Determines if a resource is a Deployment
+ * @param resource The Kubernetes resource to check
+ * @returns True if the resource is a Deployment
+ */
+export function isDeployment(resource: any): boolean {
+ if (!resource) return false;
+
+ // Check if it's explicitly a Deployment
+ if (resource.kind === 'Deployment') return true;
+
+ // Check if it has replicas in spec (Deployment-like)
+ return !!(resource.spec && typeof resource.spec.replicas !== 'undefined');
+}
+
+/**
+ * Extracts container names from a Kubernetes resource
+ * @param resource The Kubernetes resource object
+ * @returns Array of container names
+ */
+export function extractContainers(resource: any): string[] {
+ if (!resource) {
+ return [];
+ }
+
+ try {
+ // For Pod resources
+ if (isPod(resource)) {
+ const containers: string[] = [];
+
+ // Get containers
+ if (resource.spec?.containers && Array.isArray(resource.spec.containers)) {
+ containers.push(...resource.spec.containers.map((c: any) => c.name));
+ }
+
+ // Get init containers if they exist
+ if (resource.spec?.initContainers && Array.isArray(resource.spec.initContainers)) {
+ containers.push(...resource.spec.initContainers.map((c: any) => c.name));
+ }
+
+ // Get ephemeral containers if they exist
+ if (resource.spec?.ephemeralContainers && Array.isArray(resource.spec.ephemeralContainers)) {
+ containers.push(...resource.spec.ephemeralContainers.map((c: any) => c.name));
+ }
+
+ return containers;
+ }
+
+ // For Deployment resources - extract containers from template
+ if (isDeployment(resource)) {
+ const containers: string[] = [];
+
+ // Get containers from pod template
+ if (resource.spec?.template?.spec?.containers &&
+ Array.isArray(resource.spec.template.spec.containers)) {
+ containers.push(...resource.spec.template.spec.containers.map((c: any) => c.name));
+ }
+
+ // Get init containers from pod template if they exist
+ if (resource.spec?.template?.spec?.initContainers &&
+ Array.isArray(resource.spec.template.spec.initContainers)) {
+ containers.push(...resource.spec.template.spec.initContainers.map((c: any) => c.name));
+ }
+
+ return containers;
+ }
+
+ // For other resource types that might have containers
+ if (resource.spec?.containers && Array.isArray(resource.spec.containers)) {
+ return resource.spec.containers.map((c: any) => c.name);
+ }
+
+ // For StatefulSet, DaemonSet, Job, CronJob - similar structure to Deployment
+ if (resource.spec?.template?.spec?.containers &&
+ Array.isArray(resource.spec.template.spec.containers)) {
+ return resource.spec.template.spec.containers.map((c: any) => c.name);
+ }
+ } catch (error) {
+ console.error('Error extracting containers:', error);
+ }
+
+ return [];
+}
+
+export function podJsonToYaml(podJson: any): string {
+ try {
+ // Create a clean copy of the pod object
+ const cleanPod = cleanPodForEditing(podJson);
+
+ // Convert to YAML
+ const yamlString = jsYaml.dump(cleanPod, {
+ indent: 2,
+ lineWidth: -1, // Don't wrap lines
+ noRefs: true, // Don't output YAML references
+ sortKeys: false // Preserve key order
+ });
+
+ return yamlString;
+ } catch (error) {
+ console.error('Error converting Pod JSON to YAML:', error);
+ return '# Error converting Pod to YAML format';
+ }
+}
+
+/**
+ * Cleans a Pod object for editing by removing runtime fields
+ * that shouldn't be edited by users
+ *
+ * @param pod - The Pod object to clean
+ * @returns A cleaned Pod object suitable for editing
+ */
+function cleanPodForEditing(pod: any): any {
+ // Create a deep copy to avoid modifying the original
+ const cleanPod = JSON.parse(JSON.stringify(pod));
+
+ // Ensure apiVersion and kind are set
+ cleanPod.apiVersion = 'v1';
+ cleanPod.kind = 'Pod';
+
+ // Remove status field completely
+ delete cleanPod.status;
+
+ // Remove runtime fields from metadata
+ if (cleanPod.metadata) {
+ delete cleanPod.metadata.resourceVersion;
+ delete cleanPod.metadata.uid;
+ delete cleanPod.metadata.generation;
+ delete cleanPod.metadata.creationTimestamp;
+ delete cleanPod.metadata.deletionTimestamp;
+ delete cleanPod.metadata.deletionGracePeriodSeconds;
+ delete cleanPod.metadata.managedFields;
+ delete cleanPod.metadata.selfLink;
+ delete cleanPod.metadata.ownerReferences;
+
+ // Remove cluster-specific annotations
+ if (cleanPod.metadata.annotations) {
+ Object.keys(cleanPod.metadata.annotations).forEach(key => {
+ if (key.startsWith('kubernetes.io/') ||
+ key.startsWith('kubectl.kubernetes.io/')) {
+ delete cleanPod.metadata.annotations[key];
+ }
+ });
+
+ // If annotations is now empty, remove it
+ if (Object.keys(cleanPod.metadata.annotations).length === 0) {
+ delete cleanPod.metadata.annotations;
+ }
+ }
+ }
+
+ return cleanPod;
+}
+
+import * as jsYaml from 'js-yaml';
+
+/**
+ * Converts a Kubernetes Namespace JSON object to YAML format
+ *
+ * @param namespaceJson - The Namespace object in JSON format
+ * @returns A YAML string representation of the Namespace
+ */
+export function namespaceJsonToYaml(namespaceJson: any): string {
+ try {
+ // Create a clean copy of the namespace object
+ const cleanNamespace = cleanNamespaceForEditing(namespaceJson);
+
+ // Convert to YAML
+ const yamlString = jsYaml.dump(cleanNamespace, {
+ indent: 2,
+ lineWidth: -1, // Don't wrap lines
+ noRefs: true, // Don't output YAML references
+ sortKeys: false // Preserve key order
+ });
+
+ return yamlString;
+ } catch (error) {
+ console.error('Error converting Namespace JSON to YAML:', error);
+ return '# Error converting Namespace to YAML format';
+ }
+}
+
+/**
+ * Cleans a Namespace object for editing by removing runtime fields
+ * that shouldn't be edited by users
+ *
+ * @param namespace - The Namespace object to clean
+ * @returns A cleaned Namespace object suitable for editing
+ */
+function cleanNamespaceForEditing(namespace: any): any {
+ // Create a deep copy to avoid modifying the original
+ const cleanNamespace = JSON.parse(JSON.stringify(namespace));
+
+ // Ensure apiVersion and kind are set
+ cleanNamespace.apiVersion = 'v1';
+ cleanNamespace.kind = 'Namespace';
+
+ // Remove status field completely
+ delete cleanNamespace.status;
+
+ // Remove runtime fields from metadata
+ if (cleanNamespace.metadata) {
+ delete cleanNamespace.metadata.resourceVersion;
+ delete cleanNamespace.metadata.uid;
+ delete cleanNamespace.metadata.generation;
+ delete cleanNamespace.metadata.creationTimestamp;
+ delete cleanNamespace.metadata.deletionTimestamp;
+ delete cleanNamespace.metadata.deletionGracePeriodSeconds;
+ delete cleanNamespace.metadata.managedFields;
+ delete cleanNamespace.metadata.selfLink;
+ delete cleanNamespace.metadata.ownerReferences;
+
+ // Remove cluster-specific annotations
+ if (cleanNamespace.metadata.annotations) {
+ Object.keys(cleanNamespace.metadata.annotations).forEach(key => {
+ if (key.startsWith('kubernetes.io/') ||
+ key.startsWith('kubectl.kubernetes.io/')) {
+ delete cleanNamespace.metadata.annotations[key];
+ }
+ });
+
+ // If annotations is now empty, remove it
+ if (Object.keys(cleanNamespace.metadata.annotations).length === 0) {
+ delete cleanNamespace.metadata.annotations;
+ }
+ }
+ }
+
+ // Remove finalizers if present (can cause issues when editing)
+ if (cleanNamespace.spec && cleanNamespace.spec.finalizers) {
+ delete cleanNamespace.spec.finalizers;
+ }
+
+ return cleanNamespace;
+}
+
+
+/**
+ * Converts a Kubernetes Secret JSON object to YAML format
+ *
+ * @param secretJson - The Secret object in JSON format
+ * @returns A YAML string representation of the Secret
+ */
+export function secretJsonToYaml(secretJson: any): string {
+ try {
+ // Create a clean copy of the secret object
+ const cleanSecret = cleanSecretForEditing(secretJson);
+
+ // Convert to YAML
+ const yamlString = jsYaml.dump(cleanSecret, {
+ indent: 2,
+ lineWidth: -1, // Don't wrap lines
+ noRefs: true, // Don't output YAML references
+ sortKeys: false // Preserve key order
+ });
+
+ return yamlString;
+ } catch (error) {
+ console.error('Error converting Secret JSON to YAML:', error);
+ return '# Error converting Secret to YAML format';
+ }
+}
+
+/**
+ * Cleans a Secret object for editing by removing runtime fields
+ * that shouldn't be edited by users
+ *
+ * @param secret - The Secret object to clean
+ * @returns A cleaned Secret object suitable for editing
+ */
+function cleanSecretForEditing(secret: any): any {
+ // Create a deep copy to avoid modifying the original
+ const cleanSecret = JSON.parse(JSON.stringify(secret));
+
+ // Ensure apiVersion and kind are set
+ cleanSecret.apiVersion = 'v1';
+ cleanSecret.kind = 'Secret';
+
+ // Remove status field completely
+ delete cleanSecret.status;
+
+ // Remove runtime fields from metadata
+ if (cleanSecret.metadata) {
+ delete cleanSecret.metadata.resourceVersion;
+ delete cleanSecret.metadata.uid;
+ delete cleanSecret.metadata.generation;
+ delete cleanSecret.metadata.creationTimestamp;
+ delete cleanSecret.metadata.deletionTimestamp;
+ delete cleanSecret.metadata.deletionGracePeriodSeconds;
+ delete cleanSecret.metadata.managedFields;
+ delete cleanSecret.metadata.selfLink;
+ delete cleanSecret.metadata.ownerReferences;
+
+ // Remove cluster-specific annotations
+ if (cleanSecret.metadata.annotations) {
+ Object.keys(cleanSecret.metadata.annotations).forEach(key => {
+ if (key.startsWith('kubernetes.io/') ||
+ key.startsWith('kubectl.kubernetes.io/')) {
+ delete cleanSecret.metadata.annotations[key];
+ }
+ });
+
+ // If annotations is now empty, remove it
+ if (Object.keys(cleanSecret.metadata.annotations).length === 0) {
+ delete cleanSecret.metadata.annotations;
+ }
+ }
+ }
+
+ // Set default type if not present
+ if (!cleanSecret.type) {
+ cleanSecret.type = 'Opaque';
+ }
+
+ // Convert data to stringData for easier editing
+ // This allows users to edit the values as plain text instead of base64
+ if (cleanSecret.data && Object.keys(cleanSecret.data).length > 0) {
+ cleanSecret.stringData = {};
+
+ // Decode base64 data to stringData
+ Object.keys(cleanSecret.data).forEach(key => {
+ try {
+ const decodedValue = atob(cleanSecret.data[key]);
+ cleanSecret.stringData[key] = decodedValue;
+ } catch (error) {
+ // If decoding fails, keep the original base64 value in data
+ console.warn(`Failed to decode base64 value for key "${key}":`, error);
+ }
+ });
+
+ // Remove the original data field since we're using stringData
+ delete cleanSecret.data;
+ }
+
+ // If there's existing stringData, preserve it
+ if (cleanSecret.stringData && Object.keys(cleanSecret.stringData).length === 0) {
+ delete cleanSecret.stringData;
+ }
+
+ // Ensure we have either data or stringData
+ if (!cleanSecret.data && !cleanSecret.stringData) {
+ cleanSecret.stringData = {};
+ }
+
+ return cleanSecret;
+}
+
+// lib/logs.ts
+import { KubernetesCluster } from '../types/kubernetes';
+import { isPod, isDeployment } from './resources';
+
+interface LogsOptions {
+ selectedResource: any;
+ selectedCluster: KubernetesCluster;
+ selectedContainer: string;
+ tailLines: number;
+ stripColors?: boolean;
+}
+
+interface LogsConnection {
+ ws: WebSocket | null;
+ connecting: boolean;
+ closeTimeout: number | null;
+ error: string;
+ logs: string;
+ onMessage?: (logs: string) => void;
+ onError?: (error: string) => void;
+ onOpen?: () => void;
+ onClose?: (code: number, reason: string) => void;
+}
+
+export class LogsService {
+ private connection: LogsConnection = {
+ ws: null,
+ connecting: false,
+ closeTimeout: null,
+ error: '',
+ logs: ''
+ };
+
+ /**
+ * Connect to logs WebSocket
+ */
+ connectLogsWebSocket(options: LogsOptions, callbacks?: {
+ onMessage?: (logs: string) => void;
+ onError?: (error: string) => void;
+ onOpen?: () => void;
+ onClose?: (code: number, reason: string) => void;
+ }): void {
+ const { selectedResource, selectedCluster, selectedContainer, tailLines, stripColors = true } = options;
+
+ // Store callbacks
+ if (callbacks) {
+ this.connection.onMessage = callbacks.onMessage;
+ this.connection.onError = callbacks.onError;
+ this.connection.onOpen = callbacks.onOpen;
+ this.connection.onClose = callbacks.onClose;
+ }
+
+ // If we're already connecting, don't try to connect again
+ if (this.connection.connecting) {
+ console.log('Already connecting to logs WebSocket, ignoring duplicate request');
+ return;
+ }
+
+ if (!selectedResource || !selectedCluster) {
+ this.connection.logs = 'No resource selected';
+ return;
+ }
+
+ this.connection.connecting = true;
+ this.connection.logs = 'Connecting to logs...';
+ this.connection.error = '';
+
+ try {
+ // Determine the WebSocket URL based on resource type
+ let wsUrl = '';
+
+ if (isPod(selectedResource)) {
+ wsUrl = `ws://127.0.0.1:8081/api/pods/logs?` + new URLSearchParams({
+ contextName: selectedCluster.contextName,
+ namespace: selectedResource.metadata.namespace,
+ name: selectedResource.metadata.name,
+ container: selectedContainer || '',
+ tailLines: tailLines.toString(),
+ stripColors: stripColors ? 'true' : 'false'
+ }).toString();
+ } else if (isDeployment(selectedResource)) {
+ wsUrl = `ws://127.0.0.1:8081/api/deployments/logs?` + new URLSearchParams({
+ contextName: selectedCluster.contextName,
+ namespace: selectedResource.metadata.namespace,
+ name: selectedResource.metadata.name,
+ tailLines: tailLines.toString(),
+ stripColors: stripColors ? 'true' : 'false'
+ }).toString();
+ } else {
+ this.connection.logs = 'Logs not available for this resource type';
+ this.connection.connecting = false;
+ return;
+ }
+
+ console.log(`Connecting to logs WebSocket: ${wsUrl}`);
+
+ // Create WebSocket connection
+ this.connection.ws = new WebSocket(wsUrl);
+
+ // Set up event handlers
+ this.connection.ws.onopen = () => {
+ console.log('Logs WebSocket connection established');
+ this.connection.logs = '';
+ this.connection.connecting = false;
+ this.connection.error = '';
+
+ if (this.connection.onOpen) {
+ this.connection.onOpen();
+ }
+ };
+
+ this.connection.ws.onmessage = (event) => {
+ // Append new log lines to the existing logs
+ this.connection.logs += event.data;
+
+ if (this.connection.onMessage) {
+ this.connection.onMessage(event.data);
+ }
+ };
+
+ this.connection.ws.onerror = (error) => {
+ console.error('WebSocket error:', error);
+ this.connection.error = 'Error connecting to logs';
+ this.connection.connecting = false;
+
+ if (this.connection.onError) {
+ this.connection.onError(this.connection.error);
+ }
+ };
+
+ this.connection.ws.onclose = (event) => {
+ console.log(`Logs WebSocket connection closed: ${event.code} ${event.reason}`);
+ this.connection.connecting = false;
+
+ // Only set error if it wasn't a normal closure and we don't already have an error
+ if (event.code !== 1000 && event.code !== 1001 && !this.connection.error) {
+ // Don't show error for code 1006 (abnormal closure) as it's common when navigating away
+ if (event.code !== 1006) {
+ this.connection.error = `Connection closed: ${event.reason || 'Server disconnected'}`;
+
+ if (this.connection.onError) {
+ this.connection.onError(this.connection.error);
+ }
+ }
+ }
+
+ // Clear the WebSocket reference
+ this.connection.ws = null;
+
+ // Clear any pending close timeout
+ if (this.connection.closeTimeout !== null) {
+ clearTimeout(this.connection.closeTimeout);
+ this.connection.closeTimeout = null;
+ }
+
+ if (this.connection.onClose) {
+ this.connection.onClose(event.code, event.reason);
+ }
+ };
+ } catch (error) {
+ console.error('Error setting up WebSocket:', error);
+ this.connection.error = `Error setting up WebSocket: ${error}`;
+ this.connection.logs = 'Failed to connect to logs';
+ this.connection.connecting = false;
+
+ if (this.connection.onError) {
+ this.connection.onError(this.connection.error);
+ }
+ }
+ }
+
+ /**
+ * Close logs WebSocket connection
+ */
+ closeLogsWebSocket(): Promise<void> {
+ return new Promise<void>((resolve) => {
+ // Clear any existing timeout
+ if (this.connection.closeTimeout !== null) {
+ clearTimeout(this.connection.closeTimeout);
+ this.connection.closeTimeout = null;
+ }
+
+ if (this.connection.ws) {
+ console.log('Closing logs WebSocket connection');
+
+ // Set a flag to track if onclose was called
+ let onCloseCalled = false;
+
+ // Create a temporary onclose handler to know when the connection is fully closed
+ const originalOnClose = this.connection.ws.onclose;
+ this.connection.ws.onclose = (event) => {
+ // Mark that onclose was called
+ onCloseCalled = true;
+
+ // Call the original handler if it exists
+ if (originalOnClose) {
+ originalOnClose.call(this.connection.ws, event);
+ }
+
+ resolve();
+ };
+
+ // Try to close the connection gracefully
+ try {
+ this.connection.ws.close(1000, 'User navigated away');
+ } catch (error) {
+ console.error('Error closing WebSocket:', error);
+ }
+
+ // Set a timeout in case the onclose event doesn't fire
+ this.connection.closeTimeout = window.setTimeout(() => {
+ if (!onCloseCalled) {
+ console.log('WebSocket close timed out, forcing cleanup');
+
+ // If we have an original onclose handler, call it with a simulated event
+ if (originalOnClose && this.connection.ws) {
+ try {
+ originalOnClose.call(this.connection.ws, {
+ type: 'close',
+ code: 1006,
+ reason: 'Timeout while closing',
+ wasClean: false
+ } as CloseEvent);
+ } catch (error) {
+ console.error('Error calling original onclose handler:', error);
+ }
+ }
+
+ // Clear the WebSocket reference
+ this.connection.ws = null;
+ this.connection.connecting = false;
+ }
+
+ this.connection.closeTimeout = null;
+ resolve();
+ }, 300); // Shorter timeout to reduce waiting time
+ } else {
+ // No WebSocket to close
+ this.connection.connecting = false;
+ resolve();
+ }
+ });
+ }
+
+ /**
+ * Reconnect logs WebSocket
+ */
+ async reconnectLogsWebSocket(options: LogsOptions, callbacks?: {
+ onMessage?: (logs: string) => void;
+ onError?: (error: string) => void;
+ onOpen?: () => void;
+ onClose?: (code: number, reason: string) => void;
+ }): Promise<void> {
+ try {
+ // Ensure we close any existing connection first
+ await this.closeLogsWebSocket();
+
+ // Wait a short time to ensure the previous connection is fully closed
+ await new Promise(resolve => setTimeout(resolve, 100));
+
+ // Now connect the new WebSocket
+ this.connectLogsWebSocket(options, callbacks);
+ } catch (error) {
+ console.error('Error reconnecting WebSocket:', error);
+ this.connection.error = 'Error reconnecting to logs';
+
+ if (callbacks?.onError) {
+ callbacks.onError(this.connection.error);
+ }
+ }
+ }
+
+ /**
+ * Get current logs
+ */
+ getLogs(): string {
+ return this.connection.logs;
+ }
+
+ /**
+ * Clear logs
+ */
+ clearLogs(): void {
+ this.connection.logs = '';
+ }
+
+ /**
+ * Get current error
+ */
+ getError(): string {
+ return this.connection.error;
+ }
+
+
+ /**
+ * Extract container names from resource
+ */
+ extractContainers(resource: any): string[] {
+ if (!resource || !resource.spec || !resource.spec.containers) {
+ return [];
+ }
+
+ return resource.spec.containers.map((c: any) => c.name);
+ }
+}
+
+// Create a singleton instance
+export const logsService = new LogsService();
+export type KubernetesResourceKind =
+ 'Pod' |
+ 'Deployment' |
+ 'StatefulSet' |
+ 'ConfigMap' |
+ 'Ingress' |
+ 'Namespace' |
+ 'Secret' |
+ 'PersistentVolumeClaim' |
+ 'PersistentVolume' |
+ 'Unknown';
+
+export function getResourceKind(resource: any): KubernetesResourceKind {
+ if (resource.kind) {
+ switch (resource.kind) {
+ case 'Pod':
+ return 'Pod';
+ case 'Deployment':
+ return 'Deployment';
+ case 'StatefulSet':
+ return 'StatefulSet';
+ case 'ConfigMap':
+ return 'ConfigMap';
+ case 'Ingress':
+ return 'Ingress';
+ case 'Namespace':
+ return 'Namespace';
+ case 'Secret':
+ return 'Secret';
+ case 'PersistentVolumeClaim':
+ return 'PersistentVolumeClaim';
+ case 'PersistentVolume':
+ return 'PersistentVolume';
+ default:
+ return 'Unknown'
+ }
+ }
+ return 'Unknown';
+}
+
+/**
+* Check if resource is a pod
+*/
+export function isPod(resource: any): boolean {
+ return resource.kind === 'Pod' ||
+ (resource.spec && Array.isArray(resource.spec.containers));
+}
+
+/**
+ * Check if resource is a deployment
+ */
+export function isDeployment(resource: any): boolean {
+ return resource.kind === 'Deployment' ||
+ (resource.spec && typeof resource.spec.replicas !== 'undefined');
+}
+
+export function isStatefulSet(resource: any): boolean {
+ return resource.kind === 'StatefulSet';
+}
+
+export function isConfigMap(resource: any): boolean {
+ return resource.kind === 'ConfigMap';
+}
+
+import { Terminal } from '@xterm/xterm';
+import { FitAddon } from '@xterm/addon-fit';
+import '@xterm/xterm/css/xterm.css';
+
+export interface TerminalOptions {
+ contextName: string;
+ namespace: string;
+ podName: string;
+ containerName: string;
+}
+
+export class PodTerminal {
+ private terminal: Terminal | null = null;
+ private fitAddon: FitAddon | null = null;
+ private ws: WebSocket | null = null;
+ private container: HTMLElement | null = null;
+ private options: TerminalOptions;
+ private isReady: boolean = false;
+ private resizeHandler: (() => void) | null = null;
+ private reconnectAttempts: number = 0;
+ private maxReconnectAttempts: number = 3;
+ private connectTimeout: NodeJS.Timeout | null = null;
+ private pingInterval: NodeJS.Timeout | null = null;
+
+ constructor(options: TerminalOptions) {
+ this.options = options;
+ }
+
+ /**
+ * Initializes the terminal and connects to the pod
+ * @param containerId The ID of the HTML element to mount the terminal in
+ * @returns Promise that resolves when terminal is initialized
+ */
+ public async initialize(containerId: string): Promise<void> {
+ try {
+ // Get container element
+ this.container = document.getElementById(containerId);
+ if (!this.container) {
+ throw new Error(`Terminal container element with ID "${containerId}" not found`);
+ }
+
+ // Create terminal instance
+ this.terminal = new Terminal({
+ cursorBlink: true,
+ theme: {
+ background: '#1e1e1e',
+ foreground: '#e0e0e0',
+ cursor: '#ffffff',
+ selection: 'rgba(255, 255, 255, 0.3)',
+ black: '#000000',
+ red: '#e06c75',
+ green: '#98c379',
+ yellow: '#e5c07b',
+ blue: '#61afef',
+ magenta: '#c678dd',
+ cyan: '#56b6c2',
+ white: '#d0d0d0',
+ brightBlack: '#808080',
+ brightRed: '#f44747',
+ brightGreen: '#b5cea8',
+ brightYellow: '#dcdcaa',
+ brightBlue: '#569cd6',
+ brightMagenta: '#c586c0',
+ brightCyan: '#9cdcfe',
+ brightWhite: '#ffffff'
+ },
+ fontSize: 14,
+ fontFamily: 'Consolas, "Courier New", monospace',
+ scrollback: 1000,
+ convertEol: true
+ });
+
+ // Create fit addon
+ this.fitAddon = new FitAddon();
+ this.terminal.loadAddon(this.fitAddon);
+
+ // Open terminal in container
+ this.terminal.open(this.container);
+
+ // Show connecting message
+ this.terminal.writeln('Connecting to pod terminal...');
+ this.terminal.writeln('');
+
+ // Set up terminal input handler before connecting
+ this.terminal.onData((data) => {
+ // Send terminal input to the WebSocket
+ if (this.ws && this.ws.readyState === WebSocket.OPEN) {
+ this.ws.send(data);
+ }
+ });
+
+ // Connect to WebSocket
+ await this.connect();
+
+ // Fit terminal to container
+ this.fit();
+
+ // Focus terminal
+ this.terminal.focus();
+
+ // Set up resize handler
+ this.resizeHandler = this.fit.bind(this);
+ window.addEventListener('resize', this.resizeHandler);
+
+ // Mark as ready
+ this.isReady = true;
+ } catch (error) {
+ console.error('Error initializing terminal:', error);
+ if (this.terminal) {
+ this.terminal.writeln(`\r\nError initializing terminal: ${error}`);
+ this.terminal.writeln('Please check your connection and try again.');
+ }
+ throw error;
+ }
+ }
+
+ /**
+ * Connects to the pod terminal WebSocket
+ */
+ private async connect(): Promise<void> {
+ if (!this.terminal) {
+ throw new Error('Terminal not initialized');
+ }
+
+ return new Promise<void>((resolve, reject) => {
+ try {
+ // Close any existing connection
+ this.closeConnection();
+
+ // Determine the correct WebSocket URL based on the environment
+ let wsUrl: string;
+
+ // Check if we're running in a Wails app
+ if (typeof window !== 'undefined' && 'runtime' in window) {
+ // This is a Wails app, use the backend URL directly
+ wsUrl = `ws://127.0.0.1:8081/api/pods/exec?` + new URLSearchParams({
+ contextName: this.options.contextName,
+ namespace: this.options.namespace,
+ pod: this.options.podName,
+ container: this.options.containerName || ''
+ }).toString();
+ } else if (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') {
+ // Local development
+ wsUrl = `ws://${window.location.host}/api/pods/exec?` + new URLSearchParams({
+ contextName: this.options.contextName,
+ namespace: this.options.namespace,
+ pod: this.options.podName,
+ container: this.options.containerName || ''
+ }).toString();
+ } else {
+ // Production or other environment
+ const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
+ wsUrl = `${protocol}//${window.location.host}/api/pods/exec?` + new URLSearchParams({
+ contextName: this.options.contextName,
+ namespace: this.options.namespace,
+ pod: this.options.podName,
+ container: this.options.containerName || ''
+ }).toString();
+ }
+
+ console.log(`Connecting to terminal WebSocket: ${wsUrl}`);
+ if (this.terminal) {
+ this.terminal.writeln(`Connecting to: ${this.options.podName}/${this.options.containerName || 'default'}`);
+ }
+
+ // Set a timeout for the connection
+ this.connectTimeout = setTimeout(() => {
+ if (this.ws && this.ws.readyState !== WebSocket.OPEN) {
+ console.error('WebSocket connection timeout');
+ if (this.terminal) {
+ this.terminal.writeln('\r\nConnection timeout. Server might be unavailable.');
+ }
+
+ // Force close the connection
+ if (this.ws) {
+ this.ws.close();
+ }
+
+ reject(new Error('WebSocket connection timeout'));
+ }
+ }, 15000); // 15 second timeout
+
+ // Create WebSocket connection
+ this.ws = new WebSocket(wsUrl);
+
+ // Set up event handlers
+ this.ws.onopen = () => {
+ console.log('Terminal WebSocket connection established');
+
+ // Clear the connection timeout
+ if (this.connectTimeout) {
+ clearTimeout(this.connectTimeout);
+ this.connectTimeout = null;
+ }
+
+ this.reconnectAttempts = 0;
+
+ if (this.terminal) {
+ // Clear the terminal
+ this.terminal.clear();
+
+ // Write welcome message
+ this.terminal.writeln('Connected to pod terminal.');
+ this.terminal.writeln('');
+
+ // Enable terminal input
+ this.terminal.options.disableStdin = false;
+
+ // Send initial terminal size
+ this.fit();
+
+ // Set up ping interval to keep connection alive
+ this.pingInterval = setInterval(() => {
+ if (this.ws && this.ws.readyState === WebSocket.OPEN) {
+ // Send a special ping message (type 2)
+ const pingMessage = new Uint8Array([2]);
+ this.ws.send(pingMessage);
+ }
+ }, 30000); // 30 seconds
+ }
+
+ resolve();
+ };
+
+ this.ws.onmessage = (event) => {
+ // Handle different message types
+ if (event.data instanceof Blob) {
+ // Handle binary data
+ const reader = new FileReader();
+ reader.onload = () => {
+ if (this.terminal && reader.result) {
+ const data = new Uint8Array(reader.result as ArrayBuffer);
+ this.terminal.write(data);
+ }
+ };
+ reader.readAsArrayBuffer(event.data);
+ } else {
+ // Handle text data
+ if (this.terminal) {
+ this.terminal.write(event.data);
+ }
+ }
+ };
+
+ this.ws.onerror = (error) => {
+ console.error('Terminal WebSocket error:', error);
+
+ // Log detailed error information
+ console.log('WebSocket readyState:', this.ws ? this.ws.readyState : 'null');
+ console.log('WebSocket URL:', wsUrl);
+ console.log('Error event:', error);
+
+ if (this.terminal) {
+ this.terminal.writeln('\r\nConnection error. Please check your network and authentication.');
+ this.terminal.writeln(`Error details: WebSocket connection failed`);
+ }
+
+ // Don't reject immediately, let onclose handle it
+ };
+
+ this.ws.onclose = (event) => {
+ console.log(`Terminal WebSocket connection closed: ${event.code} ${event.reason}`);
+
+ // Clear timeouts and intervals
+ if (this.connectTimeout) {
+ clearTimeout(this.connectTimeout);
+ this.connectTimeout = null;
+ }
+
+ if (this.pingInterval) {
+ clearInterval(this.pingInterval);
+ this.pingInterval = null;
+ }
+
+ if (this.terminal) {
+ // Disable terminal input
+ this.terminal.options.disableStdin = true;
+
+ // Show connection closed message
+ this.terminal.writeln('\r\n');
+ this.terminal.writeln('Connection closed.');
+
+ if (event.code !== 1000 && event.code !== 1001) {
+ this.terminal.writeln(`Reason: ${event.reason || 'Server disconnected'} (Code: ${event.code})`);
+ this.terminal.writeln('');
+
+ // Try to auto-reconnect a few times
+ if (this.reconnectAttempts < this.maxReconnectAttempts) {
+ this.reconnectAttempts++;
+ this.terminal.writeln(`Attempting to reconnect (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`);
+
+ setTimeout(() => {
+ this.connect().catch(err => {
+ console.error('Reconnect failed:', err);
+ if (this.terminal) {
+ this.terminal.writeln('Reconnect failed. Press the "Refresh" button to try again.');
+ }
+ reject(err);
+ });
+ }, 2000);
+ } else {
+ this.terminal.writeln('Press the "Refresh" button to reconnect.');
+ reject(new Error(`WebSocket closed: ${event.code} ${event.reason}`));
+ }
+ } else {
+ resolve();
+ }
+ } else {
+ reject(new Error(`WebSocket closed: ${event.code} ${event.reason}`));
+ }
+ };
+ } catch (error) {
+ console.error('Error setting up terminal WebSocket:', error);
+ if (this.terminal) {
+ this.terminal.writeln(`\r\nError setting up connection: ${error}`);
+ }
+ reject(error);
+ }
+ });
+ }
+
+ /**
+ * Fits the terminal to its container
+ */
+ private fit(): void {
+ if (this.fitAddon && this.terminal) {
+ try {
+ this.fitAddon.fit();
+
+ // Send terminal size to server
+ if (this.ws && this.ws.readyState === WebSocket.OPEN) {
+ const cols = this.terminal.cols;
+ const rows = this.terminal.rows;
+
+ // Send resize message as binary data with a specific format:
+ // byte 1 = message type (1 for resize)
+ // byte 2 = rows (uint8)
+ // byte 3 = cols (uint8)
+ const resizeMessage = new Uint8Array([1, rows & 0xFF, cols & 0xFF]);
+ this.ws.send(resizeMessage);
+ }
+ } catch (error) {
+ console.error('Error resizing terminal:', error);
+ }
+ }
+ }
+
+ /**
+ * Closes the WebSocket connection
+ */
+ private closeConnection(): void {
+ // Clear any existing timeouts and intervals
+ if (this.connectTimeout) {
+ clearTimeout(this.connectTimeout);
+ this.connectTimeout = null;
+ }
+
+ if (this.pingInterval) {
+ clearInterval(this.pingInterval);
+ this.pingInterval = null;
+ }
+
+ if (this.ws) {
+ try {
+ console.log(`Closing WebSocket connection, current state: ${this.ws.readyState}`);
+
+ // Only close if not already closing/closed
+ if (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING) {
+ // For CONNECTING state, we need to set up onclose handler first
+ if (this.ws.readyState === WebSocket.CONNECTING) {
+ const oldOnClose = this.ws.onclose;
+ this.ws.onclose = (event) => {
+ console.log('Connection closed while in CONNECTING state');
+ if (oldOnClose) oldOnClose.call(this.ws, event);
+ };
+ }
+
+ this.ws.close(1000, 'User disconnected');
+ }
+ } catch (error) {
+ console.error('Error closing terminal WebSocket:', error);
+ }
+ this.ws = null;
+ }
+ }
+
+ /**
+ * Updates terminal options and reconnects
+ * @param options New terminal options
+ */
+ public async updateOptions(options: Partial<TerminalOptions>): Promise<void> {
+ // Update options
+ this.options = { ...this.options, ...options };
+
+ // Reconnect with new options
+ if (this.isReady) {
+ this.reconnectAttempts = 0;
+ if (this.terminal) {
+ this.terminal.writeln('\r\nUpdating connection...');
+ }
+ await this.connect();
+ }
+ }
+
+ /**
+ * Refreshes the terminal connection
+ */
+ public async refresh(): Promise<void> {
+ if (this.terminal) {
+ this.reconnectAttempts = 0;
+ this.terminal.writeln('\r\nRefreshing connection...');
+ await this.connect();
+ this.fit();
+ this.terminal.focus();
+ }
+ }
+
+ /**
+ * Disposes the terminal and cleans up resources
+ */
+ public dispose(): void {
+ // Remove resize event listener
+ if (this.resizeHandler) {
+ window.removeEventListener('resize', this.resizeHandler);
+ this.resizeHandler = null;
+ }
+
+ // Clear timeouts and intervals
+ if (this.connectTimeout) {
+ clearTimeout(this.connectTimeout);
+ this.connectTimeout = null;
+ }
+
+ if (this.pingInterval) {
+ clearInterval(this.pingInterval);
+ this.pingInterval = null;
+ }
+
+ // Close WebSocket connection
+ this.closeConnection();
+
+ // Dispose terminal
+ if (this.terminal) {
+ try {
+ this.terminal.dispose();
+ } catch (error) {
+ console.error('Error disposing terminal:', error);
+ }
+ this.terminal = null;
+ }
+
+ // Reset state
+ this.fitAddon = null;
+ this.isReady = false;
+ this.container = null;
+ }
+}
+
+import {createApp} from 'vue'
+import App from './App.vue'
+import './style.css';
+
+createApp(App).mount('#app')
+declare module '*.vue' {
+ import type { DefineComponent } from 'vue'
+ const component: DefineComponent<{}, {}, any>
+ export default component
+}
+html {
+ background-color: rgba(27, 38, 54, 1);
+ text-align: center;
+ color: white;
+}
+
+body {
+ margin: 0;
+ color: white;
+ font-family: "Nunito", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto",
+ "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
+ sans-serif;
+}
+
+@font-face {
+ font-family: "Nunito";
+ font-style: normal;
+ font-weight: 400;
+ src: local(""),
+ url("assets/fonts/nunito-v16-latin-regular.woff2") format("woff2");
+}
+
+#app {
+ height: 100vh;
+ text-align: center;
+}
+export class CustomPod {
+ name: string;
+ image: string;
+ namespace: string;
+
+ constructor(name: string, image: string, namespace: string = 'default') {
+ this.name = name;
+ this.image = image;
+ this.namespace = namespace;
+ }
+
+ // Convert to Kubernetes Pod definition
+ toKubernetesPod(): any {
+ return {
+ apiVersion: 'v1',
+ kind: 'Pod',
+ metadata: {
+ name: this.name,
+ namespace: this.namespace
+ },
+ spec: {
+ containers: [
+ {
+ name: 'container-1',
+ image: this.image
+ }
+ ]
+ }
+ };
+ }
+
+ // Create from form data
+ static fromForm(name: string, image: string, namespace: string = 'default'): CustomPod {
+ return new CustomPod(name, image, namespace);
+ }
+}
+
+export interface SecretUpdateOptions {
+ context: string;
+ opts: string;
+ origNamespace: string;
+ origName: string;
+}
+
+export interface SecretCreateOptions {
+ context: string;
+ opts: any;
+}
+import {
+ V1Pod,
+ V1ConfigMap,
+ V1Deployment,
+ V1DeploymentSpec,
+ V1LabelSelector,
+ V1Ingress,
+ V1Namespace,
+ V1Secret,
+ V1PersistentVolumeClaim,
+ V1PersistentVolume,
+} from '@kubernetes/client-node';
+
+export interface ApiResponse<T> {
+ success: boolean;
+ msg: string;
+ data: T;
+}
+
+export interface KubernetesCluster {
+ contextName: string;
+}
+
+export interface KubernetesStatefulSet {
+ metadata: {
+ name: string;
+ namespace: string;
+ uid: string;
+ creationTimestamp: string;
+ };
+ spec: {
+ replicas: number;
+ strategy?: {
+ type: string;
+ };
+ };
+ status: {
+ availableReplicas: number;
+ readyReplicas: number;
+ replicas: number;
+ updatedReplicas: number;
+ };
+}
+
+export interface KubernetesDeployment extends Omit<V1Deployment, 'spec'> {
+ spec?: KubernetesDeploymentSpec;
+}
+
+interface KubernetesDeploymentSpec extends Omit<V1DeploymentSpec, 'selector'> {
+ selector?: V1LabelSelector;
+}
+
+export interface KubernetesPod extends V1Pod {
+}
+
+export interface KubernetesConfigMap extends Omit<V1ConfigMap, 'binaryData'> {
+ binaryData?: { [key: string]: number[] };
+}
+
+export interface KubernetesIngress extends V1Ingress {
+}
+
+export interface KubernetesNamespace extends V1Namespace {
+}
+
+export interface KubernetesSecret extends V1Secret {
+}
+
+export interface KubernetesPersistentVolumeClaim extends V1PersistentVolumeClaim{
+}
+
+export interface KubernetesPersistentVolume extends V1PersistentVolume{
+}
+{
+ "compilerOptions": {
+ "target": "esnext",
+ "module": "esnext",
+ "strict": true,
+ "jsx": "preserve",
+ "moduleResolution": "node",
+ "skipLibCheck": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "forceConsistentCasingInFileNames": true,
+ "useDefineForClassFields": true,
+ "sourceMap": true,
+ "baseUrl": ".",
+ "types": [
+ "webpack-env",
+ "node"
+ ],
+ "paths": {
+ "@/*": [
+ "src/*"
+ ]
+ },
+ "lib": [
+ "esnext",
+ "dom",
+ "dom.iterable",
+ "scripthost"
+ ]
+ },
+ "include": [
+ "src/**/*.ts",
+ "src/**/*.tsx",
+ "src/**/*.vue",
+ "tests/**/*.ts",
+ "tests/**/*.tsx"
+ ],
+ "exclude": [
+ "node_modules"
+ ]
+}
+import {defineConfig} from 'vite'
+import vue from '@vitejs/plugin-vue'
+const rootPath = new URL('.', import.meta.url).pathname
+
+export default defineConfig({
+ plugins: [vue()],
+ resolve: {
+ alias: {
+ '@': rootPath + 'src',
+ wailsjs: rootPath + 'wailsjs',
+ },
+ },
+})
+export namespace api {
+
+ export class ExecEnvVar {
+ name: string;
+ value: string;
+
+ static createFrom(source: any = {}) {
+ return new ExecEnvVar(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.value = source["value"];
+ }
+ }
+ export class ExecConfig {
+ command: string;
+ args: string[];
+ env: ExecEnvVar[];
+ apiVersion?: string;
+ installHint?: string;
+ provideClusterInfo: boolean;
+ interactiveMode?: string;
+
+ static createFrom(source: any = {}) {
+ return new ExecConfig(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.command = source["command"];
+ this.args = source["args"];
+ this.env = this.convertValues(source["env"], ExecEnvVar);
+ this.apiVersion = source["apiVersion"];
+ this.installHint = source["installHint"];
+ this.provideClusterInfo = source["provideClusterInfo"];
+ this.interactiveMode = source["interactiveMode"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class AuthProviderConfig {
+ name: string;
+ config?: Record<string, string>;
+
+ static createFrom(source: any = {}) {
+ return new AuthProviderConfig(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.config = source["config"];
+ }
+ }
+ export class AuthInfo {
+ "client-certificate"?: string;
+ "client-certificate-data"?: number[];
+ "client-key"?: string;
+ "client-key-data"?: number[];
+ token?: string;
+ tokenFile?: string;
+ "act-as"?: string;
+ "act-as-uid"?: string;
+ "act-as-groups"?: string[];
+ "act-as-user-extra"?: Record<string, string[]>;
+ username?: string;
+ password?: string;
+ "auth-provider"?: AuthProviderConfig;
+ exec?: ExecConfig;
+ extensions?: Record<string, any>;
+
+ static createFrom(source: any = {}) {
+ return new AuthInfo(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this["client-certificate"] = source["client-certificate"];
+ this["client-certificate-data"] = source["client-certificate-data"];
+ this["client-key"] = source["client-key"];
+ this["client-key-data"] = source["client-key-data"];
+ this.token = source["token"];
+ this.tokenFile = source["tokenFile"];
+ this["act-as"] = source["act-as"];
+ this["act-as-uid"] = source["act-as-uid"];
+ this["act-as-groups"] = source["act-as-groups"];
+ this["act-as-user-extra"] = source["act-as-user-extra"];
+ this.username = source["username"];
+ this.password = source["password"];
+ this["auth-provider"] = this.convertValues(source["auth-provider"], AuthProviderConfig);
+ this.exec = this.convertValues(source["exec"], ExecConfig);
+ this.extensions = source["extensions"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+
+ export class Cluster {
+ server: string;
+ "tls-server-name"?: string;
+ "insecure-skip-tls-verify"?: boolean;
+ "certificate-authority"?: string;
+ "certificate-authority-data"?: number[];
+ "proxy-url"?: string;
+ "disable-compression"?: boolean;
+ extensions?: Record<string, any>;
+
+ static createFrom(source: any = {}) {
+ return new Cluster(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.server = source["server"];
+ this["tls-server-name"] = source["tls-server-name"];
+ this["insecure-skip-tls-verify"] = source["insecure-skip-tls-verify"];
+ this["certificate-authority"] = source["certificate-authority"];
+ this["certificate-authority-data"] = source["certificate-authority-data"];
+ this["proxy-url"] = source["proxy-url"];
+ this["disable-compression"] = source["disable-compression"];
+ this.extensions = source["extensions"];
+ }
+ }
+ export class Context {
+ cluster: string;
+ user: string;
+ namespace?: string;
+ extensions?: Record<string, any>;
+
+ static createFrom(source: any = {}) {
+ return new Context(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.cluster = source["cluster"];
+ this.user = source["user"];
+ this.namespace = source["namespace"];
+ this.extensions = source["extensions"];
+ }
+ }
+ export class Preferences {
+ colors?: boolean;
+ extensions?: Record<string, any>;
+
+ static createFrom(source: any = {}) {
+ return new Preferences(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.colors = source["colors"];
+ this.extensions = source["extensions"];
+ }
+ }
+ export class Config {
+ kind?: string;
+ apiVersion?: string;
+ preferences: Preferences;
+ clusters: Record<string, Cluster>;
+ users: Record<string, AuthInfo>;
+ contexts: Record<string, Context>;
+ "current-context": string;
+ extensions?: Record<string, any>;
+
+ static createFrom(source: any = {}) {
+ return new Config(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.kind = source["kind"];
+ this.apiVersion = source["apiVersion"];
+ this.preferences = this.convertValues(source["preferences"], Preferences);
+ this.clusters = this.convertValues(source["clusters"], Cluster, true);
+ this.users = this.convertValues(source["users"], AuthInfo, true);
+ this.contexts = this.convertValues(source["contexts"], Context, true);
+ this["current-context"] = source["current-context"];
+ this.extensions = source["extensions"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+
+
+
+
+}
+
+export namespace config {
+
+ export class KubeCluster {
+ KubeContext?: api.Context;
+ KubeCluster?: api.Cluster;
+ KubeClientSet?: kubernetes.Clientset;
+ KubeRestConfig?: rest.Config;
+
+ static createFrom(source: any = {}) {
+ return new KubeCluster(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.KubeContext = this.convertValues(source["KubeContext"], api.Context);
+ this.KubeCluster = this.convertValues(source["KubeCluster"], api.Cluster);
+ this.KubeClientSet = this.convertValues(source["KubeClientSet"], kubernetes.Clientset);
+ this.KubeRestConfig = this.convertValues(source["KubeRestConfig"], rest.Config);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class Config {
+ KubeConfig: string;
+ KubeConfigs: Record<string, api.Config>;
+ DefaultKubeContext: string;
+ KubeClusters: Record<string, KubeCluster>;
+ Debug: boolean;
+
+ static createFrom(source: any = {}) {
+ return new Config(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.KubeConfig = source["KubeConfig"];
+ this.KubeConfigs = this.convertValues(source["KubeConfigs"], api.Config, true);
+ this.DefaultKubeContext = source["DefaultKubeContext"];
+ this.KubeClusters = this.convertValues(source["KubeClusters"], KubeCluster, true);
+ this.Debug = source["Debug"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+
+}
+
+export namespace http {
+
+ export class Response {
+ Status: string;
+ StatusCode: number;
+ Proto: string;
+ ProtoMajor: number;
+ ProtoMinor: number;
+ Header: Record<string, string[]>;
+ Body: any;
+ ContentLength: number;
+ TransferEncoding: string[];
+ Close: boolean;
+ Uncompressed: boolean;
+ Trailer: Record<string, string[]>;
+ Request?: Request;
+ TLS?: tls.ConnectionState;
+
+ static createFrom(source: any = {}) {
+ return new Response(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.Status = source["Status"];
+ this.StatusCode = source["StatusCode"];
+ this.Proto = source["Proto"];
+ this.ProtoMajor = source["ProtoMajor"];
+ this.ProtoMinor = source["ProtoMinor"];
+ this.Header = source["Header"];
+ this.Body = source["Body"];
+ this.ContentLength = source["ContentLength"];
+ this.TransferEncoding = source["TransferEncoding"];
+ this.Close = source["Close"];
+ this.Uncompressed = source["Uncompressed"];
+ this.Trailer = source["Trailer"];
+ this.Request = this.convertValues(source["Request"], Request);
+ this.TLS = this.convertValues(source["TLS"], tls.ConnectionState);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class Request {
+ Method: string;
+ URL?: url.URL;
+ Proto: string;
+ ProtoMajor: number;
+ ProtoMinor: number;
+ Header: Record<string, string[]>;
+ Body: any;
+ ContentLength: number;
+ TransferEncoding: string[];
+ Close: boolean;
+ Host: string;
+ Form: Record<string, string[]>;
+ PostForm: Record<string, string[]>;
+ MultipartForm?: multipart.Form;
+ Trailer: Record<string, string[]>;
+ RemoteAddr: string;
+ RequestURI: string;
+ TLS?: tls.ConnectionState;
+ Response?: Response;
+ Pattern: string;
+
+ static createFrom(source: any = {}) {
+ return new Request(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.Method = source["Method"];
+ this.URL = this.convertValues(source["URL"], url.URL);
+ this.Proto = source["Proto"];
+ this.ProtoMajor = source["ProtoMajor"];
+ this.ProtoMinor = source["ProtoMinor"];
+ this.Header = source["Header"];
+ this.Body = source["Body"];
+ this.ContentLength = source["ContentLength"];
+ this.TransferEncoding = source["TransferEncoding"];
+ this.Close = source["Close"];
+ this.Host = source["Host"];
+ this.Form = source["Form"];
+ this.PostForm = source["PostForm"];
+ this.MultipartForm = this.convertValues(source["MultipartForm"], multipart.Form);
+ this.Trailer = source["Trailer"];
+ this.RemoteAddr = source["RemoteAddr"];
+ this.RequestURI = source["RequestURI"];
+ this.TLS = this.convertValues(source["TLS"], tls.ConnectionState);
+ this.Response = this.convertValues(source["Response"], Response);
+ this.Pattern = source["Pattern"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+
+}
+
+export namespace intstr {
+
+ export class IntOrString {
+ Type: number;
+ IntVal: number;
+ StrVal: string;
+
+ static createFrom(source: any = {}) {
+ return new IntOrString(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.Type = source["Type"];
+ this.IntVal = source["IntVal"];
+ this.StrVal = source["StrVal"];
+ }
+ }
+
+}
+
+export namespace kubernetes {
+
+ export class Clientset {
+ LegacyPrefix: string;
+ UseLegacyDiscovery: boolean;
+
+ static createFrom(source: any = {}) {
+ return new Clientset(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.LegacyPrefix = source["LegacyPrefix"];
+ this.UseLegacyDiscovery = source["UseLegacyDiscovery"];
+ }
+ }
+
+}
+
+export namespace logwrap {
+
+ export class LogWrap {
+
+
+ static createFrom(source: any = {}) {
+ return new LogWrap(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+
+ }
+ }
+
+}
+
+export namespace multipart {
+
+ export class FileHeader {
+ Filename: string;
+ Header: Record<string, string[]>;
+ Size: number;
+
+ static createFrom(source: any = {}) {
+ return new FileHeader(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.Filename = source["Filename"];
+ this.Header = source["Header"];
+ this.Size = source["Size"];
+ }
+ }
+ export class Form {
+ Value: Record<string, string[]>;
+ File: Record<string, FileHeader[]>;
+
+ static createFrom(source: any = {}) {
+ return new Form(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.Value = source["Value"];
+ this.File = this.convertValues(source["File"], FileHeader[], true);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+
+}
+
+export namespace net {
+
+ export class IPNet {
+ IP: number[];
+ Mask: number[];
+
+ static createFrom(source: any = {}) {
+ return new IPNet(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.IP = source["IP"];
+ this.Mask = source["Mask"];
+ }
+ }
+
+}
+
+export namespace pkix {
+
+ export class AttributeTypeAndValue {
+ Type: number[];
+ Value: any;
+
+ static createFrom(source: any = {}) {
+ return new AttributeTypeAndValue(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.Type = source["Type"];
+ this.Value = source["Value"];
+ }
+ }
+ export class Extension {
+ Id: number[];
+ Critical: boolean;
+ Value: number[];
+
+ static createFrom(source: any = {}) {
+ return new Extension(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.Id = source["Id"];
+ this.Critical = source["Critical"];
+ this.Value = source["Value"];
+ }
+ }
+ export class Name {
+ Country: string[];
+ Organization: string[];
+ OrganizationalUnit: string[];
+ Locality: string[];
+ Province: string[];
+ StreetAddress: string[];
+ PostalCode: string[];
+ SerialNumber: string;
+ CommonName: string;
+ Names: AttributeTypeAndValue[];
+ ExtraNames: AttributeTypeAndValue[];
+
+ static createFrom(source: any = {}) {
+ return new Name(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.Country = source["Country"];
+ this.Organization = source["Organization"];
+ this.OrganizationalUnit = source["OrganizationalUnit"];
+ this.Locality = source["Locality"];
+ this.Province = source["Province"];
+ this.StreetAddress = source["StreetAddress"];
+ this.PostalCode = source["PostalCode"];
+ this.SerialNumber = source["SerialNumber"];
+ this.CommonName = source["CommonName"];
+ this.Names = this.convertValues(source["Names"], AttributeTypeAndValue);
+ this.ExtraNames = this.convertValues(source["ExtraNames"], AttributeTypeAndValue);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+
+}
+
+export namespace resource {
+
+ export class Quantity {
+ Format: string;
+
+ static createFrom(source: any = {}) {
+ return new Quantity(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.Format = source["Format"];
+ }
+ }
+
+}
+
+export namespace rest {
+
+ export class ImpersonationConfig {
+ UserName: string;
+ UID: string;
+ Groups: string[];
+ Extra: Record<string, string[]>;
+
+ static createFrom(source: any = {}) {
+ return new ImpersonationConfig(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.UserName = source["UserName"];
+ this.UID = source["UID"];
+ this.Groups = source["Groups"];
+ this.Extra = source["Extra"];
+ }
+ }
+ export class Config {
+ Host: string;
+ APIPath: string;
+ AcceptContentTypes: string;
+ ContentType: string;
+ // Go type: schema
+ GroupVersion?: any;
+ NegotiatedSerializer: any;
+ Username: string;
+ Password: string;
+ BearerToken: string;
+ BearerTokenFile: string;
+ Impersonate: ImpersonationConfig;
+ AuthProvider?: api.AuthProviderConfig;
+ AuthConfigPersister: any;
+ ExecProvider?: api.ExecConfig;
+ Insecure: boolean;
+ ServerName: string;
+ CertFile: string;
+ KeyFile: string;
+ CAFile: string;
+ CertData: number[];
+ KeyData: number[];
+ CAData: number[];
+ NextProtos: string[];
+ UserAgent: string;
+ DisableCompression: boolean;
+ Transport: any;
+ QPS: number;
+ Burst: number;
+ RateLimiter: any;
+ WarningHandler: any;
+ Timeout: number;
+
+ static createFrom(source: any = {}) {
+ return new Config(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.Host = source["Host"];
+ this.APIPath = source["APIPath"];
+ this.AcceptContentTypes = source["AcceptContentTypes"];
+ this.ContentType = source["ContentType"];
+ this.GroupVersion = this.convertValues(source["GroupVersion"], null);
+ this.NegotiatedSerializer = source["NegotiatedSerializer"];
+ this.Username = source["Username"];
+ this.Password = source["Password"];
+ this.BearerToken = source["BearerToken"];
+ this.BearerTokenFile = source["BearerTokenFile"];
+ this.Impersonate = this.convertValues(source["Impersonate"], ImpersonationConfig);
+ this.AuthProvider = this.convertValues(source["AuthProvider"], api.AuthProviderConfig);
+ this.AuthConfigPersister = source["AuthConfigPersister"];
+ this.ExecProvider = this.convertValues(source["ExecProvider"], api.ExecConfig);
+ this.Insecure = source["Insecure"];
+ this.ServerName = source["ServerName"];
+ this.CertFile = source["CertFile"];
+ this.KeyFile = source["KeyFile"];
+ this.CAFile = source["CAFile"];
+ this.CertData = source["CertData"];
+ this.KeyData = source["KeyData"];
+ this.CAData = source["CAData"];
+ this.NextProtos = source["NextProtos"];
+ this.UserAgent = source["UserAgent"];
+ this.DisableCompression = source["DisableCompression"];
+ this.Transport = source["Transport"];
+ this.QPS = source["QPS"];
+ this.Burst = source["Burst"];
+ this.RateLimiter = source["RateLimiter"];
+ this.WarningHandler = source["WarningHandler"];
+ this.Timeout = source["Timeout"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+
+}
+
+export namespace tls {
+
+ export class ConnectionState {
+ Version: number;
+ HandshakeComplete: boolean;
+ DidResume: boolean;
+ CipherSuite: number;
+ NegotiatedProtocol: string;
+ NegotiatedProtocolIsMutual: boolean;
+ ServerName: string;
+ PeerCertificates: x509.Certificate[];
+ VerifiedChains: x509.Certificate[][];
+ SignedCertificateTimestamps: number[][];
+ OCSPResponse: number[];
+ TLSUnique: number[];
+ ECHAccepted: boolean;
+
+ static createFrom(source: any = {}) {
+ return new ConnectionState(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.Version = source["Version"];
+ this.HandshakeComplete = source["HandshakeComplete"];
+ this.DidResume = source["DidResume"];
+ this.CipherSuite = source["CipherSuite"];
+ this.NegotiatedProtocol = source["NegotiatedProtocol"];
+ this.NegotiatedProtocolIsMutual = source["NegotiatedProtocolIsMutual"];
+ this.ServerName = source["ServerName"];
+ this.PeerCertificates = this.convertValues(source["PeerCertificates"], x509.Certificate);
+ this.VerifiedChains = this.convertValues(source["VerifiedChains"], x509.Certificate);
+ this.SignedCertificateTimestamps = source["SignedCertificateTimestamps"];
+ this.OCSPResponse = source["OCSPResponse"];
+ this.TLSUnique = source["TLSUnique"];
+ this.ECHAccepted = source["ECHAccepted"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+
+}
+
+export namespace types {
+
+ export class Cluster {
+ contextName: string;
+
+ static createFrom(source: any = {}) {
+ return new Cluster(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.contextName = source["contextName"];
+ }
+ }
+ export class ClustersResponse {
+ success: boolean;
+ msg: string;
+ data: Cluster[];
+
+ static createFrom(source: any = {}) {
+ return new ClustersResponse(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.success = source["success"];
+ this.msg = source["msg"];
+ this.data = this.convertValues(source["data"], Cluster);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class ConfigMapsResponse {
+ success: boolean;
+ msg: string;
+ data: v1.ConfigMap[];
+
+ static createFrom(source: any = {}) {
+ return new ConfigMapsResponse(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.success = source["success"];
+ this.msg = source["msg"];
+ this.data = this.convertValues(source["data"], v1.ConfigMap);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class DeploymentResponse {
+ success: boolean;
+ msg: string;
+ data: v1.Deployment;
+
+ static createFrom(source: any = {}) {
+ return new DeploymentResponse(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.success = source["success"];
+ this.msg = source["msg"];
+ this.data = this.convertValues(source["data"], v1.Deployment);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class DeploymentsResponse {
+ success: boolean;
+ msg: string;
+ data: v1.Deployment[];
+
+ static createFrom(source: any = {}) {
+ return new DeploymentsResponse(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.success = source["success"];
+ this.msg = source["msg"];
+ this.data = this.convertValues(source["data"], v1.Deployment);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class DescribeResponse {
+ success: boolean;
+ msg: string;
+ data: string;
+
+ static createFrom(source: any = {}) {
+ return new DescribeResponse(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.success = source["success"];
+ this.msg = source["msg"];
+ this.data = source["data"];
+ }
+ }
+ export class IngressesResponse {
+ success: boolean;
+ msg: string;
+ data: v1.Ingress[];
+
+ static createFrom(source: any = {}) {
+ return new IngressesResponse(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.success = source["success"];
+ this.msg = source["msg"];
+ this.data = this.convertValues(source["data"], v1.Ingress);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class NamespaceResponse {
+ success: boolean;
+ msg: string;
+ data: v1.Namespace;
+
+ static createFrom(source: any = {}) {
+ return new NamespaceResponse(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.success = source["success"];
+ this.msg = source["msg"];
+ this.data = this.convertValues(source["data"], v1.Namespace);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class NamespacesResponse {
+ success: boolean;
+ msg: string;
+ data: v1.Namespace[];
+
+ static createFrom(source: any = {}) {
+ return new NamespacesResponse(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.success = source["success"];
+ this.msg = source["msg"];
+ this.data = this.convertValues(source["data"], v1.Namespace);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class PersistentVolumeClaimResponse {
+ success: boolean;
+ msg: string;
+ data: v1.PersistentVolumeClaim;
+
+ static createFrom(source: any = {}) {
+ return new PersistentVolumeClaimResponse(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.success = source["success"];
+ this.msg = source["msg"];
+ this.data = this.convertValues(source["data"], v1.PersistentVolumeClaim);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class PersistentVolumeClaimsResponse {
+ success: boolean;
+ msg: string;
+ data: v1.PersistentVolumeClaim[];
+
+ static createFrom(source: any = {}) {
+ return new PersistentVolumeClaimsResponse(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.success = source["success"];
+ this.msg = source["msg"];
+ this.data = this.convertValues(source["data"], v1.PersistentVolumeClaim);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class PersistentVolumesResponse {
+ success: boolean;
+ msg: string;
+ data: v1.PersistentVolume[];
+
+ static createFrom(source: any = {}) {
+ return new PersistentVolumesResponse(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.success = source["success"];
+ this.msg = source["msg"];
+ this.data = this.convertValues(source["data"], v1.PersistentVolume);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class PodResponse {
+ success: boolean;
+ msg: string;
+ data: v1.Pod;
+
+ static createFrom(source: any = {}) {
+ return new PodResponse(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.success = source["success"];
+ this.msg = source["msg"];
+ this.data = this.convertValues(source["data"], v1.Pod);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class PodsResponse {
+ success: boolean;
+ msg: string;
+ data: v1.Pod[];
+
+ static createFrom(source: any = {}) {
+ return new PodsResponse(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.success = source["success"];
+ this.msg = source["msg"];
+ this.data = this.convertValues(source["data"], v1.Pod);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class Response {
+ success: boolean;
+ msg: string;
+ data: string;
+
+ static createFrom(source: any = {}) {
+ return new Response(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.success = source["success"];
+ this.msg = source["msg"];
+ this.data = source["data"];
+ }
+ }
+ export class SecretResponse {
+ success: boolean;
+ msg: string;
+ data: v1.Secret;
+
+ static createFrom(source: any = {}) {
+ return new SecretResponse(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.success = source["success"];
+ this.msg = source["msg"];
+ this.data = this.convertValues(source["data"], v1.Secret);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class SecretsResponse {
+ success: boolean;
+ msg: string;
+ data: v1.Secret[];
+
+ static createFrom(source: any = {}) {
+ return new SecretsResponse(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.success = source["success"];
+ this.msg = source["msg"];
+ this.data = this.convertValues(source["data"], v1.Secret);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class StatefulSetResponse {
+ success: boolean;
+ msg: string;
+ data: v1.StatefulSet;
+
+ static createFrom(source: any = {}) {
+ return new StatefulSetResponse(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.success = source["success"];
+ this.msg = source["msg"];
+ this.data = this.convertValues(source["data"], v1.StatefulSet);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class StatefulSetsResponse {
+ success: boolean;
+ msg: string;
+ data: v1.StatefulSet[];
+
+ static createFrom(source: any = {}) {
+ return new StatefulSetsResponse(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.success = source["success"];
+ this.msg = source["msg"];
+ this.data = this.convertValues(source["data"], v1.StatefulSet);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+
+}
+
+export namespace url {
+
+ export class Userinfo {
+
+
+ static createFrom(source: any = {}) {
+ return new Userinfo(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+
+ }
+ }
+ export class URL {
+ Scheme: string;
+ Opaque: string;
+ // Go type: Userinfo
+ User?: any;
+ Host: string;
+ Path: string;
+ RawPath: string;
+ OmitHost: boolean;
+ ForceQuery: boolean;
+ RawQuery: string;
+ Fragment: string;
+ RawFragment: string;
+
+ static createFrom(source: any = {}) {
+ return new URL(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.Scheme = source["Scheme"];
+ this.Opaque = source["Opaque"];
+ this.User = this.convertValues(source["User"], null);
+ this.Host = source["Host"];
+ this.Path = source["Path"];
+ this.RawPath = source["RawPath"];
+ this.OmitHost = source["OmitHost"];
+ this.ForceQuery = source["ForceQuery"];
+ this.RawQuery = source["RawQuery"];
+ this.Fragment = source["Fragment"];
+ this.RawFragment = source["RawFragment"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+
+}
+
+export namespace v1 {
+
+ export class PodAntiAffinity {
+ requiredDuringSchedulingIgnoredDuringExecution?: PodAffinityTerm[];
+ preferredDuringSchedulingIgnoredDuringExecution?: WeightedPodAffinityTerm[];
+
+ static createFrom(source: any = {}) {
+ return new PodAntiAffinity(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.requiredDuringSchedulingIgnoredDuringExecution = this.convertValues(source["requiredDuringSchedulingIgnoredDuringExecution"], PodAffinityTerm);
+ this.preferredDuringSchedulingIgnoredDuringExecution = this.convertValues(source["preferredDuringSchedulingIgnoredDuringExecution"], WeightedPodAffinityTerm);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class WeightedPodAffinityTerm {
+ weight: number;
+ podAffinityTerm: PodAffinityTerm;
+
+ static createFrom(source: any = {}) {
+ return new WeightedPodAffinityTerm(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.weight = source["weight"];
+ this.podAffinityTerm = this.convertValues(source["podAffinityTerm"], PodAffinityTerm);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class LabelSelectorRequirement {
+ key: string;
+ operator: string;
+ values?: string[];
+
+ static createFrom(source: any = {}) {
+ return new LabelSelectorRequirement(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.key = source["key"];
+ this.operator = source["operator"];
+ this.values = source["values"];
+ }
+ }
+ export class LabelSelector {
+ matchLabels?: Record<string, string>;
+ matchExpressions?: LabelSelectorRequirement[];
+
+ static createFrom(source: any = {}) {
+ return new LabelSelector(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.matchLabels = source["matchLabels"];
+ this.matchExpressions = this.convertValues(source["matchExpressions"], LabelSelectorRequirement);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class PodAffinityTerm {
+ labelSelector?: LabelSelector;
+ namespaces?: string[];
+ topologyKey: string;
+ namespaceSelector?: LabelSelector;
+ matchLabelKeys?: string[];
+ mismatchLabelKeys?: string[];
+
+ static createFrom(source: any = {}) {
+ return new PodAffinityTerm(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.labelSelector = this.convertValues(source["labelSelector"], LabelSelector);
+ this.namespaces = source["namespaces"];
+ this.topologyKey = source["topologyKey"];
+ this.namespaceSelector = this.convertValues(source["namespaceSelector"], LabelSelector);
+ this.matchLabelKeys = source["matchLabelKeys"];
+ this.mismatchLabelKeys = source["mismatchLabelKeys"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class PodAffinity {
+ requiredDuringSchedulingIgnoredDuringExecution?: PodAffinityTerm[];
+ preferredDuringSchedulingIgnoredDuringExecution?: WeightedPodAffinityTerm[];
+
+ static createFrom(source: any = {}) {
+ return new PodAffinity(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.requiredDuringSchedulingIgnoredDuringExecution = this.convertValues(source["requiredDuringSchedulingIgnoredDuringExecution"], PodAffinityTerm);
+ this.preferredDuringSchedulingIgnoredDuringExecution = this.convertValues(source["preferredDuringSchedulingIgnoredDuringExecution"], WeightedPodAffinityTerm);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class PreferredSchedulingTerm {
+ weight: number;
+ preference: NodeSelectorTerm;
+
+ static createFrom(source: any = {}) {
+ return new PreferredSchedulingTerm(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.weight = source["weight"];
+ this.preference = this.convertValues(source["preference"], NodeSelectorTerm);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class NodeSelectorRequirement {
+ key: string;
+ operator: string;
+ values?: string[];
+
+ static createFrom(source: any = {}) {
+ return new NodeSelectorRequirement(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.key = source["key"];
+ this.operator = source["operator"];
+ this.values = source["values"];
+ }
+ }
+ export class NodeSelectorTerm {
+ matchExpressions?: NodeSelectorRequirement[];
+ matchFields?: NodeSelectorRequirement[];
+
+ static createFrom(source: any = {}) {
+ return new NodeSelectorTerm(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.matchExpressions = this.convertValues(source["matchExpressions"], NodeSelectorRequirement);
+ this.matchFields = this.convertValues(source["matchFields"], NodeSelectorRequirement);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class NodeSelector {
+ nodeSelectorTerms: NodeSelectorTerm[];
+
+ static createFrom(source: any = {}) {
+ return new NodeSelector(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.nodeSelectorTerms = this.convertValues(source["nodeSelectorTerms"], NodeSelectorTerm);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class NodeAffinity {
+ requiredDuringSchedulingIgnoredDuringExecution?: NodeSelector;
+ preferredDuringSchedulingIgnoredDuringExecution?: PreferredSchedulingTerm[];
+
+ static createFrom(source: any = {}) {
+ return new NodeAffinity(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.requiredDuringSchedulingIgnoredDuringExecution = this.convertValues(source["requiredDuringSchedulingIgnoredDuringExecution"], NodeSelector);
+ this.preferredDuringSchedulingIgnoredDuringExecution = this.convertValues(source["preferredDuringSchedulingIgnoredDuringExecution"], PreferredSchedulingTerm);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class Affinity {
+ nodeAffinity?: NodeAffinity;
+ podAffinity?: PodAffinity;
+ podAntiAffinity?: PodAntiAffinity;
+
+ static createFrom(source: any = {}) {
+ return new Affinity(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.nodeAffinity = this.convertValues(source["nodeAffinity"], NodeAffinity);
+ this.podAffinity = this.convertValues(source["podAffinity"], PodAffinity);
+ this.podAntiAffinity = this.convertValues(source["podAntiAffinity"], PodAntiAffinity);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class AppArmorProfile {
+ type: string;
+ localhostProfile?: string;
+
+ static createFrom(source: any = {}) {
+ return new AppArmorProfile(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.type = source["type"];
+ this.localhostProfile = source["localhostProfile"];
+ }
+ }
+ export class Capabilities {
+ add?: string[];
+ drop?: string[];
+
+ static createFrom(source: any = {}) {
+ return new Capabilities(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.add = source["add"];
+ this.drop = source["drop"];
+ }
+ }
+ export class FieldsV1 {
+
+
+ static createFrom(source: any = {}) {
+ return new FieldsV1(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+
+ }
+ }
+ export class ManagedFieldsEntry {
+ manager?: string;
+ operation?: string;
+ apiVersion?: string;
+ time?: Time;
+ fieldsType?: string;
+ // Go type: FieldsV1
+ fieldsV1?: any;
+ subresource?: string;
+
+ static createFrom(source: any = {}) {
+ return new ManagedFieldsEntry(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.manager = source["manager"];
+ this.operation = source["operation"];
+ this.apiVersion = source["apiVersion"];
+ this.time = this.convertValues(source["time"], Time);
+ this.fieldsType = source["fieldsType"];
+ this.fieldsV1 = this.convertValues(source["fieldsV1"], null);
+ this.subresource = source["subresource"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class OwnerReference {
+ apiVersion: string;
+ kind: string;
+ name: string;
+ uid: string;
+ controller?: boolean;
+ blockOwnerDeletion?: boolean;
+
+ static createFrom(source: any = {}) {
+ return new OwnerReference(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.apiVersion = source["apiVersion"];
+ this.kind = source["kind"];
+ this.name = source["name"];
+ this.uid = source["uid"];
+ this.controller = source["controller"];
+ this.blockOwnerDeletion = source["blockOwnerDeletion"];
+ }
+ }
+ export class Time {
+
+
+ static createFrom(source: any = {}) {
+ return new Time(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+
+ }
+ }
+ export class ConfigMap {
+ kind?: string;
+ apiVersion?: string;
+ name?: string;
+ generateName?: string;
+ namespace?: string;
+ selfLink?: string;
+ uid?: string;
+ resourceVersion?: string;
+ generation?: number;
+ creationTimestamp?: Time;
+ deletionTimestamp?: Time;
+ deletionGracePeriodSeconds?: number;
+ labels?: Record<string, string>;
+ annotations?: Record<string, string>;
+ ownerReferences?: OwnerReference[];
+ finalizers?: string[];
+ managedFields?: ManagedFieldsEntry[];
+ immutable?: boolean;
+ data?: Record<string, string>;
+ binaryData?: Record<string, number[]>;
+
+ static createFrom(source: any = {}) {
+ return new ConfigMap(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.kind = source["kind"];
+ this.apiVersion = source["apiVersion"];
+ this.name = source["name"];
+ this.generateName = source["generateName"];
+ this.namespace = source["namespace"];
+ this.selfLink = source["selfLink"];
+ this.uid = source["uid"];
+ this.resourceVersion = source["resourceVersion"];
+ this.generation = source["generation"];
+ this.creationTimestamp = this.convertValues(source["creationTimestamp"], Time);
+ this.deletionTimestamp = this.convertValues(source["deletionTimestamp"], Time);
+ this.deletionGracePeriodSeconds = source["deletionGracePeriodSeconds"];
+ this.labels = source["labels"];
+ this.annotations = source["annotations"];
+ this.ownerReferences = this.convertValues(source["ownerReferences"], OwnerReference);
+ this.finalizers = source["finalizers"];
+ this.managedFields = this.convertValues(source["managedFields"], ManagedFieldsEntry);
+ this.immutable = source["immutable"];
+ this.data = source["data"];
+ this.binaryData = source["binaryData"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class ConfigMapEnvSource {
+ name?: string;
+ optional?: boolean;
+
+ static createFrom(source: any = {}) {
+ return new ConfigMapEnvSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.optional = source["optional"];
+ }
+ }
+ export class ConfigMapKeySelector {
+ name?: string;
+ key: string;
+ optional?: boolean;
+
+ static createFrom(source: any = {}) {
+ return new ConfigMapKeySelector(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.key = source["key"];
+ this.optional = source["optional"];
+ }
+ }
+ export class SeccompProfile {
+ type: string;
+ localhostProfile?: string;
+
+ static createFrom(source: any = {}) {
+ return new SeccompProfile(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.type = source["type"];
+ this.localhostProfile = source["localhostProfile"];
+ }
+ }
+ export class WindowsSecurityContextOptions {
+ gmsaCredentialSpecName?: string;
+ gmsaCredentialSpec?: string;
+ runAsUserName?: string;
+ hostProcess?: boolean;
+
+ static createFrom(source: any = {}) {
+ return new WindowsSecurityContextOptions(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.gmsaCredentialSpecName = source["gmsaCredentialSpecName"];
+ this.gmsaCredentialSpec = source["gmsaCredentialSpec"];
+ this.runAsUserName = source["runAsUserName"];
+ this.hostProcess = source["hostProcess"];
+ }
+ }
+ export class SELinuxOptions {
+ user?: string;
+ role?: string;
+ type?: string;
+ level?: string;
+
+ static createFrom(source: any = {}) {
+ return new SELinuxOptions(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.user = source["user"];
+ this.role = source["role"];
+ this.type = source["type"];
+ this.level = source["level"];
+ }
+ }
+ export class SecurityContext {
+ capabilities?: Capabilities;
+ privileged?: boolean;
+ seLinuxOptions?: SELinuxOptions;
+ windowsOptions?: WindowsSecurityContextOptions;
+ runAsUser?: number;
+ runAsGroup?: number;
+ runAsNonRoot?: boolean;
+ readOnlyRootFilesystem?: boolean;
+ allowPrivilegeEscalation?: boolean;
+ procMount?: string;
+ seccompProfile?: SeccompProfile;
+ appArmorProfile?: AppArmorProfile;
+
+ static createFrom(source: any = {}) {
+ return new SecurityContext(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.capabilities = this.convertValues(source["capabilities"], Capabilities);
+ this.privileged = source["privileged"];
+ this.seLinuxOptions = this.convertValues(source["seLinuxOptions"], SELinuxOptions);
+ this.windowsOptions = this.convertValues(source["windowsOptions"], WindowsSecurityContextOptions);
+ this.runAsUser = source["runAsUser"];
+ this.runAsGroup = source["runAsGroup"];
+ this.runAsNonRoot = source["runAsNonRoot"];
+ this.readOnlyRootFilesystem = source["readOnlyRootFilesystem"];
+ this.allowPrivilegeEscalation = source["allowPrivilegeEscalation"];
+ this.procMount = source["procMount"];
+ this.seccompProfile = this.convertValues(source["seccompProfile"], SeccompProfile);
+ this.appArmorProfile = this.convertValues(source["appArmorProfile"], AppArmorProfile);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class SleepAction {
+ seconds: number;
+
+ static createFrom(source: any = {}) {
+ return new SleepAction(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.seconds = source["seconds"];
+ }
+ }
+ export class LifecycleHandler {
+ exec?: ExecAction;
+ httpGet?: HTTPGetAction;
+ tcpSocket?: TCPSocketAction;
+ sleep?: SleepAction;
+
+ static createFrom(source: any = {}) {
+ return new LifecycleHandler(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.exec = this.convertValues(source["exec"], ExecAction);
+ this.httpGet = this.convertValues(source["httpGet"], HTTPGetAction);
+ this.tcpSocket = this.convertValues(source["tcpSocket"], TCPSocketAction);
+ this.sleep = this.convertValues(source["sleep"], SleepAction);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class Lifecycle {
+ postStart?: LifecycleHandler;
+ preStop?: LifecycleHandler;
+
+ static createFrom(source: any = {}) {
+ return new Lifecycle(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.postStart = this.convertValues(source["postStart"], LifecycleHandler);
+ this.preStop = this.convertValues(source["preStop"], LifecycleHandler);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class GRPCAction {
+ port: number;
+ service?: string;
+
+ static createFrom(source: any = {}) {
+ return new GRPCAction(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.port = source["port"];
+ this.service = source["service"];
+ }
+ }
+ export class TCPSocketAction {
+ port: intstr.IntOrString;
+ host?: string;
+
+ static createFrom(source: any = {}) {
+ return new TCPSocketAction(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.port = this.convertValues(source["port"], intstr.IntOrString);
+ this.host = source["host"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class HTTPHeader {
+ name: string;
+ value: string;
+
+ static createFrom(source: any = {}) {
+ return new HTTPHeader(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.value = source["value"];
+ }
+ }
+ export class HTTPGetAction {
+ path?: string;
+ port: intstr.IntOrString;
+ host?: string;
+ scheme?: string;
+ httpHeaders?: HTTPHeader[];
+
+ static createFrom(source: any = {}) {
+ return new HTTPGetAction(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.path = source["path"];
+ this.port = this.convertValues(source["port"], intstr.IntOrString);
+ this.host = source["host"];
+ this.scheme = source["scheme"];
+ this.httpHeaders = this.convertValues(source["httpHeaders"], HTTPHeader);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class ExecAction {
+ command?: string[];
+
+ static createFrom(source: any = {}) {
+ return new ExecAction(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.command = source["command"];
+ }
+ }
+ export class Probe {
+ exec?: ExecAction;
+ httpGet?: HTTPGetAction;
+ tcpSocket?: TCPSocketAction;
+ // Go type: GRPCAction
+ grpc?: any;
+ initialDelaySeconds?: number;
+ timeoutSeconds?: number;
+ periodSeconds?: number;
+ successThreshold?: number;
+ failureThreshold?: number;
+ terminationGracePeriodSeconds?: number;
+
+ static createFrom(source: any = {}) {
+ return new Probe(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.exec = this.convertValues(source["exec"], ExecAction);
+ this.httpGet = this.convertValues(source["httpGet"], HTTPGetAction);
+ this.tcpSocket = this.convertValues(source["tcpSocket"], TCPSocketAction);
+ this.grpc = this.convertValues(source["grpc"], null);
+ this.initialDelaySeconds = source["initialDelaySeconds"];
+ this.timeoutSeconds = source["timeoutSeconds"];
+ this.periodSeconds = source["periodSeconds"];
+ this.successThreshold = source["successThreshold"];
+ this.failureThreshold = source["failureThreshold"];
+ this.terminationGracePeriodSeconds = source["terminationGracePeriodSeconds"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class VolumeDevice {
+ name: string;
+ devicePath: string;
+
+ static createFrom(source: any = {}) {
+ return new VolumeDevice(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.devicePath = source["devicePath"];
+ }
+ }
+ export class VolumeMount {
+ name: string;
+ readOnly?: boolean;
+ recursiveReadOnly?: string;
+ mountPath: string;
+ subPath?: string;
+ mountPropagation?: string;
+ subPathExpr?: string;
+
+ static createFrom(source: any = {}) {
+ return new VolumeMount(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.readOnly = source["readOnly"];
+ this.recursiveReadOnly = source["recursiveReadOnly"];
+ this.mountPath = source["mountPath"];
+ this.subPath = source["subPath"];
+ this.mountPropagation = source["mountPropagation"];
+ this.subPathExpr = source["subPathExpr"];
+ }
+ }
+ export class ContainerResizePolicy {
+ resourceName: string;
+ restartPolicy: string;
+
+ static createFrom(source: any = {}) {
+ return new ContainerResizePolicy(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.resourceName = source["resourceName"];
+ this.restartPolicy = source["restartPolicy"];
+ }
+ }
+ export class ResourceClaim {
+ name: string;
+ request?: string;
+
+ static createFrom(source: any = {}) {
+ return new ResourceClaim(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.request = source["request"];
+ }
+ }
+ export class ResourceRequirements {
+ limits?: Record<string, resource.Quantity>;
+ requests?: Record<string, resource.Quantity>;
+ claims?: ResourceClaim[];
+
+ static createFrom(source: any = {}) {
+ return new ResourceRequirements(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.limits = this.convertValues(source["limits"], resource.Quantity, true);
+ this.requests = this.convertValues(source["requests"], resource.Quantity, true);
+ this.claims = this.convertValues(source["claims"], ResourceClaim);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class SecretKeySelector {
+ name?: string;
+ key: string;
+ optional?: boolean;
+
+ static createFrom(source: any = {}) {
+ return new SecretKeySelector(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.key = source["key"];
+ this.optional = source["optional"];
+ }
+ }
+ export class ResourceFieldSelector {
+ containerName?: string;
+ resource: string;
+ divisor?: resource.Quantity;
+
+ static createFrom(source: any = {}) {
+ return new ResourceFieldSelector(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.containerName = source["containerName"];
+ this.resource = source["resource"];
+ this.divisor = this.convertValues(source["divisor"], resource.Quantity);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class ObjectFieldSelector {
+ apiVersion?: string;
+ fieldPath: string;
+
+ static createFrom(source: any = {}) {
+ return new ObjectFieldSelector(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.apiVersion = source["apiVersion"];
+ this.fieldPath = source["fieldPath"];
+ }
+ }
+ export class EnvVarSource {
+ fieldRef?: ObjectFieldSelector;
+ resourceFieldRef?: ResourceFieldSelector;
+ configMapKeyRef?: ConfigMapKeySelector;
+ secretKeyRef?: SecretKeySelector;
+
+ static createFrom(source: any = {}) {
+ return new EnvVarSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.fieldRef = this.convertValues(source["fieldRef"], ObjectFieldSelector);
+ this.resourceFieldRef = this.convertValues(source["resourceFieldRef"], ResourceFieldSelector);
+ this.configMapKeyRef = this.convertValues(source["configMapKeyRef"], ConfigMapKeySelector);
+ this.secretKeyRef = this.convertValues(source["secretKeyRef"], SecretKeySelector);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class EnvVar {
+ name: string;
+ value?: string;
+ valueFrom?: EnvVarSource;
+
+ static createFrom(source: any = {}) {
+ return new EnvVar(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.value = source["value"];
+ this.valueFrom = this.convertValues(source["valueFrom"], EnvVarSource);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class SecretEnvSource {
+ name?: string;
+ optional?: boolean;
+
+ static createFrom(source: any = {}) {
+ return new SecretEnvSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.optional = source["optional"];
+ }
+ }
+ export class EnvFromSource {
+ prefix?: string;
+ configMapRef?: ConfigMapEnvSource;
+ secretRef?: SecretEnvSource;
+
+ static createFrom(source: any = {}) {
+ return new EnvFromSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.prefix = source["prefix"];
+ this.configMapRef = this.convertValues(source["configMapRef"], ConfigMapEnvSource);
+ this.secretRef = this.convertValues(source["secretRef"], SecretEnvSource);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class ContainerPort {
+ name?: string;
+ hostPort?: number;
+ containerPort: number;
+ protocol?: string;
+ hostIP?: string;
+
+ static createFrom(source: any = {}) {
+ return new ContainerPort(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.hostPort = source["hostPort"];
+ this.containerPort = source["containerPort"];
+ this.protocol = source["protocol"];
+ this.hostIP = source["hostIP"];
+ }
+ }
+ export class Container {
+ name: string;
+ image?: string;
+ command?: string[];
+ args?: string[];
+ workingDir?: string;
+ ports?: ContainerPort[];
+ envFrom?: EnvFromSource[];
+ env?: EnvVar[];
+ resources?: ResourceRequirements;
+ resizePolicy?: ContainerResizePolicy[];
+ restartPolicy?: string;
+ volumeMounts?: VolumeMount[];
+ volumeDevices?: VolumeDevice[];
+ livenessProbe?: Probe;
+ readinessProbe?: Probe;
+ startupProbe?: Probe;
+ lifecycle?: Lifecycle;
+ terminationMessagePath?: string;
+ terminationMessagePolicy?: string;
+ imagePullPolicy?: string;
+ securityContext?: SecurityContext;
+ stdin?: boolean;
+ stdinOnce?: boolean;
+ tty?: boolean;
+
+ static createFrom(source: any = {}) {
+ return new Container(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.image = source["image"];
+ this.command = source["command"];
+ this.args = source["args"];
+ this.workingDir = source["workingDir"];
+ this.ports = this.convertValues(source["ports"], ContainerPort);
+ this.envFrom = this.convertValues(source["envFrom"], EnvFromSource);
+ this.env = this.convertValues(source["env"], EnvVar);
+ this.resources = this.convertValues(source["resources"], ResourceRequirements);
+ this.resizePolicy = this.convertValues(source["resizePolicy"], ContainerResizePolicy);
+ this.restartPolicy = source["restartPolicy"];
+ this.volumeMounts = this.convertValues(source["volumeMounts"], VolumeMount);
+ this.volumeDevices = this.convertValues(source["volumeDevices"], VolumeDevice);
+ this.livenessProbe = this.convertValues(source["livenessProbe"], Probe);
+ this.readinessProbe = this.convertValues(source["readinessProbe"], Probe);
+ this.startupProbe = this.convertValues(source["startupProbe"], Probe);
+ this.lifecycle = this.convertValues(source["lifecycle"], Lifecycle);
+ this.terminationMessagePath = source["terminationMessagePath"];
+ this.terminationMessagePolicy = source["terminationMessagePolicy"];
+ this.imagePullPolicy = source["imagePullPolicy"];
+ this.securityContext = this.convertValues(source["securityContext"], SecurityContext);
+ this.stdin = source["stdin"];
+ this.stdinOnce = source["stdinOnce"];
+ this.tty = source["tty"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+
+
+ export class ContainerStateTerminated {
+ exitCode: number;
+ signal?: number;
+ reason?: string;
+ message?: string;
+ startedAt?: Time;
+ finishedAt?: Time;
+ containerID?: string;
+
+ static createFrom(source: any = {}) {
+ return new ContainerStateTerminated(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.exitCode = source["exitCode"];
+ this.signal = source["signal"];
+ this.reason = source["reason"];
+ this.message = source["message"];
+ this.startedAt = this.convertValues(source["startedAt"], Time);
+ this.finishedAt = this.convertValues(source["finishedAt"], Time);
+ this.containerID = source["containerID"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class ContainerStateRunning {
+ startedAt?: Time;
+
+ static createFrom(source: any = {}) {
+ return new ContainerStateRunning(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.startedAt = this.convertValues(source["startedAt"], Time);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class ContainerStateWaiting {
+ reason?: string;
+ message?: string;
+
+ static createFrom(source: any = {}) {
+ return new ContainerStateWaiting(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.reason = source["reason"];
+ this.message = source["message"];
+ }
+ }
+ export class ContainerState {
+ waiting?: ContainerStateWaiting;
+ running?: ContainerStateRunning;
+ terminated?: ContainerStateTerminated;
+
+ static createFrom(source: any = {}) {
+ return new ContainerState(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.waiting = this.convertValues(source["waiting"], ContainerStateWaiting);
+ this.running = this.convertValues(source["running"], ContainerStateRunning);
+ this.terminated = this.convertValues(source["terminated"], ContainerStateTerminated);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+
+
+
+ export class ResourceHealth {
+ resourceID: string;
+ health?: string;
+
+ static createFrom(source: any = {}) {
+ return new ResourceHealth(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.resourceID = source["resourceID"];
+ this.health = source["health"];
+ }
+ }
+ export class ResourceStatus {
+ name: string;
+ resources?: ResourceHealth[];
+
+ static createFrom(source: any = {}) {
+ return new ResourceStatus(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.resources = this.convertValues(source["resources"], ResourceHealth);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class LinuxContainerUser {
+ uid: number;
+ gid: number;
+ supplementalGroups?: number[];
+
+ static createFrom(source: any = {}) {
+ return new LinuxContainerUser(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.uid = source["uid"];
+ this.gid = source["gid"];
+ this.supplementalGroups = source["supplementalGroups"];
+ }
+ }
+ export class ContainerUser {
+ linux?: LinuxContainerUser;
+
+ static createFrom(source: any = {}) {
+ return new ContainerUser(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.linux = this.convertValues(source["linux"], LinuxContainerUser);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class VolumeMountStatus {
+ name: string;
+ mountPath: string;
+ readOnly?: boolean;
+ recursiveReadOnly?: string;
+
+ static createFrom(source: any = {}) {
+ return new VolumeMountStatus(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.mountPath = source["mountPath"];
+ this.readOnly = source["readOnly"];
+ this.recursiveReadOnly = source["recursiveReadOnly"];
+ }
+ }
+ export class ContainerStatus {
+ name: string;
+ state?: ContainerState;
+ lastState?: ContainerState;
+ ready: boolean;
+ restartCount: number;
+ image: string;
+ imageID: string;
+ containerID?: string;
+ started?: boolean;
+ allocatedResources?: Record<string, resource.Quantity>;
+ resources?: ResourceRequirements;
+ volumeMounts?: VolumeMountStatus[];
+ user?: ContainerUser;
+ allocatedResourcesStatus?: ResourceStatus[];
+
+ static createFrom(source: any = {}) {
+ return new ContainerStatus(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.state = this.convertValues(source["state"], ContainerState);
+ this.lastState = this.convertValues(source["lastState"], ContainerState);
+ this.ready = source["ready"];
+ this.restartCount = source["restartCount"];
+ this.image = source["image"];
+ this.imageID = source["imageID"];
+ this.containerID = source["containerID"];
+ this.started = source["started"];
+ this.allocatedResources = this.convertValues(source["allocatedResources"], resource.Quantity, true);
+ this.resources = this.convertValues(source["resources"], ResourceRequirements);
+ this.volumeMounts = this.convertValues(source["volumeMounts"], VolumeMountStatus);
+ this.user = this.convertValues(source["user"], ContainerUser);
+ this.allocatedResourcesStatus = this.convertValues(source["allocatedResourcesStatus"], ResourceStatus);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+
+ export class DeploymentCondition {
+ type: string;
+ status: string;
+ lastUpdateTime?: Time;
+ lastTransitionTime?: Time;
+ reason?: string;
+ message?: string;
+
+ static createFrom(source: any = {}) {
+ return new DeploymentCondition(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.type = source["type"];
+ this.status = source["status"];
+ this.lastUpdateTime = this.convertValues(source["lastUpdateTime"], Time);
+ this.lastTransitionTime = this.convertValues(source["lastTransitionTime"], Time);
+ this.reason = source["reason"];
+ this.message = source["message"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class DeploymentStatus {
+ observedGeneration?: number;
+ replicas?: number;
+ updatedReplicas?: number;
+ readyReplicas?: number;
+ availableReplicas?: number;
+ unavailableReplicas?: number;
+ conditions?: DeploymentCondition[];
+ collisionCount?: number;
+
+ static createFrom(source: any = {}) {
+ return new DeploymentStatus(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.observedGeneration = source["observedGeneration"];
+ this.replicas = source["replicas"];
+ this.updatedReplicas = source["updatedReplicas"];
+ this.readyReplicas = source["readyReplicas"];
+ this.availableReplicas = source["availableReplicas"];
+ this.unavailableReplicas = source["unavailableReplicas"];
+ this.conditions = this.convertValues(source["conditions"], DeploymentCondition);
+ this.collisionCount = source["collisionCount"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class RollingUpdateDeployment {
+ maxUnavailable?: intstr.IntOrString;
+ maxSurge?: intstr.IntOrString;
+
+ static createFrom(source: any = {}) {
+ return new RollingUpdateDeployment(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.maxUnavailable = this.convertValues(source["maxUnavailable"], intstr.IntOrString);
+ this.maxSurge = this.convertValues(source["maxSurge"], intstr.IntOrString);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class DeploymentStrategy {
+ type?: string;
+ rollingUpdate?: RollingUpdateDeployment;
+
+ static createFrom(source: any = {}) {
+ return new DeploymentStrategy(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.type = source["type"];
+ this.rollingUpdate = this.convertValues(source["rollingUpdate"], RollingUpdateDeployment);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class PodResourceClaim {
+ name: string;
+ resourceClaimName?: string;
+ resourceClaimTemplateName?: string;
+
+ static createFrom(source: any = {}) {
+ return new PodResourceClaim(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.resourceClaimName = source["resourceClaimName"];
+ this.resourceClaimTemplateName = source["resourceClaimTemplateName"];
+ }
+ }
+ export class PodSchedulingGate {
+ name: string;
+
+ static createFrom(source: any = {}) {
+ return new PodSchedulingGate(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ }
+ }
+ export class PodOS {
+ name: string;
+
+ static createFrom(source: any = {}) {
+ return new PodOS(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ }
+ }
+ export class TopologySpreadConstraint {
+ maxSkew: number;
+ topologyKey: string;
+ whenUnsatisfiable: string;
+ labelSelector?: LabelSelector;
+ minDomains?: number;
+ nodeAffinityPolicy?: string;
+ nodeTaintsPolicy?: string;
+ matchLabelKeys?: string[];
+
+ static createFrom(source: any = {}) {
+ return new TopologySpreadConstraint(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.maxSkew = source["maxSkew"];
+ this.topologyKey = source["topologyKey"];
+ this.whenUnsatisfiable = source["whenUnsatisfiable"];
+ this.labelSelector = this.convertValues(source["labelSelector"], LabelSelector);
+ this.minDomains = source["minDomains"];
+ this.nodeAffinityPolicy = source["nodeAffinityPolicy"];
+ this.nodeTaintsPolicy = source["nodeTaintsPolicy"];
+ this.matchLabelKeys = source["matchLabelKeys"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class PodReadinessGate {
+ conditionType: string;
+
+ static createFrom(source: any = {}) {
+ return new PodReadinessGate(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.conditionType = source["conditionType"];
+ }
+ }
+ export class PodDNSConfigOption {
+ name?: string;
+ value?: string;
+
+ static createFrom(source: any = {}) {
+ return new PodDNSConfigOption(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.value = source["value"];
+ }
+ }
+ export class PodDNSConfig {
+ nameservers?: string[];
+ searches?: string[];
+ options?: PodDNSConfigOption[];
+
+ static createFrom(source: any = {}) {
+ return new PodDNSConfig(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.nameservers = source["nameservers"];
+ this.searches = source["searches"];
+ this.options = this.convertValues(source["options"], PodDNSConfigOption);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class HostAlias {
+ ip: string;
+ hostnames?: string[];
+
+ static createFrom(source: any = {}) {
+ return new HostAlias(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.ip = source["ip"];
+ this.hostnames = source["hostnames"];
+ }
+ }
+ export class Toleration {
+ key?: string;
+ operator?: string;
+ value?: string;
+ effect?: string;
+ tolerationSeconds?: number;
+
+ static createFrom(source: any = {}) {
+ return new Toleration(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.key = source["key"];
+ this.operator = source["operator"];
+ this.value = source["value"];
+ this.effect = source["effect"];
+ this.tolerationSeconds = source["tolerationSeconds"];
+ }
+ }
+ export class Sysctl {
+ name: string;
+ value: string;
+
+ static createFrom(source: any = {}) {
+ return new Sysctl(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.value = source["value"];
+ }
+ }
+ export class PodSecurityContext {
+ seLinuxOptions?: SELinuxOptions;
+ windowsOptions?: WindowsSecurityContextOptions;
+ runAsUser?: number;
+ runAsGroup?: number;
+ runAsNonRoot?: boolean;
+ supplementalGroups?: number[];
+ supplementalGroupsPolicy?: string;
+ fsGroup?: number;
+ sysctls?: Sysctl[];
+ fsGroupChangePolicy?: string;
+ seccompProfile?: SeccompProfile;
+ appArmorProfile?: AppArmorProfile;
+ seLinuxChangePolicy?: string;
+
+ static createFrom(source: any = {}) {
+ return new PodSecurityContext(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.seLinuxOptions = this.convertValues(source["seLinuxOptions"], SELinuxOptions);
+ this.windowsOptions = this.convertValues(source["windowsOptions"], WindowsSecurityContextOptions);
+ this.runAsUser = source["runAsUser"];
+ this.runAsGroup = source["runAsGroup"];
+ this.runAsNonRoot = source["runAsNonRoot"];
+ this.supplementalGroups = source["supplementalGroups"];
+ this.supplementalGroupsPolicy = source["supplementalGroupsPolicy"];
+ this.fsGroup = source["fsGroup"];
+ this.sysctls = this.convertValues(source["sysctls"], Sysctl);
+ this.fsGroupChangePolicy = source["fsGroupChangePolicy"];
+ this.seccompProfile = this.convertValues(source["seccompProfile"], SeccompProfile);
+ this.appArmorProfile = this.convertValues(source["appArmorProfile"], AppArmorProfile);
+ this.seLinuxChangePolicy = source["seLinuxChangePolicy"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class EphemeralContainer {
+ name: string;
+ image?: string;
+ command?: string[];
+ args?: string[];
+ workingDir?: string;
+ ports?: ContainerPort[];
+ envFrom?: EnvFromSource[];
+ env?: EnvVar[];
+ resources?: ResourceRequirements;
+ resizePolicy?: ContainerResizePolicy[];
+ restartPolicy?: string;
+ volumeMounts?: VolumeMount[];
+ volumeDevices?: VolumeDevice[];
+ livenessProbe?: Probe;
+ readinessProbe?: Probe;
+ startupProbe?: Probe;
+ lifecycle?: Lifecycle;
+ terminationMessagePath?: string;
+ terminationMessagePolicy?: string;
+ imagePullPolicy?: string;
+ securityContext?: SecurityContext;
+ stdin?: boolean;
+ stdinOnce?: boolean;
+ tty?: boolean;
+ targetContainerName?: string;
+
+ static createFrom(source: any = {}) {
+ return new EphemeralContainer(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.image = source["image"];
+ this.command = source["command"];
+ this.args = source["args"];
+ this.workingDir = source["workingDir"];
+ this.ports = this.convertValues(source["ports"], ContainerPort);
+ this.envFrom = this.convertValues(source["envFrom"], EnvFromSource);
+ this.env = this.convertValues(source["env"], EnvVar);
+ this.resources = this.convertValues(source["resources"], ResourceRequirements);
+ this.resizePolicy = this.convertValues(source["resizePolicy"], ContainerResizePolicy);
+ this.restartPolicy = source["restartPolicy"];
+ this.volumeMounts = this.convertValues(source["volumeMounts"], VolumeMount);
+ this.volumeDevices = this.convertValues(source["volumeDevices"], VolumeDevice);
+ this.livenessProbe = this.convertValues(source["livenessProbe"], Probe);
+ this.readinessProbe = this.convertValues(source["readinessProbe"], Probe);
+ this.startupProbe = this.convertValues(source["startupProbe"], Probe);
+ this.lifecycle = this.convertValues(source["lifecycle"], Lifecycle);
+ this.terminationMessagePath = source["terminationMessagePath"];
+ this.terminationMessagePolicy = source["terminationMessagePolicy"];
+ this.imagePullPolicy = source["imagePullPolicy"];
+ this.securityContext = this.convertValues(source["securityContext"], SecurityContext);
+ this.stdin = source["stdin"];
+ this.stdinOnce = source["stdinOnce"];
+ this.tty = source["tty"];
+ this.targetContainerName = source["targetContainerName"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class ImageVolumeSource {
+ reference?: string;
+ pullPolicy?: string;
+
+ static createFrom(source: any = {}) {
+ return new ImageVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.reference = source["reference"];
+ this.pullPolicy = source["pullPolicy"];
+ }
+ }
+ export class TypedObjectReference {
+ apiGroup?: string;
+ kind: string;
+ name: string;
+ namespace?: string;
+
+ static createFrom(source: any = {}) {
+ return new TypedObjectReference(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.apiGroup = source["apiGroup"];
+ this.kind = source["kind"];
+ this.name = source["name"];
+ this.namespace = source["namespace"];
+ }
+ }
+ export class TypedLocalObjectReference {
+ apiGroup?: string;
+ kind: string;
+ name: string;
+
+ static createFrom(source: any = {}) {
+ return new TypedLocalObjectReference(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.apiGroup = source["apiGroup"];
+ this.kind = source["kind"];
+ this.name = source["name"];
+ }
+ }
+ export class VolumeResourceRequirements {
+ limits?: Record<string, resource.Quantity>;
+ requests?: Record<string, resource.Quantity>;
+
+ static createFrom(source: any = {}) {
+ return new VolumeResourceRequirements(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.limits = this.convertValues(source["limits"], resource.Quantity, true);
+ this.requests = this.convertValues(source["requests"], resource.Quantity, true);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class PersistentVolumeClaimSpec {
+ accessModes?: string[];
+ selector?: LabelSelector;
+ resources?: VolumeResourceRequirements;
+ volumeName?: string;
+ storageClassName?: string;
+ volumeMode?: string;
+ dataSource?: TypedLocalObjectReference;
+ dataSourceRef?: TypedObjectReference;
+ volumeAttributesClassName?: string;
+
+ static createFrom(source: any = {}) {
+ return new PersistentVolumeClaimSpec(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.accessModes = source["accessModes"];
+ this.selector = this.convertValues(source["selector"], LabelSelector);
+ this.resources = this.convertValues(source["resources"], VolumeResourceRequirements);
+ this.volumeName = source["volumeName"];
+ this.storageClassName = source["storageClassName"];
+ this.volumeMode = source["volumeMode"];
+ this.dataSource = this.convertValues(source["dataSource"], TypedLocalObjectReference);
+ this.dataSourceRef = this.convertValues(source["dataSourceRef"], TypedObjectReference);
+ this.volumeAttributesClassName = source["volumeAttributesClassName"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class PersistentVolumeClaimTemplate {
+ name?: string;
+ generateName?: string;
+ namespace?: string;
+ selfLink?: string;
+ uid?: string;
+ resourceVersion?: string;
+ generation?: number;
+ creationTimestamp?: Time;
+ deletionTimestamp?: Time;
+ deletionGracePeriodSeconds?: number;
+ labels?: Record<string, string>;
+ annotations?: Record<string, string>;
+ ownerReferences?: OwnerReference[];
+ finalizers?: string[];
+ managedFields?: ManagedFieldsEntry[];
+ spec: PersistentVolumeClaimSpec;
+
+ static createFrom(source: any = {}) {
+ return new PersistentVolumeClaimTemplate(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.generateName = source["generateName"];
+ this.namespace = source["namespace"];
+ this.selfLink = source["selfLink"];
+ this.uid = source["uid"];
+ this.resourceVersion = source["resourceVersion"];
+ this.generation = source["generation"];
+ this.creationTimestamp = this.convertValues(source["creationTimestamp"], Time);
+ this.deletionTimestamp = this.convertValues(source["deletionTimestamp"], Time);
+ this.deletionGracePeriodSeconds = source["deletionGracePeriodSeconds"];
+ this.labels = source["labels"];
+ this.annotations = source["annotations"];
+ this.ownerReferences = this.convertValues(source["ownerReferences"], OwnerReference);
+ this.finalizers = source["finalizers"];
+ this.managedFields = this.convertValues(source["managedFields"], ManagedFieldsEntry);
+ this.spec = this.convertValues(source["spec"], PersistentVolumeClaimSpec);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class EphemeralVolumeSource {
+ // Go type: PersistentVolumeClaimTemplate
+ volumeClaimTemplate?: any;
+
+ static createFrom(source: any = {}) {
+ return new EphemeralVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.volumeClaimTemplate = this.convertValues(source["volumeClaimTemplate"], null);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class CSIVolumeSource {
+ driver: string;
+ readOnly?: boolean;
+ fsType?: string;
+ volumeAttributes?: Record<string, string>;
+ nodePublishSecretRef?: LocalObjectReference;
+
+ static createFrom(source: any = {}) {
+ return new CSIVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.driver = source["driver"];
+ this.readOnly = source["readOnly"];
+ this.fsType = source["fsType"];
+ this.volumeAttributes = source["volumeAttributes"];
+ this.nodePublishSecretRef = this.convertValues(source["nodePublishSecretRef"], LocalObjectReference);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class StorageOSVolumeSource {
+ volumeName?: string;
+ volumeNamespace?: string;
+ fsType?: string;
+ readOnly?: boolean;
+ secretRef?: LocalObjectReference;
+
+ static createFrom(source: any = {}) {
+ return new StorageOSVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.volumeName = source["volumeName"];
+ this.volumeNamespace = source["volumeNamespace"];
+ this.fsType = source["fsType"];
+ this.readOnly = source["readOnly"];
+ this.secretRef = this.convertValues(source["secretRef"], LocalObjectReference);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class ScaleIOVolumeSource {
+ gateway: string;
+ system: string;
+ secretRef?: LocalObjectReference;
+ sslEnabled?: boolean;
+ protectionDomain?: string;
+ storagePool?: string;
+ storageMode?: string;
+ volumeName?: string;
+ fsType?: string;
+ readOnly?: boolean;
+
+ static createFrom(source: any = {}) {
+ return new ScaleIOVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.gateway = source["gateway"];
+ this.system = source["system"];
+ this.secretRef = this.convertValues(source["secretRef"], LocalObjectReference);
+ this.sslEnabled = source["sslEnabled"];
+ this.protectionDomain = source["protectionDomain"];
+ this.storagePool = source["storagePool"];
+ this.storageMode = source["storageMode"];
+ this.volumeName = source["volumeName"];
+ this.fsType = source["fsType"];
+ this.readOnly = source["readOnly"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class PortworxVolumeSource {
+ volumeID: string;
+ fsType?: string;
+ readOnly?: boolean;
+
+ static createFrom(source: any = {}) {
+ return new PortworxVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.volumeID = source["volumeID"];
+ this.fsType = source["fsType"];
+ this.readOnly = source["readOnly"];
+ }
+ }
+ export class ClusterTrustBundleProjection {
+ name?: string;
+ signerName?: string;
+ labelSelector?: LabelSelector;
+ optional?: boolean;
+ path: string;
+
+ static createFrom(source: any = {}) {
+ return new ClusterTrustBundleProjection(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.signerName = source["signerName"];
+ this.labelSelector = this.convertValues(source["labelSelector"], LabelSelector);
+ this.optional = source["optional"];
+ this.path = source["path"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class ServiceAccountTokenProjection {
+ audience?: string;
+ expirationSeconds?: number;
+ path: string;
+
+ static createFrom(source: any = {}) {
+ return new ServiceAccountTokenProjection(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.audience = source["audience"];
+ this.expirationSeconds = source["expirationSeconds"];
+ this.path = source["path"];
+ }
+ }
+ export class ConfigMapProjection {
+ name?: string;
+ items?: KeyToPath[];
+ optional?: boolean;
+
+ static createFrom(source: any = {}) {
+ return new ConfigMapProjection(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.items = this.convertValues(source["items"], KeyToPath);
+ this.optional = source["optional"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class DownwardAPIProjection {
+ items?: DownwardAPIVolumeFile[];
+
+ static createFrom(source: any = {}) {
+ return new DownwardAPIProjection(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.items = this.convertValues(source["items"], DownwardAPIVolumeFile);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class SecretProjection {
+ name?: string;
+ items?: KeyToPath[];
+ optional?: boolean;
+
+ static createFrom(source: any = {}) {
+ return new SecretProjection(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.items = this.convertValues(source["items"], KeyToPath);
+ this.optional = source["optional"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class VolumeProjection {
+ // Go type: SecretProjection
+ secret?: any;
+ // Go type: DownwardAPIProjection
+ downwardAPI?: any;
+ // Go type: ConfigMapProjection
+ configMap?: any;
+ // Go type: ServiceAccountTokenProjection
+ serviceAccountToken?: any;
+ // Go type: ClusterTrustBundleProjection
+ clusterTrustBundle?: any;
+
+ static createFrom(source: any = {}) {
+ return new VolumeProjection(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.secret = this.convertValues(source["secret"], null);
+ this.downwardAPI = this.convertValues(source["downwardAPI"], null);
+ this.configMap = this.convertValues(source["configMap"], null);
+ this.serviceAccountToken = this.convertValues(source["serviceAccountToken"], null);
+ this.clusterTrustBundle = this.convertValues(source["clusterTrustBundle"], null);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class ProjectedVolumeSource {
+ sources: VolumeProjection[];
+ defaultMode?: number;
+
+ static createFrom(source: any = {}) {
+ return new ProjectedVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.sources = this.convertValues(source["sources"], VolumeProjection);
+ this.defaultMode = source["defaultMode"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class PhotonPersistentDiskVolumeSource {
+ pdID: string;
+ fsType?: string;
+
+ static createFrom(source: any = {}) {
+ return new PhotonPersistentDiskVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.pdID = source["pdID"];
+ this.fsType = source["fsType"];
+ }
+ }
+ export class AzureDiskVolumeSource {
+ diskName: string;
+ diskURI: string;
+ cachingMode?: string;
+ fsType?: string;
+ readOnly?: boolean;
+ kind?: string;
+
+ static createFrom(source: any = {}) {
+ return new AzureDiskVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.diskName = source["diskName"];
+ this.diskURI = source["diskURI"];
+ this.cachingMode = source["cachingMode"];
+ this.fsType = source["fsType"];
+ this.readOnly = source["readOnly"];
+ this.kind = source["kind"];
+ }
+ }
+ export class QuobyteVolumeSource {
+ registry: string;
+ volume: string;
+ readOnly?: boolean;
+ user?: string;
+ group?: string;
+ tenant?: string;
+
+ static createFrom(source: any = {}) {
+ return new QuobyteVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.registry = source["registry"];
+ this.volume = source["volume"];
+ this.readOnly = source["readOnly"];
+ this.user = source["user"];
+ this.group = source["group"];
+ this.tenant = source["tenant"];
+ }
+ }
+ export class VsphereVirtualDiskVolumeSource {
+ volumePath: string;
+ fsType?: string;
+ storagePolicyName?: string;
+ storagePolicyID?: string;
+
+ static createFrom(source: any = {}) {
+ return new VsphereVirtualDiskVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.volumePath = source["volumePath"];
+ this.fsType = source["fsType"];
+ this.storagePolicyName = source["storagePolicyName"];
+ this.storagePolicyID = source["storagePolicyID"];
+ }
+ }
+ export class ConfigMapVolumeSource {
+ name?: string;
+ items?: KeyToPath[];
+ defaultMode?: number;
+ optional?: boolean;
+
+ static createFrom(source: any = {}) {
+ return new ConfigMapVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.items = this.convertValues(source["items"], KeyToPath);
+ this.defaultMode = source["defaultMode"];
+ this.optional = source["optional"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class AzureFileVolumeSource {
+ secretName: string;
+ shareName: string;
+ readOnly?: boolean;
+
+ static createFrom(source: any = {}) {
+ return new AzureFileVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.secretName = source["secretName"];
+ this.shareName = source["shareName"];
+ this.readOnly = source["readOnly"];
+ }
+ }
+ export class FCVolumeSource {
+ targetWWNs?: string[];
+ lun?: number;
+ fsType?: string;
+ readOnly?: boolean;
+ wwids?: string[];
+
+ static createFrom(source: any = {}) {
+ return new FCVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.targetWWNs = source["targetWWNs"];
+ this.lun = source["lun"];
+ this.fsType = source["fsType"];
+ this.readOnly = source["readOnly"];
+ this.wwids = source["wwids"];
+ }
+ }
+ export class DownwardAPIVolumeFile {
+ path: string;
+ fieldRef?: ObjectFieldSelector;
+ resourceFieldRef?: ResourceFieldSelector;
+ mode?: number;
+
+ static createFrom(source: any = {}) {
+ return new DownwardAPIVolumeFile(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.path = source["path"];
+ this.fieldRef = this.convertValues(source["fieldRef"], ObjectFieldSelector);
+ this.resourceFieldRef = this.convertValues(source["resourceFieldRef"], ResourceFieldSelector);
+ this.mode = source["mode"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class DownwardAPIVolumeSource {
+ items?: DownwardAPIVolumeFile[];
+ defaultMode?: number;
+
+ static createFrom(source: any = {}) {
+ return new DownwardAPIVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.items = this.convertValues(source["items"], DownwardAPIVolumeFile);
+ this.defaultMode = source["defaultMode"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class FlockerVolumeSource {
+ datasetName?: string;
+ datasetUUID?: string;
+
+ static createFrom(source: any = {}) {
+ return new FlockerVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.datasetName = source["datasetName"];
+ this.datasetUUID = source["datasetUUID"];
+ }
+ }
+ export class CephFSVolumeSource {
+ monitors: string[];
+ path?: string;
+ user?: string;
+ secretFile?: string;
+ secretRef?: LocalObjectReference;
+ readOnly?: boolean;
+
+ static createFrom(source: any = {}) {
+ return new CephFSVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.monitors = source["monitors"];
+ this.path = source["path"];
+ this.user = source["user"];
+ this.secretFile = source["secretFile"];
+ this.secretRef = this.convertValues(source["secretRef"], LocalObjectReference);
+ this.readOnly = source["readOnly"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class CinderVolumeSource {
+ volumeID: string;
+ fsType?: string;
+ readOnly?: boolean;
+ secretRef?: LocalObjectReference;
+
+ static createFrom(source: any = {}) {
+ return new CinderVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.volumeID = source["volumeID"];
+ this.fsType = source["fsType"];
+ this.readOnly = source["readOnly"];
+ this.secretRef = this.convertValues(source["secretRef"], LocalObjectReference);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class FlexVolumeSource {
+ driver: string;
+ fsType?: string;
+ secretRef?: LocalObjectReference;
+ readOnly?: boolean;
+ options?: Record<string, string>;
+
+ static createFrom(source: any = {}) {
+ return new FlexVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.driver = source["driver"];
+ this.fsType = source["fsType"];
+ this.secretRef = this.convertValues(source["secretRef"], LocalObjectReference);
+ this.readOnly = source["readOnly"];
+ this.options = source["options"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class RBDVolumeSource {
+ monitors: string[];
+ image: string;
+ fsType?: string;
+ pool?: string;
+ user?: string;
+ keyring?: string;
+ secretRef?: LocalObjectReference;
+ readOnly?: boolean;
+
+ static createFrom(source: any = {}) {
+ return new RBDVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.monitors = source["monitors"];
+ this.image = source["image"];
+ this.fsType = source["fsType"];
+ this.pool = source["pool"];
+ this.user = source["user"];
+ this.keyring = source["keyring"];
+ this.secretRef = this.convertValues(source["secretRef"], LocalObjectReference);
+ this.readOnly = source["readOnly"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class PersistentVolumeClaimVolumeSource {
+ claimName: string;
+ readOnly?: boolean;
+
+ static createFrom(source: any = {}) {
+ return new PersistentVolumeClaimVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.claimName = source["claimName"];
+ this.readOnly = source["readOnly"];
+ }
+ }
+ export class GlusterfsVolumeSource {
+ endpoints: string;
+ path: string;
+ readOnly?: boolean;
+
+ static createFrom(source: any = {}) {
+ return new GlusterfsVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.endpoints = source["endpoints"];
+ this.path = source["path"];
+ this.readOnly = source["readOnly"];
+ }
+ }
+ export class LocalObjectReference {
+ name?: string;
+
+ static createFrom(source: any = {}) {
+ return new LocalObjectReference(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ }
+ }
+ export class ISCSIVolumeSource {
+ targetPortal: string;
+ iqn: string;
+ lun: number;
+ iscsiInterface?: string;
+ fsType?: string;
+ readOnly?: boolean;
+ portals?: string[];
+ chapAuthDiscovery?: boolean;
+ chapAuthSession?: boolean;
+ secretRef?: LocalObjectReference;
+ initiatorName?: string;
+
+ static createFrom(source: any = {}) {
+ return new ISCSIVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.targetPortal = source["targetPortal"];
+ this.iqn = source["iqn"];
+ this.lun = source["lun"];
+ this.iscsiInterface = source["iscsiInterface"];
+ this.fsType = source["fsType"];
+ this.readOnly = source["readOnly"];
+ this.portals = source["portals"];
+ this.chapAuthDiscovery = source["chapAuthDiscovery"];
+ this.chapAuthSession = source["chapAuthSession"];
+ this.secretRef = this.convertValues(source["secretRef"], LocalObjectReference);
+ this.initiatorName = source["initiatorName"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class NFSVolumeSource {
+ server: string;
+ path: string;
+ readOnly?: boolean;
+
+ static createFrom(source: any = {}) {
+ return new NFSVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.server = source["server"];
+ this.path = source["path"];
+ this.readOnly = source["readOnly"];
+ }
+ }
+ export class KeyToPath {
+ key: string;
+ path: string;
+ mode?: number;
+
+ static createFrom(source: any = {}) {
+ return new KeyToPath(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.key = source["key"];
+ this.path = source["path"];
+ this.mode = source["mode"];
+ }
+ }
+ export class SecretVolumeSource {
+ secretName?: string;
+ items?: KeyToPath[];
+ defaultMode?: number;
+ optional?: boolean;
+
+ static createFrom(source: any = {}) {
+ return new SecretVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.secretName = source["secretName"];
+ this.items = this.convertValues(source["items"], KeyToPath);
+ this.defaultMode = source["defaultMode"];
+ this.optional = source["optional"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class GitRepoVolumeSource {
+ repository: string;
+ revision?: string;
+ directory?: string;
+
+ static createFrom(source: any = {}) {
+ return new GitRepoVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.repository = source["repository"];
+ this.revision = source["revision"];
+ this.directory = source["directory"];
+ }
+ }
+ export class AWSElasticBlockStoreVolumeSource {
+ volumeID: string;
+ fsType?: string;
+ partition?: number;
+ readOnly?: boolean;
+
+ static createFrom(source: any = {}) {
+ return new AWSElasticBlockStoreVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.volumeID = source["volumeID"];
+ this.fsType = source["fsType"];
+ this.partition = source["partition"];
+ this.readOnly = source["readOnly"];
+ }
+ }
+ export class GCEPersistentDiskVolumeSource {
+ pdName: string;
+ fsType?: string;
+ partition?: number;
+ readOnly?: boolean;
+
+ static createFrom(source: any = {}) {
+ return new GCEPersistentDiskVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.pdName = source["pdName"];
+ this.fsType = source["fsType"];
+ this.partition = source["partition"];
+ this.readOnly = source["readOnly"];
+ }
+ }
+ export class EmptyDirVolumeSource {
+ medium?: string;
+ sizeLimit?: resource.Quantity;
+
+ static createFrom(source: any = {}) {
+ return new EmptyDirVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.medium = source["medium"];
+ this.sizeLimit = this.convertValues(source["sizeLimit"], resource.Quantity);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class HostPathVolumeSource {
+ path: string;
+ type?: string;
+
+ static createFrom(source: any = {}) {
+ return new HostPathVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.path = source["path"];
+ this.type = source["type"];
+ }
+ }
+ export class Volume {
+ name: string;
+ // Go type: HostPathVolumeSource
+ hostPath?: any;
+ // Go type: EmptyDirVolumeSource
+ emptyDir?: any;
+ // Go type: GCEPersistentDiskVolumeSource
+ gcePersistentDisk?: any;
+ // Go type: AWSElasticBlockStoreVolumeSource
+ awsElasticBlockStore?: any;
+ // Go type: GitRepoVolumeSource
+ gitRepo?: any;
+ // Go type: SecretVolumeSource
+ secret?: any;
+ // Go type: NFSVolumeSource
+ nfs?: any;
+ // Go type: ISCSIVolumeSource
+ iscsi?: any;
+ // Go type: GlusterfsVolumeSource
+ glusterfs?: any;
+ // Go type: PersistentVolumeClaimVolumeSource
+ persistentVolumeClaim?: any;
+ // Go type: RBDVolumeSource
+ rbd?: any;
+ // Go type: FlexVolumeSource
+ flexVolume?: any;
+ // Go type: CinderVolumeSource
+ cinder?: any;
+ // Go type: CephFSVolumeSource
+ cephfs?: any;
+ // Go type: FlockerVolumeSource
+ flocker?: any;
+ // Go type: DownwardAPIVolumeSource
+ downwardAPI?: any;
+ // Go type: FCVolumeSource
+ fc?: any;
+ // Go type: AzureFileVolumeSource
+ azureFile?: any;
+ // Go type: ConfigMapVolumeSource
+ configMap?: any;
+ // Go type: VsphereVirtualDiskVolumeSource
+ vsphereVolume?: any;
+ // Go type: QuobyteVolumeSource
+ quobyte?: any;
+ // Go type: AzureDiskVolumeSource
+ azureDisk?: any;
+ // Go type: PhotonPersistentDiskVolumeSource
+ photonPersistentDisk?: any;
+ // Go type: ProjectedVolumeSource
+ projected?: any;
+ // Go type: PortworxVolumeSource
+ portworxVolume?: any;
+ // Go type: ScaleIOVolumeSource
+ scaleIO?: any;
+ // Go type: StorageOSVolumeSource
+ storageos?: any;
+ // Go type: CSIVolumeSource
+ csi?: any;
+ // Go type: EphemeralVolumeSource
+ ephemeral?: any;
+ // Go type: ImageVolumeSource
+ image?: any;
+
+ static createFrom(source: any = {}) {
+ return new Volume(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.hostPath = this.convertValues(source["hostPath"], null);
+ this.emptyDir = this.convertValues(source["emptyDir"], null);
+ this.gcePersistentDisk = this.convertValues(source["gcePersistentDisk"], null);
+ this.awsElasticBlockStore = this.convertValues(source["awsElasticBlockStore"], null);
+ this.gitRepo = this.convertValues(source["gitRepo"], null);
+ this.secret = this.convertValues(source["secret"], null);
+ this.nfs = this.convertValues(source["nfs"], null);
+ this.iscsi = this.convertValues(source["iscsi"], null);
+ this.glusterfs = this.convertValues(source["glusterfs"], null);
+ this.persistentVolumeClaim = this.convertValues(source["persistentVolumeClaim"], null);
+ this.rbd = this.convertValues(source["rbd"], null);
+ this.flexVolume = this.convertValues(source["flexVolume"], null);
+ this.cinder = this.convertValues(source["cinder"], null);
+ this.cephfs = this.convertValues(source["cephfs"], null);
+ this.flocker = this.convertValues(source["flocker"], null);
+ this.downwardAPI = this.convertValues(source["downwardAPI"], null);
+ this.fc = this.convertValues(source["fc"], null);
+ this.azureFile = this.convertValues(source["azureFile"], null);
+ this.configMap = this.convertValues(source["configMap"], null);
+ this.vsphereVolume = this.convertValues(source["vsphereVolume"], null);
+ this.quobyte = this.convertValues(source["quobyte"], null);
+ this.azureDisk = this.convertValues(source["azureDisk"], null);
+ this.photonPersistentDisk = this.convertValues(source["photonPersistentDisk"], null);
+ this.projected = this.convertValues(source["projected"], null);
+ this.portworxVolume = this.convertValues(source["portworxVolume"], null);
+ this.scaleIO = this.convertValues(source["scaleIO"], null);
+ this.storageos = this.convertValues(source["storageos"], null);
+ this.csi = this.convertValues(source["csi"], null);
+ this.ephemeral = this.convertValues(source["ephemeral"], null);
+ this.image = this.convertValues(source["image"], null);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class PodSpec {
+ volumes?: Volume[];
+ initContainers?: Container[];
+ containers: Container[];
+ ephemeralContainers?: EphemeralContainer[];
+ restartPolicy?: string;
+ terminationGracePeriodSeconds?: number;
+ activeDeadlineSeconds?: number;
+ dnsPolicy?: string;
+ nodeSelector?: Record<string, string>;
+ serviceAccountName?: string;
+ serviceAccount?: string;
+ automountServiceAccountToken?: boolean;
+ nodeName?: string;
+ hostNetwork?: boolean;
+ hostPID?: boolean;
+ hostIPC?: boolean;
+ shareProcessNamespace?: boolean;
+ securityContext?: PodSecurityContext;
+ imagePullSecrets?: LocalObjectReference[];
+ hostname?: string;
+ subdomain?: string;
+ affinity?: Affinity;
+ schedulerName?: string;
+ tolerations?: Toleration[];
+ hostAliases?: HostAlias[];
+ priorityClassName?: string;
+ priority?: number;
+ dnsConfig?: PodDNSConfig;
+ readinessGates?: PodReadinessGate[];
+ runtimeClassName?: string;
+ enableServiceLinks?: boolean;
+ preemptionPolicy?: string;
+ overhead?: Record<string, resource.Quantity>;
+ topologySpreadConstraints?: TopologySpreadConstraint[];
+ setHostnameAsFQDN?: boolean;
+ os?: PodOS;
+ hostUsers?: boolean;
+ schedulingGates?: PodSchedulingGate[];
+ resourceClaims?: PodResourceClaim[];
+ resources?: ResourceRequirements;
+
+ static createFrom(source: any = {}) {
+ return new PodSpec(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.volumes = this.convertValues(source["volumes"], Volume);
+ this.initContainers = this.convertValues(source["initContainers"], Container);
+ this.containers = this.convertValues(source["containers"], Container);
+ this.ephemeralContainers = this.convertValues(source["ephemeralContainers"], EphemeralContainer);
+ this.restartPolicy = source["restartPolicy"];
+ this.terminationGracePeriodSeconds = source["terminationGracePeriodSeconds"];
+ this.activeDeadlineSeconds = source["activeDeadlineSeconds"];
+ this.dnsPolicy = source["dnsPolicy"];
+ this.nodeSelector = source["nodeSelector"];
+ this.serviceAccountName = source["serviceAccountName"];
+ this.serviceAccount = source["serviceAccount"];
+ this.automountServiceAccountToken = source["automountServiceAccountToken"];
+ this.nodeName = source["nodeName"];
+ this.hostNetwork = source["hostNetwork"];
+ this.hostPID = source["hostPID"];
+ this.hostIPC = source["hostIPC"];
+ this.shareProcessNamespace = source["shareProcessNamespace"];
+ this.securityContext = this.convertValues(source["securityContext"], PodSecurityContext);
+ this.imagePullSecrets = this.convertValues(source["imagePullSecrets"], LocalObjectReference);
+ this.hostname = source["hostname"];
+ this.subdomain = source["subdomain"];
+ this.affinity = this.convertValues(source["affinity"], Affinity);
+ this.schedulerName = source["schedulerName"];
+ this.tolerations = this.convertValues(source["tolerations"], Toleration);
+ this.hostAliases = this.convertValues(source["hostAliases"], HostAlias);
+ this.priorityClassName = source["priorityClassName"];
+ this.priority = source["priority"];
+ this.dnsConfig = this.convertValues(source["dnsConfig"], PodDNSConfig);
+ this.readinessGates = this.convertValues(source["readinessGates"], PodReadinessGate);
+ this.runtimeClassName = source["runtimeClassName"];
+ this.enableServiceLinks = source["enableServiceLinks"];
+ this.preemptionPolicy = source["preemptionPolicy"];
+ this.overhead = this.convertValues(source["overhead"], resource.Quantity, true);
+ this.topologySpreadConstraints = this.convertValues(source["topologySpreadConstraints"], TopologySpreadConstraint);
+ this.setHostnameAsFQDN = source["setHostnameAsFQDN"];
+ this.os = this.convertValues(source["os"], PodOS);
+ this.hostUsers = source["hostUsers"];
+ this.schedulingGates = this.convertValues(source["schedulingGates"], PodSchedulingGate);
+ this.resourceClaims = this.convertValues(source["resourceClaims"], PodResourceClaim);
+ this.resources = this.convertValues(source["resources"], ResourceRequirements);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class PodTemplateSpec {
+ name?: string;
+ generateName?: string;
+ namespace?: string;
+ selfLink?: string;
+ uid?: string;
+ resourceVersion?: string;
+ generation?: number;
+ creationTimestamp?: Time;
+ deletionTimestamp?: Time;
+ deletionGracePeriodSeconds?: number;
+ labels?: Record<string, string>;
+ annotations?: Record<string, string>;
+ ownerReferences?: OwnerReference[];
+ finalizers?: string[];
+ managedFields?: ManagedFieldsEntry[];
+ spec?: PodSpec;
+
+ static createFrom(source: any = {}) {
+ return new PodTemplateSpec(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.generateName = source["generateName"];
+ this.namespace = source["namespace"];
+ this.selfLink = source["selfLink"];
+ this.uid = source["uid"];
+ this.resourceVersion = source["resourceVersion"];
+ this.generation = source["generation"];
+ this.creationTimestamp = this.convertValues(source["creationTimestamp"], Time);
+ this.deletionTimestamp = this.convertValues(source["deletionTimestamp"], Time);
+ this.deletionGracePeriodSeconds = source["deletionGracePeriodSeconds"];
+ this.labels = source["labels"];
+ this.annotations = source["annotations"];
+ this.ownerReferences = this.convertValues(source["ownerReferences"], OwnerReference);
+ this.finalizers = source["finalizers"];
+ this.managedFields = this.convertValues(source["managedFields"], ManagedFieldsEntry);
+ this.spec = this.convertValues(source["spec"], PodSpec);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class DeploymentSpec {
+ replicas?: number;
+ selector?: LabelSelector;
+ template: PodTemplateSpec;
+ strategy?: DeploymentStrategy;
+ minReadySeconds?: number;
+ revisionHistoryLimit?: number;
+ paused?: boolean;
+ progressDeadlineSeconds?: number;
+
+ static createFrom(source: any = {}) {
+ return new DeploymentSpec(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.replicas = source["replicas"];
+ this.selector = this.convertValues(source["selector"], LabelSelector);
+ this.template = this.convertValues(source["template"], PodTemplateSpec);
+ this.strategy = this.convertValues(source["strategy"], DeploymentStrategy);
+ this.minReadySeconds = source["minReadySeconds"];
+ this.revisionHistoryLimit = source["revisionHistoryLimit"];
+ this.paused = source["paused"];
+ this.progressDeadlineSeconds = source["progressDeadlineSeconds"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class Deployment {
+ kind?: string;
+ apiVersion?: string;
+ name?: string;
+ generateName?: string;
+ namespace?: string;
+ selfLink?: string;
+ uid?: string;
+ resourceVersion?: string;
+ generation?: number;
+ creationTimestamp?: Time;
+ deletionTimestamp?: Time;
+ deletionGracePeriodSeconds?: number;
+ labels?: Record<string, string>;
+ annotations?: Record<string, string>;
+ ownerReferences?: OwnerReference[];
+ finalizers?: string[];
+ managedFields?: ManagedFieldsEntry[];
+ spec?: DeploymentSpec;
+ status?: DeploymentStatus;
+
+ static createFrom(source: any = {}) {
+ return new Deployment(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.kind = source["kind"];
+ this.apiVersion = source["apiVersion"];
+ this.name = source["name"];
+ this.generateName = source["generateName"];
+ this.namespace = source["namespace"];
+ this.selfLink = source["selfLink"];
+ this.uid = source["uid"];
+ this.resourceVersion = source["resourceVersion"];
+ this.generation = source["generation"];
+ this.creationTimestamp = this.convertValues(source["creationTimestamp"], Time);
+ this.deletionTimestamp = this.convertValues(source["deletionTimestamp"], Time);
+ this.deletionGracePeriodSeconds = source["deletionGracePeriodSeconds"];
+ this.labels = source["labels"];
+ this.annotations = source["annotations"];
+ this.ownerReferences = this.convertValues(source["ownerReferences"], OwnerReference);
+ this.finalizers = source["finalizers"];
+ this.managedFields = this.convertValues(source["managedFields"], ManagedFieldsEntry);
+ this.spec = this.convertValues(source["spec"], DeploymentSpec);
+ this.status = this.convertValues(source["status"], DeploymentStatus);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+ export class HostIP {
+ ip: string;
+
+ static createFrom(source: any = {}) {
+ return new HostIP(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.ip = source["ip"];
+ }
+ }
+ export class IngressPortStatus {
+ port: number;
+ protocol: string;
+ error?: string;
+
+ static createFrom(source: any = {}) {
+ return new IngressPortStatus(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.port = source["port"];
+ this.protocol = source["protocol"];
+ this.error = source["error"];
+ }
+ }
+ export class IngressLoadBalancerIngress {
+ ip?: string;
+ hostname?: string;
+ ports?: IngressPortStatus[];
+
+ static createFrom(source: any = {}) {
+ return new IngressLoadBalancerIngress(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.ip = source["ip"];
+ this.hostname = source["hostname"];
+ this.ports = this.convertValues(source["ports"], IngressPortStatus);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class IngressLoadBalancerStatus {
+ ingress?: IngressLoadBalancerIngress[];
+
+ static createFrom(source: any = {}) {
+ return new IngressLoadBalancerStatus(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.ingress = this.convertValues(source["ingress"], IngressLoadBalancerIngress);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class IngressStatus {
+ loadBalancer?: IngressLoadBalancerStatus;
+
+ static createFrom(source: any = {}) {
+ return new IngressStatus(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.loadBalancer = this.convertValues(source["loadBalancer"], IngressLoadBalancerStatus);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class HTTPIngressPath {
+ path?: string;
+ pathType?: string;
+ backend: IngressBackend;
+
+ static createFrom(source: any = {}) {
+ return new HTTPIngressPath(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.path = source["path"];
+ this.pathType = source["pathType"];
+ this.backend = this.convertValues(source["backend"], IngressBackend);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class HTTPIngressRuleValue {
+ paths: HTTPIngressPath[];
+
+ static createFrom(source: any = {}) {
+ return new HTTPIngressRuleValue(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.paths = this.convertValues(source["paths"], HTTPIngressPath);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class IngressRule {
+ host?: string;
+ // Go type: HTTPIngressRuleValue
+ http?: any;
+
+ static createFrom(source: any = {}) {
+ return new IngressRule(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.host = source["host"];
+ this.http = this.convertValues(source["http"], null);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class IngressTLS {
+ hosts?: string[];
+ secretName?: string;
+
+ static createFrom(source: any = {}) {
+ return new IngressTLS(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.hosts = source["hosts"];
+ this.secretName = source["secretName"];
+ }
+ }
+ export class ServiceBackendPort {
+ name?: string;
+ number?: number;
+
+ static createFrom(source: any = {}) {
+ return new ServiceBackendPort(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.number = source["number"];
+ }
+ }
+ export class IngressServiceBackend {
+ name: string;
+ port?: ServiceBackendPort;
+
+ static createFrom(source: any = {}) {
+ return new IngressServiceBackend(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.port = this.convertValues(source["port"], ServiceBackendPort);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class IngressBackend {
+ service?: IngressServiceBackend;
+ resource?: TypedLocalObjectReference;
+
+ static createFrom(source: any = {}) {
+ return new IngressBackend(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.service = this.convertValues(source["service"], IngressServiceBackend);
+ this.resource = this.convertValues(source["resource"], TypedLocalObjectReference);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class IngressSpec {
+ ingressClassName?: string;
+ defaultBackend?: IngressBackend;
+ tls?: IngressTLS[];
+ rules?: IngressRule[];
+
+ static createFrom(source: any = {}) {
+ return new IngressSpec(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.ingressClassName = source["ingressClassName"];
+ this.defaultBackend = this.convertValues(source["defaultBackend"], IngressBackend);
+ this.tls = this.convertValues(source["tls"], IngressTLS);
+ this.rules = this.convertValues(source["rules"], IngressRule);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class Ingress {
+ kind?: string;
+ apiVersion?: string;
+ name?: string;
+ generateName?: string;
+ namespace?: string;
+ selfLink?: string;
+ uid?: string;
+ resourceVersion?: string;
+ generation?: number;
+ creationTimestamp?: Time;
+ deletionTimestamp?: Time;
+ deletionGracePeriodSeconds?: number;
+ labels?: Record<string, string>;
+ annotations?: Record<string, string>;
+ ownerReferences?: OwnerReference[];
+ finalizers?: string[];
+ managedFields?: ManagedFieldsEntry[];
+ spec?: IngressSpec;
+ status?: IngressStatus;
+
+ static createFrom(source: any = {}) {
+ return new Ingress(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.kind = source["kind"];
+ this.apiVersion = source["apiVersion"];
+ this.name = source["name"];
+ this.generateName = source["generateName"];
+ this.namespace = source["namespace"];
+ this.selfLink = source["selfLink"];
+ this.uid = source["uid"];
+ this.resourceVersion = source["resourceVersion"];
+ this.generation = source["generation"];
+ this.creationTimestamp = this.convertValues(source["creationTimestamp"], Time);
+ this.deletionTimestamp = this.convertValues(source["deletionTimestamp"], Time);
+ this.deletionGracePeriodSeconds = source["deletionGracePeriodSeconds"];
+ this.labels = source["labels"];
+ this.annotations = source["annotations"];
+ this.ownerReferences = this.convertValues(source["ownerReferences"], OwnerReference);
+ this.finalizers = source["finalizers"];
+ this.managedFields = this.convertValues(source["managedFields"], ManagedFieldsEntry);
+ this.spec = this.convertValues(source["spec"], IngressSpec);
+ this.status = this.convertValues(source["status"], IngressStatus);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ export class ModifyVolumeStatus {
+ targetVolumeAttributesClassName?: string;
+ status: string;
+
+ static createFrom(source: any = {}) {
+ return new ModifyVolumeStatus(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.targetVolumeAttributesClassName = source["targetVolumeAttributesClassName"];
+ this.status = source["status"];
+ }
+ }
+ export class NamespaceCondition {
+ type: string;
+ status: string;
+ lastTransitionTime?: Time;
+ reason?: string;
+ message?: string;
+
+ static createFrom(source: any = {}) {
+ return new NamespaceCondition(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.type = source["type"];
+ this.status = source["status"];
+ this.lastTransitionTime = this.convertValues(source["lastTransitionTime"], Time);
+ this.reason = source["reason"];
+ this.message = source["message"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class NamespaceStatus {
+ phase?: string;
+ conditions?: NamespaceCondition[];
+
+ static createFrom(source: any = {}) {
+ return new NamespaceStatus(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.phase = source["phase"];
+ this.conditions = this.convertValues(source["conditions"], NamespaceCondition);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class NamespaceSpec {
+ finalizers?: string[];
+
+ static createFrom(source: any = {}) {
+ return new NamespaceSpec(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.finalizers = source["finalizers"];
+ }
+ }
+ export class Namespace {
+ kind?: string;
+ apiVersion?: string;
+ name?: string;
+ generateName?: string;
+ namespace?: string;
+ selfLink?: string;
+ uid?: string;
+ resourceVersion?: string;
+ generation?: number;
+ creationTimestamp?: Time;
+ deletionTimestamp?: Time;
+ deletionGracePeriodSeconds?: number;
+ labels?: Record<string, string>;
+ annotations?: Record<string, string>;
+ ownerReferences?: OwnerReference[];
+ finalizers?: string[];
+ managedFields?: ManagedFieldsEntry[];
+ spec?: NamespaceSpec;
+ status?: NamespaceStatus;
+
+ static createFrom(source: any = {}) {
+ return new Namespace(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.kind = source["kind"];
+ this.apiVersion = source["apiVersion"];
+ this.name = source["name"];
+ this.generateName = source["generateName"];
+ this.namespace = source["namespace"];
+ this.selfLink = source["selfLink"];
+ this.uid = source["uid"];
+ this.resourceVersion = source["resourceVersion"];
+ this.generation = source["generation"];
+ this.creationTimestamp = this.convertValues(source["creationTimestamp"], Time);
+ this.deletionTimestamp = this.convertValues(source["deletionTimestamp"], Time);
+ this.deletionGracePeriodSeconds = source["deletionGracePeriodSeconds"];
+ this.labels = source["labels"];
+ this.annotations = source["annotations"];
+ this.ownerReferences = this.convertValues(source["ownerReferences"], OwnerReference);
+ this.finalizers = source["finalizers"];
+ this.managedFields = this.convertValues(source["managedFields"], ManagedFieldsEntry);
+ this.spec = this.convertValues(source["spec"], NamespaceSpec);
+ this.status = this.convertValues(source["status"], NamespaceStatus);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+
+
+
+
+
+
+
+
+ export class ObjectReference {
+ kind?: string;
+ namespace?: string;
+ name?: string;
+ uid?: string;
+ apiVersion?: string;
+ resourceVersion?: string;
+ fieldPath?: string;
+
+ static createFrom(source: any = {}) {
+ return new ObjectReference(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.kind = source["kind"];
+ this.namespace = source["namespace"];
+ this.name = source["name"];
+ this.uid = source["uid"];
+ this.apiVersion = source["apiVersion"];
+ this.resourceVersion = source["resourceVersion"];
+ this.fieldPath = source["fieldPath"];
+ }
+ }
+ export class PersistentVolumeStatus {
+ phase?: string;
+ message?: string;
+ reason?: string;
+ lastPhaseTransitionTime?: Time;
+
+ static createFrom(source: any = {}) {
+ return new PersistentVolumeStatus(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.phase = source["phase"];
+ this.message = source["message"];
+ this.reason = source["reason"];
+ this.lastPhaseTransitionTime = this.convertValues(source["lastPhaseTransitionTime"], Time);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class VolumeNodeAffinity {
+ required?: NodeSelector;
+
+ static createFrom(source: any = {}) {
+ return new VolumeNodeAffinity(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.required = this.convertValues(source["required"], NodeSelector);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class CSIPersistentVolumeSource {
+ driver: string;
+ volumeHandle: string;
+ readOnly?: boolean;
+ fsType?: string;
+ volumeAttributes?: Record<string, string>;
+ // Go type: SecretReference
+ controllerPublishSecretRef?: any;
+ // Go type: SecretReference
+ nodeStageSecretRef?: any;
+ // Go type: SecretReference
+ nodePublishSecretRef?: any;
+ // Go type: SecretReference
+ controllerExpandSecretRef?: any;
+ // Go type: SecretReference
+ nodeExpandSecretRef?: any;
+
+ static createFrom(source: any = {}) {
+ return new CSIPersistentVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.driver = source["driver"];
+ this.volumeHandle = source["volumeHandle"];
+ this.readOnly = source["readOnly"];
+ this.fsType = source["fsType"];
+ this.volumeAttributes = source["volumeAttributes"];
+ this.controllerPublishSecretRef = this.convertValues(source["controllerPublishSecretRef"], null);
+ this.nodeStageSecretRef = this.convertValues(source["nodeStageSecretRef"], null);
+ this.nodePublishSecretRef = this.convertValues(source["nodePublishSecretRef"], null);
+ this.controllerExpandSecretRef = this.convertValues(source["controllerExpandSecretRef"], null);
+ this.nodeExpandSecretRef = this.convertValues(source["nodeExpandSecretRef"], null);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class StorageOSPersistentVolumeSource {
+ volumeName?: string;
+ volumeNamespace?: string;
+ fsType?: string;
+ readOnly?: boolean;
+ secretRef?: ObjectReference;
+
+ static createFrom(source: any = {}) {
+ return new StorageOSPersistentVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.volumeName = source["volumeName"];
+ this.volumeNamespace = source["volumeNamespace"];
+ this.fsType = source["fsType"];
+ this.readOnly = source["readOnly"];
+ this.secretRef = this.convertValues(source["secretRef"], ObjectReference);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class LocalVolumeSource {
+ path: string;
+ fsType?: string;
+
+ static createFrom(source: any = {}) {
+ return new LocalVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.path = source["path"];
+ this.fsType = source["fsType"];
+ }
+ }
+ export class ScaleIOPersistentVolumeSource {
+ gateway: string;
+ system: string;
+ // Go type: SecretReference
+ secretRef?: any;
+ sslEnabled?: boolean;
+ protectionDomain?: string;
+ storagePool?: string;
+ storageMode?: string;
+ volumeName?: string;
+ fsType?: string;
+ readOnly?: boolean;
+
+ static createFrom(source: any = {}) {
+ return new ScaleIOPersistentVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.gateway = source["gateway"];
+ this.system = source["system"];
+ this.secretRef = this.convertValues(source["secretRef"], null);
+ this.sslEnabled = source["sslEnabled"];
+ this.protectionDomain = source["protectionDomain"];
+ this.storagePool = source["storagePool"];
+ this.storageMode = source["storageMode"];
+ this.volumeName = source["volumeName"];
+ this.fsType = source["fsType"];
+ this.readOnly = source["readOnly"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class AzureFilePersistentVolumeSource {
+ secretName: string;
+ shareName: string;
+ readOnly?: boolean;
+ secretNamespace?: string;
+
+ static createFrom(source: any = {}) {
+ return new AzureFilePersistentVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.secretName = source["secretName"];
+ this.shareName = source["shareName"];
+ this.readOnly = source["readOnly"];
+ this.secretNamespace = source["secretNamespace"];
+ }
+ }
+ export class FlexPersistentVolumeSource {
+ driver: string;
+ fsType?: string;
+ // Go type: SecretReference
+ secretRef?: any;
+ readOnly?: boolean;
+ options?: Record<string, string>;
+
+ static createFrom(source: any = {}) {
+ return new FlexPersistentVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.driver = source["driver"];
+ this.fsType = source["fsType"];
+ this.secretRef = this.convertValues(source["secretRef"], null);
+ this.readOnly = source["readOnly"];
+ this.options = source["options"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class CephFSPersistentVolumeSource {
+ monitors: string[];
+ path?: string;
+ user?: string;
+ secretFile?: string;
+ // Go type: SecretReference
+ secretRef?: any;
+ readOnly?: boolean;
+
+ static createFrom(source: any = {}) {
+ return new CephFSPersistentVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.monitors = source["monitors"];
+ this.path = source["path"];
+ this.user = source["user"];
+ this.secretFile = source["secretFile"];
+ this.secretRef = this.convertValues(source["secretRef"], null);
+ this.readOnly = source["readOnly"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class CinderPersistentVolumeSource {
+ volumeID: string;
+ fsType?: string;
+ readOnly?: boolean;
+ // Go type: SecretReference
+ secretRef?: any;
+
+ static createFrom(source: any = {}) {
+ return new CinderPersistentVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.volumeID = source["volumeID"];
+ this.fsType = source["fsType"];
+ this.readOnly = source["readOnly"];
+ this.secretRef = this.convertValues(source["secretRef"], null);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class ISCSIPersistentVolumeSource {
+ targetPortal: string;
+ iqn: string;
+ lun: number;
+ iscsiInterface?: string;
+ fsType?: string;
+ readOnly?: boolean;
+ portals?: string[];
+ chapAuthDiscovery?: boolean;
+ chapAuthSession?: boolean;
+ // Go type: SecretReference
+ secretRef?: any;
+ initiatorName?: string;
+
+ static createFrom(source: any = {}) {
+ return new ISCSIPersistentVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.targetPortal = source["targetPortal"];
+ this.iqn = source["iqn"];
+ this.lun = source["lun"];
+ this.iscsiInterface = source["iscsiInterface"];
+ this.fsType = source["fsType"];
+ this.readOnly = source["readOnly"];
+ this.portals = source["portals"];
+ this.chapAuthDiscovery = source["chapAuthDiscovery"];
+ this.chapAuthSession = source["chapAuthSession"];
+ this.secretRef = this.convertValues(source["secretRef"], null);
+ this.initiatorName = source["initiatorName"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class SecretReference {
+ name?: string;
+ namespace?: string;
+
+ static createFrom(source: any = {}) {
+ return new SecretReference(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.namespace = source["namespace"];
+ }
+ }
+ export class RBDPersistentVolumeSource {
+ monitors: string[];
+ image: string;
+ fsType?: string;
+ pool?: string;
+ user?: string;
+ keyring?: string;
+ // Go type: SecretReference
+ secretRef?: any;
+ readOnly?: boolean;
+
+ static createFrom(source: any = {}) {
+ return new RBDPersistentVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.monitors = source["monitors"];
+ this.image = source["image"];
+ this.fsType = source["fsType"];
+ this.pool = source["pool"];
+ this.user = source["user"];
+ this.keyring = source["keyring"];
+ this.secretRef = this.convertValues(source["secretRef"], null);
+ this.readOnly = source["readOnly"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class GlusterfsPersistentVolumeSource {
+ endpoints: string;
+ path: string;
+ readOnly?: boolean;
+ endpointsNamespace?: string;
+
+ static createFrom(source: any = {}) {
+ return new GlusterfsPersistentVolumeSource(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.endpoints = source["endpoints"];
+ this.path = source["path"];
+ this.readOnly = source["readOnly"];
+ this.endpointsNamespace = source["endpointsNamespace"];
+ }
+ }
+ export class PersistentVolumeSpec {
+ capacity?: Record<string, resource.Quantity>;
+ // Go type: GCEPersistentDiskVolumeSource
+ gcePersistentDisk?: any;
+ // Go type: AWSElasticBlockStoreVolumeSource
+ awsElasticBlockStore?: any;
+ // Go type: HostPathVolumeSource
+ hostPath?: any;
+ // Go type: GlusterfsPersistentVolumeSource
+ glusterfs?: any;
+ // Go type: NFSVolumeSource
+ nfs?: any;
+ // Go type: RBDPersistentVolumeSource
+ rbd?: any;
+ // Go type: ISCSIPersistentVolumeSource
+ iscsi?: any;
+ // Go type: CinderPersistentVolumeSource
+ cinder?: any;
+ // Go type: CephFSPersistentVolumeSource
+ cephfs?: any;
+ // Go type: FCVolumeSource
+ fc?: any;
+ // Go type: FlockerVolumeSource
+ flocker?: any;
+ // Go type: FlexPersistentVolumeSource
+ flexVolume?: any;
+ // Go type: AzureFilePersistentVolumeSource
+ azureFile?: any;
+ // Go type: VsphereVirtualDiskVolumeSource
+ vsphereVolume?: any;
+ // Go type: QuobyteVolumeSource
+ quobyte?: any;
+ // Go type: AzureDiskVolumeSource
+ azureDisk?: any;
+ // Go type: PhotonPersistentDiskVolumeSource
+ photonPersistentDisk?: any;
+ // Go type: PortworxVolumeSource
+ portworxVolume?: any;
+ // Go type: ScaleIOPersistentVolumeSource
+ scaleIO?: any;
+ // Go type: LocalVolumeSource
+ local?: any;
+ // Go type: StorageOSPersistentVolumeSource
+ storageos?: any;
+ // Go type: CSIPersistentVolumeSource
+ csi?: any;
+ accessModes?: string[];
+ claimRef?: ObjectReference;
+ persistentVolumeReclaimPolicy?: string;
+ storageClassName?: string;
+ mountOptions?: string[];
+ volumeMode?: string;
+ nodeAffinity?: VolumeNodeAffinity;
+ volumeAttributesClassName?: string;
+
+ static createFrom(source: any = {}) {
+ return new PersistentVolumeSpec(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.capacity = this.convertValues(source["capacity"], resource.Quantity, true);
+ this.gcePersistentDisk = this.convertValues(source["gcePersistentDisk"], null);
+ this.awsElasticBlockStore = this.convertValues(source["awsElasticBlockStore"], null);
+ this.hostPath = this.convertValues(source["hostPath"], null);
+ this.glusterfs = this.convertValues(source["glusterfs"], null);
+ this.nfs = this.convertValues(source["nfs"], null);
+ this.rbd = this.convertValues(source["rbd"], null);
+ this.iscsi = this.convertValues(source["iscsi"], null);
+ this.cinder = this.convertValues(source["cinder"], null);
+ this.cephfs = this.convertValues(source["cephfs"], null);
+ this.fc = this.convertValues(source["fc"], null);
+ this.flocker = this.convertValues(source["flocker"], null);
+ this.flexVolume = this.convertValues(source["flexVolume"], null);
+ this.azureFile = this.convertValues(source["azureFile"], null);
+ this.vsphereVolume = this.convertValues(source["vsphereVolume"], null);
+ this.quobyte = this.convertValues(source["quobyte"], null);
+ this.azureDisk = this.convertValues(source["azureDisk"], null);
+ this.photonPersistentDisk = this.convertValues(source["photonPersistentDisk"], null);
+ this.portworxVolume = this.convertValues(source["portworxVolume"], null);
+ this.scaleIO = this.convertValues(source["scaleIO"], null);
+ this.local = this.convertValues(source["local"], null);
+ this.storageos = this.convertValues(source["storageos"], null);
+ this.csi = this.convertValues(source["csi"], null);
+ this.accessModes = source["accessModes"];
+ this.claimRef = this.convertValues(source["claimRef"], ObjectReference);
+ this.persistentVolumeReclaimPolicy = source["persistentVolumeReclaimPolicy"];
+ this.storageClassName = source["storageClassName"];
+ this.mountOptions = source["mountOptions"];
+ this.volumeMode = source["volumeMode"];
+ this.nodeAffinity = this.convertValues(source["nodeAffinity"], VolumeNodeAffinity);
+ this.volumeAttributesClassName = source["volumeAttributesClassName"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class PersistentVolume {
+ kind?: string;
+ apiVersion?: string;
+ name?: string;
+ generateName?: string;
+ namespace?: string;
+ selfLink?: string;
+ uid?: string;
+ resourceVersion?: string;
+ generation?: number;
+ creationTimestamp?: Time;
+ deletionTimestamp?: Time;
+ deletionGracePeriodSeconds?: number;
+ labels?: Record<string, string>;
+ annotations?: Record<string, string>;
+ ownerReferences?: OwnerReference[];
+ finalizers?: string[];
+ managedFields?: ManagedFieldsEntry[];
+ spec?: PersistentVolumeSpec;
+ status?: PersistentVolumeStatus;
+
+ static createFrom(source: any = {}) {
+ return new PersistentVolume(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.kind = source["kind"];
+ this.apiVersion = source["apiVersion"];
+ this.name = source["name"];
+ this.generateName = source["generateName"];
+ this.namespace = source["namespace"];
+ this.selfLink = source["selfLink"];
+ this.uid = source["uid"];
+ this.resourceVersion = source["resourceVersion"];
+ this.generation = source["generation"];
+ this.creationTimestamp = this.convertValues(source["creationTimestamp"], Time);
+ this.deletionTimestamp = this.convertValues(source["deletionTimestamp"], Time);
+ this.deletionGracePeriodSeconds = source["deletionGracePeriodSeconds"];
+ this.labels = source["labels"];
+ this.annotations = source["annotations"];
+ this.ownerReferences = this.convertValues(source["ownerReferences"], OwnerReference);
+ this.finalizers = source["finalizers"];
+ this.managedFields = this.convertValues(source["managedFields"], ManagedFieldsEntry);
+ this.spec = this.convertValues(source["spec"], PersistentVolumeSpec);
+ this.status = this.convertValues(source["status"], PersistentVolumeStatus);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class PersistentVolumeClaimCondition {
+ type: string;
+ status: string;
+ lastProbeTime?: Time;
+ lastTransitionTime?: Time;
+ reason?: string;
+ message?: string;
+
+ static createFrom(source: any = {}) {
+ return new PersistentVolumeClaimCondition(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.type = source["type"];
+ this.status = source["status"];
+ this.lastProbeTime = this.convertValues(source["lastProbeTime"], Time);
+ this.lastTransitionTime = this.convertValues(source["lastTransitionTime"], Time);
+ this.reason = source["reason"];
+ this.message = source["message"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class PersistentVolumeClaimStatus {
+ phase?: string;
+ accessModes?: string[];
+ capacity?: Record<string, resource.Quantity>;
+ conditions?: PersistentVolumeClaimCondition[];
+ allocatedResources?: Record<string, resource.Quantity>;
+ allocatedResourceStatuses?: Record<string, string>;
+ currentVolumeAttributesClassName?: string;
+ modifyVolumeStatus?: ModifyVolumeStatus;
+
+ static createFrom(source: any = {}) {
+ return new PersistentVolumeClaimStatus(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.phase = source["phase"];
+ this.accessModes = source["accessModes"];
+ this.capacity = this.convertValues(source["capacity"], resource.Quantity, true);
+ this.conditions = this.convertValues(source["conditions"], PersistentVolumeClaimCondition);
+ this.allocatedResources = this.convertValues(source["allocatedResources"], resource.Quantity, true);
+ this.allocatedResourceStatuses = source["allocatedResourceStatuses"];
+ this.currentVolumeAttributesClassName = source["currentVolumeAttributesClassName"];
+ this.modifyVolumeStatus = this.convertValues(source["modifyVolumeStatus"], ModifyVolumeStatus);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class PersistentVolumeClaim {
+ kind?: string;
+ apiVersion?: string;
+ name?: string;
+ generateName?: string;
+ namespace?: string;
+ selfLink?: string;
+ uid?: string;
+ resourceVersion?: string;
+ generation?: number;
+ creationTimestamp?: Time;
+ deletionTimestamp?: Time;
+ deletionGracePeriodSeconds?: number;
+ labels?: Record<string, string>;
+ annotations?: Record<string, string>;
+ ownerReferences?: OwnerReference[];
+ finalizers?: string[];
+ managedFields?: ManagedFieldsEntry[];
+ spec?: PersistentVolumeClaimSpec;
+ status?: PersistentVolumeClaimStatus;
+
+ static createFrom(source: any = {}) {
+ return new PersistentVolumeClaim(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.kind = source["kind"];
+ this.apiVersion = source["apiVersion"];
+ this.name = source["name"];
+ this.generateName = source["generateName"];
+ this.namespace = source["namespace"];
+ this.selfLink = source["selfLink"];
+ this.uid = source["uid"];
+ this.resourceVersion = source["resourceVersion"];
+ this.generation = source["generation"];
+ this.creationTimestamp = this.convertValues(source["creationTimestamp"], Time);
+ this.deletionTimestamp = this.convertValues(source["deletionTimestamp"], Time);
+ this.deletionGracePeriodSeconds = source["deletionGracePeriodSeconds"];
+ this.labels = source["labels"];
+ this.annotations = source["annotations"];
+ this.ownerReferences = this.convertValues(source["ownerReferences"], OwnerReference);
+ this.finalizers = source["finalizers"];
+ this.managedFields = this.convertValues(source["managedFields"], ManagedFieldsEntry);
+ this.spec = this.convertValues(source["spec"], PersistentVolumeClaimSpec);
+ this.status = this.convertValues(source["status"], PersistentVolumeClaimStatus);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+
+
+
+
+
+ export class PodResourceClaimStatus {
+ name: string;
+ resourceClaimName?: string;
+
+ static createFrom(source: any = {}) {
+ return new PodResourceClaimStatus(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.name = source["name"];
+ this.resourceClaimName = source["resourceClaimName"];
+ }
+ }
+ export class PodIP {
+ ip: string;
+
+ static createFrom(source: any = {}) {
+ return new PodIP(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.ip = source["ip"];
+ }
+ }
+ export class PodCondition {
+ type: string;
+ status: string;
+ lastProbeTime?: Time;
+ lastTransitionTime?: Time;
+ reason?: string;
+ message?: string;
+
+ static createFrom(source: any = {}) {
+ return new PodCondition(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.type = source["type"];
+ this.status = source["status"];
+ this.lastProbeTime = this.convertValues(source["lastProbeTime"], Time);
+ this.lastTransitionTime = this.convertValues(source["lastTransitionTime"], Time);
+ this.reason = source["reason"];
+ this.message = source["message"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class PodStatus {
+ phase?: string;
+ conditions?: PodCondition[];
+ message?: string;
+ reason?: string;
+ nominatedNodeName?: string;
+ hostIP?: string;
+ hostIPs?: HostIP[];
+ podIP?: string;
+ podIPs?: PodIP[];
+ startTime?: Time;
+ initContainerStatuses?: ContainerStatus[];
+ containerStatuses?: ContainerStatus[];
+ qosClass?: string;
+ ephemeralContainerStatuses?: ContainerStatus[];
+ resize?: string;
+ resourceClaimStatuses?: PodResourceClaimStatus[];
+
+ static createFrom(source: any = {}) {
+ return new PodStatus(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.phase = source["phase"];
+ this.conditions = this.convertValues(source["conditions"], PodCondition);
+ this.message = source["message"];
+ this.reason = source["reason"];
+ this.nominatedNodeName = source["nominatedNodeName"];
+ this.hostIP = source["hostIP"];
+ this.hostIPs = this.convertValues(source["hostIPs"], HostIP);
+ this.podIP = source["podIP"];
+ this.podIPs = this.convertValues(source["podIPs"], PodIP);
+ this.startTime = this.convertValues(source["startTime"], Time);
+ this.initContainerStatuses = this.convertValues(source["initContainerStatuses"], ContainerStatus);
+ this.containerStatuses = this.convertValues(source["containerStatuses"], ContainerStatus);
+ this.qosClass = source["qosClass"];
+ this.ephemeralContainerStatuses = this.convertValues(source["ephemeralContainerStatuses"], ContainerStatus);
+ this.resize = source["resize"];
+ this.resourceClaimStatuses = this.convertValues(source["resourceClaimStatuses"], PodResourceClaimStatus);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class Pod {
+ kind?: string;
+ apiVersion?: string;
+ name?: string;
+ generateName?: string;
+ namespace?: string;
+ selfLink?: string;
+ uid?: string;
+ resourceVersion?: string;
+ generation?: number;
+ creationTimestamp?: Time;
+ deletionTimestamp?: Time;
+ deletionGracePeriodSeconds?: number;
+ labels?: Record<string, string>;
+ annotations?: Record<string, string>;
+ ownerReferences?: OwnerReference[];
+ finalizers?: string[];
+ managedFields?: ManagedFieldsEntry[];
+ spec?: PodSpec;
+ status?: PodStatus;
+
+ static createFrom(source: any = {}) {
+ return new Pod(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.kind = source["kind"];
+ this.apiVersion = source["apiVersion"];
+ this.name = source["name"];
+ this.generateName = source["generateName"];
+ this.namespace = source["namespace"];
+ this.selfLink = source["selfLink"];
+ this.uid = source["uid"];
+ this.resourceVersion = source["resourceVersion"];
+ this.generation = source["generation"];
+ this.creationTimestamp = this.convertValues(source["creationTimestamp"], Time);
+ this.deletionTimestamp = this.convertValues(source["deletionTimestamp"], Time);
+ this.deletionGracePeriodSeconds = source["deletionGracePeriodSeconds"];
+ this.labels = source["labels"];
+ this.annotations = source["annotations"];
+ this.ownerReferences = this.convertValues(source["ownerReferences"], OwnerReference);
+ this.finalizers = source["finalizers"];
+ this.managedFields = this.convertValues(source["managedFields"], ManagedFieldsEntry);
+ this.spec = this.convertValues(source["spec"], PodSpec);
+ this.status = this.convertValues(source["status"], PodStatus);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ export class RollingUpdateStatefulSetStrategy {
+ partition?: number;
+ maxUnavailable?: intstr.IntOrString;
+
+ static createFrom(source: any = {}) {
+ return new RollingUpdateStatefulSetStrategy(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.partition = source["partition"];
+ this.maxUnavailable = this.convertValues(source["maxUnavailable"], intstr.IntOrString);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+
+
+ export class Secret {
+ kind?: string;
+ apiVersion?: string;
+ name?: string;
+ generateName?: string;
+ namespace?: string;
+ selfLink?: string;
+ uid?: string;
+ resourceVersion?: string;
+ generation?: number;
+ creationTimestamp?: Time;
+ deletionTimestamp?: Time;
+ deletionGracePeriodSeconds?: number;
+ labels?: Record<string, string>;
+ annotations?: Record<string, string>;
+ ownerReferences?: OwnerReference[];
+ finalizers?: string[];
+ managedFields?: ManagedFieldsEntry[];
+ immutable?: boolean;
+ data?: Record<string, number[]>;
+ stringData?: Record<string, string>;
+ type?: string;
+
+ static createFrom(source: any = {}) {
+ return new Secret(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.kind = source["kind"];
+ this.apiVersion = source["apiVersion"];
+ this.name = source["name"];
+ this.generateName = source["generateName"];
+ this.namespace = source["namespace"];
+ this.selfLink = source["selfLink"];
+ this.uid = source["uid"];
+ this.resourceVersion = source["resourceVersion"];
+ this.generation = source["generation"];
+ this.creationTimestamp = this.convertValues(source["creationTimestamp"], Time);
+ this.deletionTimestamp = this.convertValues(source["deletionTimestamp"], Time);
+ this.deletionGracePeriodSeconds = source["deletionGracePeriodSeconds"];
+ this.labels = source["labels"];
+ this.annotations = source["annotations"];
+ this.ownerReferences = this.convertValues(source["ownerReferences"], OwnerReference);
+ this.finalizers = source["finalizers"];
+ this.managedFields = this.convertValues(source["managedFields"], ManagedFieldsEntry);
+ this.immutable = source["immutable"];
+ this.data = source["data"];
+ this.stringData = source["stringData"];
+ this.type = source["type"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+
+
+
+
+
+ export class StatefulSetCondition {
+ type: string;
+ status: string;
+ lastTransitionTime?: Time;
+ reason?: string;
+ message?: string;
+
+ static createFrom(source: any = {}) {
+ return new StatefulSetCondition(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.type = source["type"];
+ this.status = source["status"];
+ this.lastTransitionTime = this.convertValues(source["lastTransitionTime"], Time);
+ this.reason = source["reason"];
+ this.message = source["message"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class StatefulSetStatus {
+ observedGeneration?: number;
+ replicas: number;
+ readyReplicas?: number;
+ currentReplicas?: number;
+ updatedReplicas?: number;
+ currentRevision?: string;
+ updateRevision?: string;
+ collisionCount?: number;
+ conditions?: StatefulSetCondition[];
+ availableReplicas: number;
+
+ static createFrom(source: any = {}) {
+ return new StatefulSetStatus(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.observedGeneration = source["observedGeneration"];
+ this.replicas = source["replicas"];
+ this.readyReplicas = source["readyReplicas"];
+ this.currentReplicas = source["currentReplicas"];
+ this.updatedReplicas = source["updatedReplicas"];
+ this.currentRevision = source["currentRevision"];
+ this.updateRevision = source["updateRevision"];
+ this.collisionCount = source["collisionCount"];
+ this.conditions = this.convertValues(source["conditions"], StatefulSetCondition);
+ this.availableReplicas = source["availableReplicas"];
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class StatefulSetOrdinals {
+ start: number;
+
+ static createFrom(source: any = {}) {
+ return new StatefulSetOrdinals(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.start = source["start"];
+ }
+ }
+ export class StatefulSetPersistentVolumeClaimRetentionPolicy {
+ whenDeleted?: string;
+ whenScaled?: string;
+
+ static createFrom(source: any = {}) {
+ return new StatefulSetPersistentVolumeClaimRetentionPolicy(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.whenDeleted = source["whenDeleted"];
+ this.whenScaled = source["whenScaled"];
+ }
+ }
+ export class StatefulSetUpdateStrategy {
+ type?: string;
+ rollingUpdate?: RollingUpdateStatefulSetStrategy;
+
+ static createFrom(source: any = {}) {
+ return new StatefulSetUpdateStrategy(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.type = source["type"];
+ this.rollingUpdate = this.convertValues(source["rollingUpdate"], RollingUpdateStatefulSetStrategy);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class StatefulSetSpec {
+ replicas?: number;
+ selector?: LabelSelector;
+ template: PodTemplateSpec;
+ volumeClaimTemplates?: PersistentVolumeClaim[];
+ serviceName: string;
+ podManagementPolicy?: string;
+ updateStrategy?: StatefulSetUpdateStrategy;
+ revisionHistoryLimit?: number;
+ minReadySeconds?: number;
+ persistentVolumeClaimRetentionPolicy?: StatefulSetPersistentVolumeClaimRetentionPolicy;
+ ordinals?: StatefulSetOrdinals;
+
+ static createFrom(source: any = {}) {
+ return new StatefulSetSpec(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.replicas = source["replicas"];
+ this.selector = this.convertValues(source["selector"], LabelSelector);
+ this.template = this.convertValues(source["template"], PodTemplateSpec);
+ this.volumeClaimTemplates = this.convertValues(source["volumeClaimTemplates"], PersistentVolumeClaim);
+ this.serviceName = source["serviceName"];
+ this.podManagementPolicy = source["podManagementPolicy"];
+ this.updateStrategy = this.convertValues(source["updateStrategy"], StatefulSetUpdateStrategy);
+ this.revisionHistoryLimit = source["revisionHistoryLimit"];
+ this.minReadySeconds = source["minReadySeconds"];
+ this.persistentVolumeClaimRetentionPolicy = this.convertValues(source["persistentVolumeClaimRetentionPolicy"], StatefulSetPersistentVolumeClaimRetentionPolicy);
+ this.ordinals = this.convertValues(source["ordinals"], StatefulSetOrdinals);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class StatefulSet {
+ kind?: string;
+ apiVersion?: string;
+ name?: string;
+ generateName?: string;
+ namespace?: string;
+ selfLink?: string;
+ uid?: string;
+ resourceVersion?: string;
+ generation?: number;
+ creationTimestamp?: Time;
+ deletionTimestamp?: Time;
+ deletionGracePeriodSeconds?: number;
+ labels?: Record<string, string>;
+ annotations?: Record<string, string>;
+ ownerReferences?: OwnerReference[];
+ finalizers?: string[];
+ managedFields?: ManagedFieldsEntry[];
+ spec?: StatefulSetSpec;
+ status?: StatefulSetStatus;
+
+ static createFrom(source: any = {}) {
+ return new StatefulSet(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.kind = source["kind"];
+ this.apiVersion = source["apiVersion"];
+ this.name = source["name"];
+ this.generateName = source["generateName"];
+ this.namespace = source["namespace"];
+ this.selfLink = source["selfLink"];
+ this.uid = source["uid"];
+ this.resourceVersion = source["resourceVersion"];
+ this.generation = source["generation"];
+ this.creationTimestamp = this.convertValues(source["creationTimestamp"], Time);
+ this.deletionTimestamp = this.convertValues(source["deletionTimestamp"], Time);
+ this.deletionGracePeriodSeconds = source["deletionGracePeriodSeconds"];
+ this.labels = source["labels"];
+ this.annotations = source["annotations"];
+ this.ownerReferences = this.convertValues(source["ownerReferences"], OwnerReference);
+ this.finalizers = source["finalizers"];
+ this.managedFields = this.convertValues(source["managedFields"], ManagedFieldsEntry);
+ this.spec = this.convertValues(source["spec"], StatefulSetSpec);
+ this.status = this.convertValues(source["status"], StatefulSetStatus);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
+
+export namespace x509 {
+
+ export class PolicyMapping {
+ // Go type: OID
+ IssuerDomainPolicy: any;
+ // Go type: OID
+ SubjectDomainPolicy: any;
+
+ static createFrom(source: any = {}) {
+ return new PolicyMapping(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.IssuerDomainPolicy = this.convertValues(source["IssuerDomainPolicy"], null);
+ this.SubjectDomainPolicy = this.convertValues(source["SubjectDomainPolicy"], null);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+ export class OID {
+
+
+ static createFrom(source: any = {}) {
+ return new OID(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+
+ }
+ }
+ export class Certificate {
+ Raw: number[];
+ RawTBSCertificate: number[];
+ RawSubjectPublicKeyInfo: number[];
+ RawSubject: number[];
+ RawIssuer: number[];
+ Signature: number[];
+ SignatureAlgorithm: number;
+ PublicKeyAlgorithm: number;
+ PublicKey: any;
+ Version: number;
+ // Go type: big
+ SerialNumber?: any;
+ Issuer: pkix.Name;
+ Subject: pkix.Name;
+ // Go type: time
+ NotBefore: any;
+ // Go type: time
+ NotAfter: any;
+ KeyUsage: number;
+ Extensions: pkix.Extension[];
+ ExtraExtensions: pkix.Extension[];
+ UnhandledCriticalExtensions: number[][];
+ ExtKeyUsage: number[];
+ UnknownExtKeyUsage: number[][];
+ BasicConstraintsValid: boolean;
+ IsCA: boolean;
+ MaxPathLen: number;
+ MaxPathLenZero: boolean;
+ SubjectKeyId: number[];
+ AuthorityKeyId: number[];
+ OCSPServer: string[];
+ IssuingCertificateURL: string[];
+ DNSNames: string[];
+ EmailAddresses: string[];
+ IPAddresses: number[][];
+ URIs: url.URL[];
+ PermittedDNSDomainsCritical: boolean;
+ PermittedDNSDomains: string[];
+ ExcludedDNSDomains: string[];
+ PermittedIPRanges: net.IPNet[];
+ ExcludedIPRanges: net.IPNet[];
+ PermittedEmailAddresses: string[];
+ ExcludedEmailAddresses: string[];
+ PermittedURIDomains: string[];
+ ExcludedURIDomains: string[];
+ CRLDistributionPoints: string[];
+ PolicyIdentifiers: number[][];
+ Policies: OID[];
+ InhibitAnyPolicy: number;
+ InhibitAnyPolicyZero: boolean;
+ InhibitPolicyMapping: number;
+ InhibitPolicyMappingZero: boolean;
+ RequireExplicitPolicy: number;
+ RequireExplicitPolicyZero: boolean;
+ PolicyMappings: PolicyMapping[];
+
+ static createFrom(source: any = {}) {
+ return new Certificate(source);
+ }
+
+ constructor(source: any = {}) {
+ if ('string' === typeof source) source = JSON.parse(source);
+ this.Raw = source["Raw"];
+ this.RawTBSCertificate = source["RawTBSCertificate"];
+ this.RawSubjectPublicKeyInfo = source["RawSubjectPublicKeyInfo"];
+ this.RawSubject = source["RawSubject"];
+ this.RawIssuer = source["RawIssuer"];
+ this.Signature = source["Signature"];
+ this.SignatureAlgorithm = source["SignatureAlgorithm"];
+ this.PublicKeyAlgorithm = source["PublicKeyAlgorithm"];
+ this.PublicKey = source["PublicKey"];
+ this.Version = source["Version"];
+ this.SerialNumber = this.convertValues(source["SerialNumber"], null);
+ this.Issuer = this.convertValues(source["Issuer"], pkix.Name);
+ this.Subject = this.convertValues(source["Subject"], pkix.Name);
+ this.NotBefore = this.convertValues(source["NotBefore"], null);
+ this.NotAfter = this.convertValues(source["NotAfter"], null);
+ this.KeyUsage = source["KeyUsage"];
+ this.Extensions = this.convertValues(source["Extensions"], pkix.Extension);
+ this.ExtraExtensions = this.convertValues(source["ExtraExtensions"], pkix.Extension);
+ this.UnhandledCriticalExtensions = source["UnhandledCriticalExtensions"];
+ this.ExtKeyUsage = source["ExtKeyUsage"];
+ this.UnknownExtKeyUsage = source["UnknownExtKeyUsage"];
+ this.BasicConstraintsValid = source["BasicConstraintsValid"];
+ this.IsCA = source["IsCA"];
+ this.MaxPathLen = source["MaxPathLen"];
+ this.MaxPathLenZero = source["MaxPathLenZero"];
+ this.SubjectKeyId = source["SubjectKeyId"];
+ this.AuthorityKeyId = source["AuthorityKeyId"];
+ this.OCSPServer = source["OCSPServer"];
+ this.IssuingCertificateURL = source["IssuingCertificateURL"];
+ this.DNSNames = source["DNSNames"];
+ this.EmailAddresses = source["EmailAddresses"];
+ this.IPAddresses = source["IPAddresses"];
+ this.URIs = this.convertValues(source["URIs"], url.URL);
+ this.PermittedDNSDomainsCritical = source["PermittedDNSDomainsCritical"];
+ this.PermittedDNSDomains = source["PermittedDNSDomains"];
+ this.ExcludedDNSDomains = source["ExcludedDNSDomains"];
+ this.PermittedIPRanges = this.convertValues(source["PermittedIPRanges"], net.IPNet);
+ this.ExcludedIPRanges = this.convertValues(source["ExcludedIPRanges"], net.IPNet);
+ this.PermittedEmailAddresses = source["PermittedEmailAddresses"];
+ this.ExcludedEmailAddresses = source["ExcludedEmailAddresses"];
+ this.PermittedURIDomains = source["PermittedURIDomains"];
+ this.ExcludedURIDomains = source["ExcludedURIDomains"];
+ this.CRLDistributionPoints = source["CRLDistributionPoints"];
+ this.PolicyIdentifiers = source["PolicyIdentifiers"];
+ this.Policies = this.convertValues(source["Policies"], OID);
+ this.InhibitAnyPolicy = source["InhibitAnyPolicy"];
+ this.InhibitAnyPolicyZero = source["InhibitAnyPolicyZero"];
+ this.InhibitPolicyMapping = source["InhibitPolicyMapping"];
+ this.InhibitPolicyMappingZero = source["InhibitPolicyMappingZero"];
+ this.RequireExplicitPolicy = source["RequireExplicitPolicy"];
+ this.RequireExplicitPolicyZero = source["RequireExplicitPolicyZero"];
+ this.PolicyMappings = this.convertValues(source["PolicyMappings"], PolicyMapping);
+ }
+
+ convertValues(a: any, classs: any, asMap: boolean = false): any {
+ if (!a) {
+ return a;
+ }
+ if (a.slice && a.map) {
+ return (a as any[]).map(elem => this.convertValues(elem, classs));
+ } else if ("object" === typeof a) {
+ if (asMap) {
+ for (const key of Object.keys(a)) {
+ a[key] = new classs(a[key]);
+ }
+ return a;
+ }
+ return new classs(a);
+ }
+ return a;
+ }
+ }
+
+}
+
+// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
+// This file is automatically generated. DO NOT EDIT
+import {types} from '../models';
+import {context} from '../models';
+import {config} from '../models';
+import {logwrap} from '../models';
+
+export function CreateNamespace(arg1:string,arg2:any):Promise<types.Response>;
+
+export function CreateNamespaceYAML(arg1:string,arg2:string):Promise<types.Response>;
+
+export function CreatePod(arg1:string,arg2:any):Promise<types.Response>;
+
+export function CreatePodYAML(arg1:string,arg2:string):Promise<types.Response>;
+
+export function DeleteIngress(arg1:string,arg2:string,arg3:string):Promise<types.Response>;
+
+export function DeleteNamespace(arg1:string,arg2:string):Promise<types.Response>;
+
+export function DeletePod(arg1:string,arg2:string,arg3:string):Promise<types.Response>;
+
+export function DescribeConfigMap(arg1:string,arg2:string,arg3:string):Promise<types.DescribeResponse>;
+
+export function DescribeDeployment(arg1:string,arg2:string,arg3:string):Promise<types.DescribeResponse>;
+
+export function DescribeIngress(arg1:string,arg2:string,arg3:string):Promise<types.DescribeResponse>;
+
+export function DescribeNamespace(arg1:string,arg2:string):Promise<types.DescribeResponse>;
+
+export function DescribePod(arg1:string,arg2:string,arg3:string):Promise<types.DescribeResponse>;
+
+export function DescribeStatefulSet(arg1:string,arg2:string,arg3:string):Promise<types.DescribeResponse>;
+
+export function GetClusters():Promise<types.ClustersResponse>;
+
+export function GetConfigMaps(arg1:string,arg2:string):Promise<types.ConfigMapsResponse>;
+
+export function GetDeployments(arg1:string,arg2:string):Promise<types.DeploymentsResponse>;
+
+export function GetIngresses(arg1:string,arg2:string):Promise<types.IngressesResponse>;
+
+export function GetNamespace(arg1:string,arg2:string):Promise<types.NamespaceResponse>;
+
+export function GetNamespaces(arg1:string):Promise<types.NamespacesResponse>;
+
+export function GetPod(arg1:string,arg2:string,arg3:string):Promise<types.PodResponse>;
+
+export function GetPods(arg1:string,arg2:string):Promise<types.PodsResponse>;
+
+export function GetStatefulSets(arg1:string,arg2:string):Promise<types.StatefulSetsResponse>;
+
+export function RestartDeployment(arg1:string,arg2:string,arg3:string):Promise<types.DeploymentResponse>;
+
+export function RestartStatefulSet(arg1:string,arg2:string,arg3:string):Promise<types.StatefulSetResponse>;
+
+export function Start(arg1:context.Context,arg2:config.Config,arg3:logwrap.LogWrap):Promise<void>;
+
+export function UpdateNamespaceFromYaml(arg1:string,arg2:string,arg3:string):Promise<types.NamespaceResponse>;
+
+export function UpdatePodFromYaml(arg1:string,arg2:string,arg3:string,arg4:string):Promise<types.PodResponse>;
+// @ts-check
+// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
+// This file is automatically generated. DO NOT EDIT
+
+export function CreateNamespace(arg1, arg2) {
+ return window['go']['services']['clusterService']['CreateNamespace'](arg1, arg2);
+}
+
+export function CreateNamespaceYAML(arg1, arg2) {
+ return window['go']['services']['clusterService']['CreateNamespaceYAML'](arg1, arg2);
+}
+
+export function CreatePod(arg1, arg2) {
+ return window['go']['services']['clusterService']['CreatePod'](arg1, arg2);
+}
+
+export function CreatePodYAML(arg1, arg2) {
+ return window['go']['services']['clusterService']['CreatePodYAML'](arg1, arg2);
+}
+
+export function DeleteIngress(arg1, arg2, arg3) {
+ return window['go']['services']['clusterService']['DeleteIngress'](arg1, arg2, arg3);
+}
+
+export function DeleteNamespace(arg1, arg2) {
+ return window['go']['services']['clusterService']['DeleteNamespace'](arg1, arg2);
+}
+
+export function DeletePod(arg1, arg2, arg3) {
+ return window['go']['services']['clusterService']['DeletePod'](arg1, arg2, arg3);
+}
+
+export function DescribeConfigMap(arg1, arg2, arg3) {
+ return window['go']['services']['clusterService']['DescribeConfigMap'](arg1, arg2, arg3);
+}
+
+export function DescribeDeployment(arg1, arg2, arg3) {
+ return window['go']['services']['clusterService']['DescribeDeployment'](arg1, arg2, arg3);
+}
+
+export function DescribeIngress(arg1, arg2, arg3) {
+ return window['go']['services']['clusterService']['DescribeIngress'](arg1, arg2, arg3);
+}
+
+export function DescribeNamespace(arg1, arg2) {
+ return window['go']['services']['clusterService']['DescribeNamespace'](arg1, arg2);
+}
+
+export function DescribePod(arg1, arg2, arg3) {
+ return window['go']['services']['clusterService']['DescribePod'](arg1, arg2, arg3);
+}
+
+export function DescribeStatefulSet(arg1, arg2, arg3) {
+ return window['go']['services']['clusterService']['DescribeStatefulSet'](arg1, arg2, arg3);
+}
+
+export function GetClusters() {
+ return window['go']['services']['clusterService']['GetClusters']();
+}
+
+export function GetConfigMaps(arg1, arg2) {
+ return window['go']['services']['clusterService']['GetConfigMaps'](arg1, arg2);
+}
+
+export function GetDeployments(arg1, arg2) {
+ return window['go']['services']['clusterService']['GetDeployments'](arg1, arg2);
+}
+
+export function GetIngresses(arg1, arg2) {
+ return window['go']['services']['clusterService']['GetIngresses'](arg1, arg2);
+}
+
+export function GetNamespace(arg1, arg2) {
+ return window['go']['services']['clusterService']['GetNamespace'](arg1, arg2);
+}
+
+export function GetNamespaces(arg1) {
+ return window['go']['services']['clusterService']['GetNamespaces'](arg1);
+}
+
+export function GetPod(arg1, arg2, arg3) {
+ return window['go']['services']['clusterService']['GetPod'](arg1, arg2, arg3);
+}
+
+export function GetPods(arg1, arg2) {
+ return window['go']['services']['clusterService']['GetPods'](arg1, arg2);
+}
+
+export function GetStatefulSets(arg1, arg2) {
+ return window['go']['services']['clusterService']['GetStatefulSets'](arg1, arg2);
+}
+
+export function RestartDeployment(arg1, arg2, arg3) {
+ return window['go']['services']['clusterService']['RestartDeployment'](arg1, arg2, arg3);
+}
+
+export function RestartStatefulSet(arg1, arg2, arg3) {
+ return window['go']['services']['clusterService']['RestartStatefulSet'](arg1, arg2, arg3);
+}
+
+export function Start(arg1, arg2, arg3) {
+ return window['go']['services']['clusterService']['Start'](arg1, arg2, arg3);
+}
+
+export function UpdateNamespaceFromYaml(arg1, arg2, arg3) {
+ return window['go']['services']['clusterService']['UpdateNamespaceFromYaml'](arg1, arg2, arg3);
+}
+
+export function UpdatePodFromYaml(arg1, arg2, arg3, arg4) {
+ return window['go']['services']['clusterService']['UpdatePodFromYaml'](arg1, arg2, arg3, arg4);
+}
+// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
+// This file is automatically generated. DO NOT EDIT
+import {http} from '../models';
+import {context} from '../models';
+import {config} from '../models';
+import {logwrap} from '../models';
+
+export function HandleDeploymentLogs(arg1:http.ResponseWriter,arg2:http.Request):Promise<void>;
+
+export function HandlePodExecWebSocket(arg1:http.ResponseWriter,arg2:http.Request):Promise<void>;
+
+export function HandlePodLogs(arg1:http.ResponseWriter,arg2:http.Request):Promise<void>;
+
+export function Start(arg1:context.Context,arg2:config.Config,arg3:logwrap.LogWrap):Promise<void>;
+// @ts-check
+// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
+// This file is automatically generated. DO NOT EDIT
+
+export function HandleDeploymentLogs(arg1, arg2) {
+ return window['go']['services']['httpsrvService']['HandleDeploymentLogs'](arg1, arg2);
+}
+
+export function HandlePodExecWebSocket(arg1, arg2) {
+ return window['go']['services']['httpsrvService']['HandlePodExecWebSocket'](arg1, arg2);
+}
+
+export function HandlePodLogs(arg1, arg2) {
+ return window['go']['services']['httpsrvService']['HandlePodLogs'](arg1, arg2);
+}
+
+export function Start(arg1, arg2, arg3) {
+ return window['go']['services']['httpsrvService']['Start'](arg1, arg2, arg3);
+}
+// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
+// This file is automatically generated. DO NOT EDIT
+import {types} from '../models';
+import {context} from '../models';
+import {config} from '../models';
+import {logwrap} from '../models';
+
+export function Create(arg1:string,arg2:any):Promise<types.PersistentVolumeClaimResponse>;
+
+export function Delete(arg1:string,arg2:string,arg3:string):Promise<types.Response>;
+
+export function Describe(arg1:string,arg2:string,arg3:string):Promise<types.DescribeResponse>;
+
+export function List(arg1:string,arg2:string):Promise<types.PersistentVolumeClaimsResponse>;
+
+export function Start(arg1:context.Context,arg2:config.Config,arg3:logwrap.LogWrap):Promise<void>;
+// @ts-check
+// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
+// This file is automatically generated. DO NOT EDIT
+
+export function Create(arg1, arg2) {
+ return window['go']['services']['persistentVolumeClaimsService']['Create'](arg1, arg2);
+}
+
+export function Delete(arg1, arg2, arg3) {
+ return window['go']['services']['persistentVolumeClaimsService']['Delete'](arg1, arg2, arg3);
+}
+
+export function Describe(arg1, arg2, arg3) {
+ return window['go']['services']['persistentVolumeClaimsService']['Describe'](arg1, arg2, arg3);
+}
+
+export function List(arg1, arg2) {
+ return window['go']['services']['persistentVolumeClaimsService']['List'](arg1, arg2);
+}
+
+export function Start(arg1, arg2, arg3) {
+ return window['go']['services']['persistentVolumeClaimsService']['Start'](arg1, arg2, arg3);
+}
+// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
+// This file is automatically generated. DO NOT EDIT
+import {types} from '../models';
+import {context} from '../models';
+import {config} from '../models';
+import {logwrap} from '../models';
+
+export function Create(arg1:string,arg2:any):Promise<types.Response>;
+
+export function Delete(arg1:string,arg2:string):Promise<types.Response>;
+
+export function Describe(arg1:string,arg2:string,arg3:string):Promise<types.DescribeResponse>;
+
+export function List(arg1:string):Promise<types.PersistentVolumesResponse>;
+
+export function Start(arg1:context.Context,arg2:config.Config,arg3:logwrap.LogWrap):Promise<void>;
+// @ts-check
+// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
+// This file is automatically generated. DO NOT EDIT
+
+export function Create(arg1, arg2) {
+ return window['go']['services']['persistentVolumesService']['Create'](arg1, arg2);
+}
+
+export function Delete(arg1, arg2) {
+ return window['go']['services']['persistentVolumesService']['Delete'](arg1, arg2);
+}
+
+export function Describe(arg1, arg2, arg3) {
+ return window['go']['services']['persistentVolumesService']['Describe'](arg1, arg2, arg3);
+}
+
+export function List(arg1) {
+ return window['go']['services']['persistentVolumesService']['List'](arg1);
+}
+
+export function Start(arg1, arg2, arg3) {
+ return window['go']['services']['persistentVolumesService']['Start'](arg1, arg2, arg3);
+}
+// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
+// This file is automatically generated. DO NOT EDIT
+import {types} from '../models';
+import {context} from '../models';
+import {config} from '../models';
+import {logwrap} from '../models';
+
+export function Create(arg1:string,arg2:any):Promise<types.Response>;
+
+export function Delete(arg1:string,arg2:string,arg3:string):Promise<types.Response>;
+
+export function Describe(arg1:string,arg2:string,arg3:string):Promise<types.DescribeResponse>;
+
+export function Get(arg1:string,arg2:string,arg3:string):Promise<types.SecretResponse>;
+
+export function List(arg1:string,arg2:string):Promise<types.SecretsResponse>;
+
+export function Start(arg1:context.Context,arg2:config.Config,arg3:logwrap.LogWrap):Promise<void>;
+
+export function Update(arg1:string,arg2:string,arg3:string,arg4:string):Promise<types.SecretResponse>;
+// @ts-check
+// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
+// This file is automatically generated. DO NOT EDIT
+
+export function Create(arg1, arg2) {
+ return window['go']['services']['secretsService']['Create'](arg1, arg2);
+}
+
+export function Delete(arg1, arg2, arg3) {
+ return window['go']['services']['secretsService']['Delete'](arg1, arg2, arg3);
+}
+
+export function Describe(arg1, arg2, arg3) {
+ return window['go']['services']['secretsService']['Describe'](arg1, arg2, arg3);
+}
+
+export function Get(arg1, arg2, arg3) {
+ return window['go']['services']['secretsService']['Get'](arg1, arg2, arg3);
+}
+
+export function List(arg1, arg2) {
+ return window['go']['services']['secretsService']['List'](arg1, arg2);
+}
+
+export function Start(arg1, arg2, arg3) {
+ return window['go']['services']['secretsService']['Start'](arg1, arg2, arg3);
+}
+
+export function Update(arg1, arg2, arg3, arg4) {
+ return window['go']['services']['secretsService']['Update'](arg1, arg2, arg3, arg4);
+}
+{
+ "name": "@wailsapp/runtime",
+ "version": "2.0.0",
+ "description": "Wails Javascript runtime library",
+ "main": "runtime.js",
+ "types": "runtime.d.ts",
+ "scripts": {
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/wailsapp/wails.git"
+ },
+ "keywords": [
+ "Wails",
+ "Javascript",
+ "Go"
+ ],
+ "author": "Lea Anthony <lea.anthony@gmail.com>",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/wailsapp/wails/issues"
+ },
+ "homepage": "https://github.com/wailsapp/wails#readme"
+}
+/*
+ _ __ _ __
+| | / /___ _(_) /____
+| | /| / / __ `/ / / ___/
+| |/ |/ / /_/ / / (__ )
+|__/|__/\__,_/_/_/____/
+The electron alternative for Go
+(c) Lea Anthony 2019-present
+*/
+
+export interface Position {
+ x: number;
+ y: number;
+}
+
+export interface Size {
+ w: number;
+ h: number;
+}
+
+export interface Screen {
+ isCurrent: boolean;
+ isPrimary: boolean;
+ width : number
+ height : number
+}
+
+// Environment information such as platform, buildtype, ...
+export interface EnvironmentInfo {
+ buildType: string;
+ platform: string;
+ arch: string;
+}
+
+// [EventsEmit](https://wails.io/docs/reference/runtime/events#eventsemit)
+// emits the given event. Optional data may be passed with the event.
+// This will trigger any event listeners.
+export function EventsEmit(eventName: string, ...data: any): void;
+
+// [EventsOn](https://wails.io/docs/reference/runtime/events#eventson) sets up a listener for the given event name.
+export function EventsOn(eventName: string, callback: (...data: any) => void): () => void;
+
+// [EventsOnMultiple](https://wails.io/docs/reference/runtime/events#eventsonmultiple)
+// sets up a listener for the given event name, but will only trigger a given number times.
+export function EventsOnMultiple(eventName: string, callback: (...data: any) => void, maxCallbacks: number): () => void;
+
+// [EventsOnce](https://wails.io/docs/reference/runtime/events#eventsonce)
+// sets up a listener for the given event name, but will only trigger once.
+export function EventsOnce(eventName: string, callback: (...data: any) => void): () => void;
+
+// [EventsOff](https://wails.io/docs/reference/runtime/events#eventsoff)
+// unregisters the listener for the given event name.
+export function EventsOff(eventName: string, ...additionalEventNames: string[]): void;
+
+// [EventsOffAll](https://wails.io/docs/reference/runtime/events#eventsoffall)
+// unregisters all listeners.
+export function EventsOffAll(): void;
+
+// [LogPrint](https://wails.io/docs/reference/runtime/log#logprint)
+// logs the given message as a raw message
+export function LogPrint(message: string): void;
+
+// [LogTrace](https://wails.io/docs/reference/runtime/log#logtrace)
+// logs the given message at the `trace` log level.
+export function LogTrace(message: string): void;
+
+// [LogDebug](https://wails.io/docs/reference/runtime/log#logdebug)
+// logs the given message at the `debug` log level.
+export function LogDebug(message: string): void;
+
+// [LogError](https://wails.io/docs/reference/runtime/log#logerror)
+// logs the given message at the `error` log level.
+export function LogError(message: string): void;
+
+// [LogFatal](https://wails.io/docs/reference/runtime/log#logfatal)
+// logs the given message at the `fatal` log level.
+// The application will quit after calling this method.
+export function LogFatal(message: string): void;
+
+// [LogInfo](https://wails.io/docs/reference/runtime/log#loginfo)
+// logs the given message at the `info` log level.
+export function LogInfo(message: string): void;
+
+// [LogWarning](https://wails.io/docs/reference/runtime/log#logwarning)
+// logs the given message at the `warning` log level.
+export function LogWarning(message: string): void;
+
+// [WindowReload](https://wails.io/docs/reference/runtime/window#windowreload)
+// Forces a reload by the main application as well as connected browsers.
+export function WindowReload(): void;
+
+// [WindowReloadApp](https://wails.io/docs/reference/runtime/window#windowreloadapp)
+// Reloads the application frontend.
+export function WindowReloadApp(): void;
+
+// [WindowSetAlwaysOnTop](https://wails.io/docs/reference/runtime/window#windowsetalwaysontop)
+// Sets the window AlwaysOnTop or not on top.
+export function WindowSetAlwaysOnTop(b: boolean): void;
+
+// [WindowSetSystemDefaultTheme](https://wails.io/docs/next/reference/runtime/window#windowsetsystemdefaulttheme)
+// *Windows only*
+// Sets window theme to system default (dark/light).
+export function WindowSetSystemDefaultTheme(): void;
+
+// [WindowSetLightTheme](https://wails.io/docs/next/reference/runtime/window#windowsetlighttheme)
+// *Windows only*
+// Sets window to light theme.
+export function WindowSetLightTheme(): void;
+
+// [WindowSetDarkTheme](https://wails.io/docs/next/reference/runtime/window#windowsetdarktheme)
+// *Windows only*
+// Sets window to dark theme.
+export function WindowSetDarkTheme(): void;
+
+// [WindowCenter](https://wails.io/docs/reference/runtime/window#windowcenter)
+// Centers the window on the monitor the window is currently on.
+export function WindowCenter(): void;
+
+// [WindowSetTitle](https://wails.io/docs/reference/runtime/window#windowsettitle)
+// Sets the text in the window title bar.
+export function WindowSetTitle(title: string): void;
+
+// [WindowFullscreen](https://wails.io/docs/reference/runtime/window#windowfullscreen)
+// Makes the window full screen.
+export function WindowFullscreen(): void;
+
+// [WindowUnfullscreen](https://wails.io/docs/reference/runtime/window#windowunfullscreen)
+// Restores the previous window dimensions and position prior to full screen.
+export function WindowUnfullscreen(): void;
+
+// [WindowIsFullscreen](https://wails.io/docs/reference/runtime/window#windowisfullscreen)
+// Returns the state of the window, i.e. whether the window is in full screen mode or not.
+export function WindowIsFullscreen(): Promise<boolean>;
+
+// [WindowSetSize](https://wails.io/docs/reference/runtime/window#windowsetsize)
+// Sets the width and height of the window.
+export function WindowSetSize(width: number, height: number): void;
+
+// [WindowGetSize](https://wails.io/docs/reference/runtime/window#windowgetsize)
+// Gets the width and height of the window.
+export function WindowGetSize(): Promise<Size>;
+
+// [WindowSetMaxSize](https://wails.io/docs/reference/runtime/window#windowsetmaxsize)
+// Sets the maximum window size. Will resize the window if the window is currently larger than the given dimensions.
+// Setting a size of 0,0 will disable this constraint.
+export function WindowSetMaxSize(width: number, height: number): void;
+
+// [WindowSetMinSize](https://wails.io/docs/reference/runtime/window#windowsetminsize)
+// Sets the minimum window size. Will resize the window if the window is currently smaller than the given dimensions.
+// Setting a size of 0,0 will disable this constraint.
+export function WindowSetMinSize(width: number, height: number): void;
+
+// [WindowSetPosition](https://wails.io/docs/reference/runtime/window#windowsetposition)
+// Sets the window position relative to the monitor the window is currently on.
+export function WindowSetPosition(x: number, y: number): void;
+
+// [WindowGetPosition](https://wails.io/docs/reference/runtime/window#windowgetposition)
+// Gets the window position relative to the monitor the window is currently on.
+export function WindowGetPosition(): Promise<Position>;
+
+// [WindowHide](https://wails.io/docs/reference/runtime/window#windowhide)
+// Hides the window.
+export function WindowHide(): void;
+
+// [WindowShow](https://wails.io/docs/reference/runtime/window#windowshow)
+// Shows the window, if it is currently hidden.
+export function WindowShow(): void;
+
+// [WindowMaximise](https://wails.io/docs/reference/runtime/window#windowmaximise)
+// Maximises the window to fill the screen.
+export function WindowMaximise(): void;
+
+// [WindowToggleMaximise](https://wails.io/docs/reference/runtime/window#windowtogglemaximise)
+// Toggles between Maximised and UnMaximised.
+export function WindowToggleMaximise(): void;
+
+// [WindowUnmaximise](https://wails.io/docs/reference/runtime/window#windowunmaximise)
+// Restores the window to the dimensions and position prior to maximising.
+export function WindowUnmaximise(): void;
+
+// [WindowIsMaximised](https://wails.io/docs/reference/runtime/window#windowismaximised)
+// Returns the state of the window, i.e. whether the window is maximised or not.
+export function WindowIsMaximised(): Promise<boolean>;
+
+// [WindowMinimise](https://wails.io/docs/reference/runtime/window#windowminimise)
+// Minimises the window.
+export function WindowMinimise(): void;
+
+// [WindowUnminimise](https://wails.io/docs/reference/runtime/window#windowunminimise)
+// Restores the window to the dimensions and position prior to minimising.
+export function WindowUnminimise(): void;
+
+// [WindowIsMinimised](https://wails.io/docs/reference/runtime/window#windowisminimised)
+// Returns the state of the window, i.e. whether the window is minimised or not.
+export function WindowIsMinimised(): Promise<boolean>;
+
+// [WindowIsNormal](https://wails.io/docs/reference/runtime/window#windowisnormal)
+// Returns the state of the window, i.e. whether the window is normal or not.
+export function WindowIsNormal(): Promise<boolean>;
+
+// [WindowSetBackgroundColour](https://wails.io/docs/reference/runtime/window#windowsetbackgroundcolour)
+// Sets the background colour of the window to the given RGBA colour definition. This colour will show through for all transparent pixels.
+export function WindowSetBackgroundColour(R: number, G: number, B: number, A: number): void;
+
+// [ScreenGetAll](https://wails.io/docs/reference/runtime/window#screengetall)
+// Gets the all screens. Call this anew each time you want to refresh data from the underlying windowing system.
+export function ScreenGetAll(): Promise<Screen[]>;
+
+// [BrowserOpenURL](https://wails.io/docs/reference/runtime/browser#browseropenurl)
+// Opens the given URL in the system browser.
+export function BrowserOpenURL(url: string): void;
+
+// [Environment](https://wails.io/docs/reference/runtime/intro#environment)
+// Returns information about the environment
+export function Environment(): Promise<EnvironmentInfo>;
+
+// [Quit](https://wails.io/docs/reference/runtime/intro#quit)
+// Quits the application.
+export function Quit(): void;
+
+// [Hide](https://wails.io/docs/reference/runtime/intro#hide)
+// Hides the application.
+export function Hide(): void;
+
+// [Show](https://wails.io/docs/reference/runtime/intro#show)
+// Shows the application.
+export function Show(): void;
+
+// [ClipboardGetText](https://wails.io/docs/reference/runtime/clipboard#clipboardgettext)
+// Returns the current text stored on clipboard
+export function ClipboardGetText(): Promise<string>;
+
+// [ClipboardSetText](https://wails.io/docs/reference/runtime/clipboard#clipboardsettext)
+// Sets a text on the clipboard
+export function ClipboardSetText(text: string): Promise<boolean>;
+
+// [OnFileDrop](https://wails.io/docs/reference/runtime/draganddrop#onfiledrop)
+// OnFileDrop listens to drag and drop events and calls the callback with the coordinates of the drop and an array of path strings.
+export function OnFileDrop(callback: (x: number, y: number ,paths: string[]) => void, useDropTarget: boolean) :void
+
+// [OnFileDropOff](https://wails.io/docs/reference/runtime/draganddrop#dragandddropoff)
+// OnFileDropOff removes the drag and drop listeners and handlers.
+export function OnFileDropOff() :void
+
+// Check if the file path resolver is available
+export function CanResolveFilePaths(): boolean;
+
+// Resolves file paths for an array of files
+export function ResolveFilePaths(files: File[]): void
\ No newline at end of file
+/*
+ _ __ _ __
+| | / /___ _(_) /____
+| | /| / / __ `/ / / ___/
+| |/ |/ / /_/ / / (__ )
+|__/|__/\__,_/_/_/____/
+The electron alternative for Go
+(c) Lea Anthony 2019-present
+*/
+
+export function LogPrint(message) {
+ window.runtime.LogPrint(message);
+}
+
+export function LogTrace(message) {
+ window.runtime.LogTrace(message);
+}
+
+export function LogDebug(message) {
+ window.runtime.LogDebug(message);
+}
+
+export function LogInfo(message) {
+ window.runtime.LogInfo(message);
+}
+
+export function LogWarning(message) {
+ window.runtime.LogWarning(message);
+}
+
+export function LogError(message) {
+ window.runtime.LogError(message);
+}
+
+export function LogFatal(message) {
+ window.runtime.LogFatal(message);
+}
+
+export function EventsOnMultiple(eventName, callback, maxCallbacks) {
+ return window.runtime.EventsOnMultiple(eventName, callback, maxCallbacks);
+}
+
+export function EventsOn(eventName, callback) {
+ return EventsOnMultiple(eventName, callback, -1);
+}
+
+export function EventsOff(eventName, ...additionalEventNames) {
+ return window.runtime.EventsOff(eventName, ...additionalEventNames);
+}
+
+export function EventsOnce(eventName, callback) {
+ return EventsOnMultiple(eventName, callback, 1);
+}
+
+export function EventsEmit(eventName) {
+ let args = [eventName].slice.call(arguments);
+ return window.runtime.EventsEmit.apply(null, args);
+}
+
+export function WindowReload() {
+ window.runtime.WindowReload();
+}
+
+export function WindowReloadApp() {
+ window.runtime.WindowReloadApp();
+}
+
+export function WindowSetAlwaysOnTop(b) {
+ window.runtime.WindowSetAlwaysOnTop(b);
+}
+
+export function WindowSetSystemDefaultTheme() {
+ window.runtime.WindowSetSystemDefaultTheme();
+}
+
+export function WindowSetLightTheme() {
+ window.runtime.WindowSetLightTheme();
+}
+
+export function WindowSetDarkTheme() {
+ window.runtime.WindowSetDarkTheme();
+}
+
+export function WindowCenter() {
+ window.runtime.WindowCenter();
+}
+
+export function WindowSetTitle(title) {
+ window.runtime.WindowSetTitle(title);
+}
+
+export function WindowFullscreen() {
+ window.runtime.WindowFullscreen();
+}
+
+export function WindowUnfullscreen() {
+ window.runtime.WindowUnfullscreen();
+}
+
+export function WindowIsFullscreen() {
+ return window.runtime.WindowIsFullscreen();
+}
+
+export function WindowGetSize() {
+ return window.runtime.WindowGetSize();
+}
+
+export function WindowSetSize(width, height) {
+ window.runtime.WindowSetSize(width, height);
+}
+
+export function WindowSetMaxSize(width, height) {
+ window.runtime.WindowSetMaxSize(width, height);
+}
+
+export function WindowSetMinSize(width, height) {
+ window.runtime.WindowSetMinSize(width, height);
+}
+
+export function WindowSetPosition(x, y) {
+ window.runtime.WindowSetPosition(x, y);
+}
+
+export function WindowGetPosition() {
+ return window.runtime.WindowGetPosition();
+}
+
+export function WindowHide() {
+ window.runtime.WindowHide();
+}
+
+export function WindowShow() {
+ window.runtime.WindowShow();
+}
+
+export function WindowMaximise() {
+ window.runtime.WindowMaximise();
+}
+
+export function WindowToggleMaximise() {
+ window.runtime.WindowToggleMaximise();
+}
+
+export function WindowUnmaximise() {
+ window.runtime.WindowUnmaximise();
+}
+
+export function WindowIsMaximised() {
+ return window.runtime.WindowIsMaximised();
+}
+
+export function WindowMinimise() {
+ window.runtime.WindowMinimise();
+}
+
+export function WindowUnminimise() {
+ window.runtime.WindowUnminimise();
+}
+
+export function WindowSetBackgroundColour(R, G, B, A) {
+ window.runtime.WindowSetBackgroundColour(R, G, B, A);
+}
+
+export function ScreenGetAll() {
+ return window.runtime.ScreenGetAll();
+}
+
+export function WindowIsMinimised() {
+ return window.runtime.WindowIsMinimised();
+}
+
+export function WindowIsNormal() {
+ return window.runtime.WindowIsNormal();
+}
+
+export function BrowserOpenURL(url) {
+ window.runtime.BrowserOpenURL(url);
+}
+
+export function Environment() {
+ return window.runtime.Environment();
+}
+
+export function Quit() {
+ window.runtime.Quit();
+}
+
+export function Hide() {
+ window.runtime.Hide();
+}
+
+export function Show() {
+ window.runtime.Show();
+}
+
+export function ClipboardGetText() {
+ return window.runtime.ClipboardGetText();
+}
+
+export function ClipboardSetText(text) {
+ return window.runtime.ClipboardSetText(text);
+}
+
+/**
+ * Callback for OnFileDrop returns a slice of file path strings when a drop is finished.
+ *
+ * @export
+ * @callback OnFileDropCallback
+ * @param {number} x - x coordinate of the drop
+ * @param {number} y - y coordinate of the drop
+ * @param {string[]} paths - A list of file paths.
+ */
+
+/**
+ * OnFileDrop listens to drag and drop events and calls the callback with the coordinates of the drop and an array of path strings.
+ *
+ * @export
+ * @param {OnFileDropCallback} callback - Callback for OnFileDrop returns a slice of file path strings when a drop is finished.
+ * @param {boolean} [useDropTarget=true] - Only call the callback when the drop finished on an element that has the drop target style. (--wails-drop-target)
+ */
+export function OnFileDrop(callback, useDropTarget) {
+ return window.runtime.OnFileDrop(callback, useDropTarget);
+}
+
+/**
+ * OnFileDropOff removes the drag and drop listeners and handlers.
+ */
+export function OnFileDropOff() {
+ return window.runtime.OnFileDropOff();
+}
+
+export function CanResolveFilePaths() {
+ return window.runtime.CanResolveFilePaths();
+}
+
+export function ResolveFilePaths(files) {
+ return window.runtime.ResolveFilePaths(files);
+}
\ No newline at end of file
+module kd
+
+go 1.23.0
+
+toolchain go1.23.4
+
+require (
+ github.com/gorilla/websocket v1.5.3
+ github.com/spf13/cobra v1.9.1
+ github.com/spf13/viper v1.20.0
+ github.com/wailsapp/wails/v2 v2.10.1
+ k8s.io/api v0.32.3
+ k8s.io/apimachinery v0.32.3
+ k8s.io/client-go v0.32.3
+ k8s.io/kubectl v0.32.3
+)
+
+require (
+ github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
+ github.com/bep/debounce v1.2.1 // indirect
+ github.com/blang/semver/v4 v4.0.0 // indirect
+ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
+ github.com/emicklei/go-restful/v3 v3.11.0 // indirect
+ github.com/fatih/camelcase v1.0.0 // indirect
+ github.com/fsnotify/fsnotify v1.8.0 // indirect
+ github.com/fxamacker/cbor/v2 v2.7.0 // indirect
+ github.com/go-errors/errors v1.4.2 // indirect
+ github.com/go-logr/logr v1.4.2 // indirect
+ github.com/go-ole/go-ole v1.3.0 // indirect
+ github.com/go-openapi/jsonpointer v0.21.0 // indirect
+ github.com/go-openapi/jsonreference v0.20.2 // indirect
+ github.com/go-openapi/swag v0.23.0 // indirect
+ github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
+ github.com/godbus/dbus/v5 v5.1.0 // indirect
+ github.com/gogo/protobuf v1.3.2 // indirect
+ github.com/golang/protobuf v1.5.4 // indirect
+ github.com/google/btree v1.0.1 // indirect
+ github.com/google/gnostic-models v0.6.8 // indirect
+ github.com/google/go-cmp v0.6.0 // indirect
+ github.com/google/gofuzz v1.2.0 // indirect
+ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
+ github.com/google/uuid v1.6.0 // indirect
+ github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
+ github.com/inconshreveable/mousetrap v1.1.0 // indirect
+ github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect
+ github.com/josharian/intern v1.0.0 // indirect
+ github.com/json-iterator/go v1.1.12 // indirect
+ github.com/labstack/echo/v4 v4.13.3 // indirect
+ github.com/labstack/gommon v0.4.2 // indirect
+ github.com/leaanthony/go-ansi-parser v1.6.1 // indirect
+ github.com/leaanthony/gosod v1.0.4 // indirect
+ github.com/leaanthony/slicer v1.6.0 // indirect
+ github.com/leaanthony/u v1.1.1 // indirect
+ github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
+ github.com/mailru/easyjson v0.7.7 // indirect
+ github.com/mattn/go-colorable v0.1.13 // indirect
+ github.com/mattn/go-isatty v0.0.20 // indirect
+ github.com/moby/spdystream v0.5.0 // indirect
+ github.com/moby/term v0.5.0 // indirect
+ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+ github.com/modern-go/reflect2 v1.0.2 // indirect
+ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
+ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
+ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
+ github.com/pelletier/go-toml/v2 v2.2.3 // indirect
+ github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
+ github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
+ github.com/pkg/errors v0.9.1 // indirect
+ github.com/rivo/uniseg v0.4.7 // indirect
+ github.com/sagikazarmark/locafero v0.7.0 // indirect
+ github.com/samber/lo v1.49.1 // indirect
+ github.com/sourcegraph/conc v0.3.0 // indirect
+ github.com/spf13/afero v1.12.0 // indirect
+ github.com/spf13/cast v1.7.1 // indirect
+ github.com/spf13/pflag v1.0.6 // indirect
+ github.com/subosito/gotenv v1.6.0 // indirect
+ github.com/tkrajina/go-reflector v0.5.8 // indirect
+ github.com/valyala/bytebufferpool v1.0.0 // indirect
+ github.com/valyala/fasttemplate v1.2.2 // indirect
+ github.com/wailsapp/go-webview2 v1.0.19 // indirect
+ github.com/wailsapp/mimetype v1.4.1 // indirect
+ github.com/x448/float16 v0.8.4 // indirect
+ github.com/xlab/treeprint v1.2.0 // indirect
+ go.uber.org/multierr v1.11.0 // indirect
+ golang.org/x/crypto v0.33.0 // indirect
+ golang.org/x/net v0.35.0 // indirect
+ golang.org/x/oauth2 v0.25.0 // indirect
+ golang.org/x/sync v0.11.0 // indirect
+ golang.org/x/sys v0.30.0 // indirect
+ golang.org/x/term v0.29.0 // indirect
+ golang.org/x/text v0.22.0 // indirect
+ golang.org/x/time v0.8.0 // indirect
+ google.golang.org/protobuf v1.36.1 // indirect
+ gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
+ gopkg.in/inf.v0 v0.9.1 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
+ k8s.io/cli-runtime v0.32.3 // indirect
+ k8s.io/klog/v2 v2.130.1 // indirect
+ k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect
+ k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
+ sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
+ sigs.k8s.io/kustomize/api v0.18.0 // indirect
+ sigs.k8s.io/kustomize/kyaml v0.18.1 // indirect
+ sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect
+ sigs.k8s.io/yaml v1.4.0 // indirect
+)
+github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
+github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
+github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
+github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
+github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY=
+github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0=
+github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
+github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
+github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
+github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
+github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
+github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
+github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
+github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8=
+github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
+github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
+github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
+github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
+github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
+github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
+github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
+github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
+github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
+github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
+github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
+github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
+github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
+github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
+github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
+github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
+github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
+github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
+github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
+github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
+github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
+github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
+github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss=
+github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
+github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
+github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
+github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
+github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
+github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
+github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
+github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
+github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
+github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
+github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
+github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo=
+github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
+github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
+github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
+github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA=
+github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
+github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
+github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
+github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e h1:Q3+PugElBCf4PFpxhErSzU3/PY5sFL5Z6rfv4AbGAck=
+github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs=
+github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
+github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
+github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
+github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
+github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY=
+github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g=
+github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
+github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
+github.com/leaanthony/debme v1.2.1 h1:9Tgwf+kjcrbMQ4WnPcEIUcQuIZYqdWftzZkBr+i/oOc=
+github.com/leaanthony/debme v1.2.1/go.mod h1:3V+sCm5tYAgQymvSOfYQ5Xx2JCr+OXiD9Jkw3otUjiA=
+github.com/leaanthony/go-ansi-parser v1.6.1 h1:xd8bzARK3dErqkPFtoF9F3/HgN8UQk0ed1YDKpEz01A=
+github.com/leaanthony/go-ansi-parser v1.6.1/go.mod h1:+vva/2y4alzVmmIEpk9QDhA7vLC5zKDTRwfZGOp3IWU=
+github.com/leaanthony/gosod v1.0.4 h1:YLAbVyd591MRffDgxUOU1NwLhT9T1/YiwjKZpkNFeaI=
+github.com/leaanthony/gosod v1.0.4/go.mod h1:GKuIL0zzPj3O1SdWQOdgURSuhkF+Urizzxh26t9f1cw=
+github.com/leaanthony/slicer v1.6.0 h1:1RFP5uiPJvT93TAHi+ipd3NACobkW53yUiBqZheE/Js=
+github.com/leaanthony/slicer v1.6.0/go.mod h1:o/Iz29g7LN0GqH3aMjWAe90381nyZlDNquK+mtH2Fj8=
+github.com/leaanthony/u v1.1.1 h1:TUFjwDGlNX+WuwVEzDqQwC2lOv0P4uhTQw7CMFdiK7M=
+github.com/leaanthony/u v1.1.1/go.mod h1:9+o6hejoRljvZ3BzdYlVL0JYCwtnAsVuN9pVTQcaRfI=
+github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=
+github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
+github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY=
+github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=
+github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
+github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
+github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
+github.com/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ=
+github.com/matryer/is v1.4.1/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
+github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
+github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
+github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU=
+github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI=
+github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
+github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
+github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
+github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
+github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
+github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
+github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
+github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
+github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM=
+github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
+github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4=
+github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
+github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
+github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
+github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
+github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
+github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
+github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
+github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
+github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
+github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
+github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo=
+github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k=
+github.com/samber/lo v1.49.1 h1:4BIFyVfuQSEpluc7Fua+j1NolZHiEHEpaSEKdsH0tew=
+github.com/samber/lo v1.49.1/go.mod h1:dO6KHFzUKXgP8LDhU0oI8d2hekjXnGOu0DB8Jecxd6o=
+github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
+github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
+github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
+github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
+github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs=
+github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4=
+github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
+github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
+github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
+github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
+github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
+github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/viper v1.20.0 h1:zrxIyR3RQIOsarIrgL8+sAvALXul9jeEPa06Y0Ph6vY=
+github.com/spf13/viper v1.20.0/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
+github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
+github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
+github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
+github.com/tkrajina/go-reflector v0.5.8 h1:yPADHrwmUbMq4RGEyaOUpz2H90sRsETNVpjzo3DLVQQ=
+github.com/tkrajina/go-reflector v0.5.8/go.mod h1:ECbqLgccecY5kPmPmXg1MrHW585yMcDkVl6IvJe64T4=
+github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
+github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
+github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
+github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
+github.com/wailsapp/go-webview2 v1.0.19 h1:7U3QcDj1PrBPaxJNCui2k1SkWml+Q5kvFUFyTImA6NU=
+github.com/wailsapp/go-webview2 v1.0.19/go.mod h1:qJmWAmAmaniuKGZPWwne+uor3AHMB5PFhqiK0Bbj8kc=
+github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs=
+github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
+github.com/wailsapp/wails/v2 v2.10.1 h1:QWHvWMXII2nI/nXz77gpPG8P3ehl6zKe+u4su5BWIns=
+github.com/wailsapp/wails/v2 v2.10.1/go.mod h1:zrebnFV6MQf9kx8HI4iAv63vsR5v67oS7GTEZ7Pz1TY=
+github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
+github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
+github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ=
+github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
+github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
+go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
+go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
+go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
+golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
+golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
+golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
+golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70=
+golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
+golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
+golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
+golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
+golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
+golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg=
+golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
+golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=
+google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
+gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
+gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
+gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+k8s.io/api v0.32.3 h1:Hw7KqxRusq+6QSplE3NYG4MBxZw1BZnq4aP4cJVINls=
+k8s.io/api v0.32.3/go.mod h1:2wEDTXADtm/HA7CCMD8D8bK4yuBUptzaRhYcYEEYA3k=
+k8s.io/apimachinery v0.32.3 h1:JmDuDarhDmA/Li7j3aPrwhpNBA94Nvk5zLeOge9HH1U=
+k8s.io/apimachinery v0.32.3/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
+k8s.io/cli-runtime v0.32.3 h1:khLF2ivU2T6Q77H97atx3REY9tXiA3OLOjWJxUrdvss=
+k8s.io/cli-runtime v0.32.3/go.mod h1:vZT6dZq7mZAca53rwUfdFSZjdtLyfF61mkf/8q+Xjak=
+k8s.io/client-go v0.32.3 h1:RKPVltzopkSgHS7aS98QdscAgtgah/+zmpAogooIqVU=
+k8s.io/client-go v0.32.3/go.mod h1:3v0+3k4IcT9bXTc4V2rt+d2ZPPG700Xy6Oi0Gdl2PaY=
+k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
+k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
+k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y=
+k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4=
+k8s.io/kubectl v0.32.3 h1:VMi584rbboso+yjfv0d8uBHwwxbC438LKq+dXd5tOAI=
+k8s.io/kubectl v0.32.3/go.mod h1:6Euv2aso5GKzo/UVMacV6C7miuyevpfI91SvBvV9Zdg=
+k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro=
+k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
+sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8=
+sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo=
+sigs.k8s.io/kustomize/api v0.18.0 h1:hTzp67k+3NEVInwz5BHyzc9rGxIauoXferXyjv5lWPo=
+sigs.k8s.io/kustomize/api v0.18.0/go.mod h1:f8isXnX+8b+SGLHQ6yO4JG1rdkZlvhaCf/uZbLVMb0U=
+sigs.k8s.io/kustomize/kyaml v0.18.1 h1:WvBo56Wzw3fjS+7vBjN6TeivvpbW9GmRaWZ9CIVmt4E=
+sigs.k8s.io/kustomize/kyaml v0.18.1/go.mod h1:C3L2BFVU1jgcddNBE1TxuVLgS46TjObMwW5FT9FcjYo=
+sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aNqRlpuvjmwA=
+sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4=
+sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
+sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
+package main
+
+import (
+ "context"
+ "embed"
+ "flag"
+ "os"
+ "path"
+
+ "kd/backend/config"
+ "kd/backend/logwrap"
+ "kd/backend/services"
+
+ "github.com/wailsapp/wails/v2"
+ wailslogger "github.com/wailsapp/wails/v2/pkg/logger"
+ "github.com/wailsapp/wails/v2/pkg/options"
+ "github.com/wailsapp/wails/v2/pkg/options/assetserver"
+)
+
+//go:embed all:frontend/dist
+var assets embed.FS
+
+func main() {
+ var err error
+ logger := logwrap.New("logger", os.Stdout, true)
+ logger.SetLevel(logwrap.INFO)
+ wailsLogLevel := wailslogger.INFO
+
+ var (
+ debugFlag = flag.Bool("debug", false, "debug")
+ traceFlag = flag.Bool("trace", false, "trace")
+ )
+ flag.Parse()
+
+ if *debugFlag {
+ logger.SetLevel(logwrap.DEBUG)
+ wailsLogLevel = wailslogger.DEBUG
+ }
+
+ if *traceFlag {
+ wailsLogLevel = wailslogger.TRACE
+ }
+
+ kubeConfigPath, ok := os.LookupEnv("KUBECONFIG")
+ if !ok {
+ homeDir, err := os.UserHomeDir()
+ if err != nil {
+ logger.Error(err.Error())
+ os.Exit(1)
+ }
+ kubeConfigPath = path.Join(homeDir, ".kube", "config.yaml")
+ }
+
+ configOpts := []config.OptFunc{
+ config.WithDebug(*debugFlag),
+ }
+
+ conf, err := config.NewConfig(kubeConfigPath, configOpts...)
+ if err != nil {
+ logger.Error(err.Error())
+ os.Exit(1)
+ }
+
+ clusterSvc := services.Cluster()
+ secretsSvc := services.Secrets()
+ persistentVolumeClaimsSvc := services.PersistentVolumeClaims()
+ persistentVolumesSvc := services.PersistentVolumes()
+ httpsrvSvc := services.Httpsrv()
+
+ err = wails.Run(&options.App{
+ Title: "kd",
+ Width: 1024,
+ Height: 768,
+ AssetServer: &assetserver.Options{
+ Assets: assets,
+ },
+ BackgroundColour: &options.RGBA{R: 27, G: 38, B: 54, A: 1},
+ OnStartup: func(ctx context.Context) {
+ clusterSvc.Start(ctx, conf, logger)
+ secretsSvc.Start(ctx, conf, logger)
+ persistentVolumeClaimsSvc.Start(ctx, conf, logger)
+ persistentVolumesSvc.Start(ctx, conf, logger)
+ httpsrvSvc.Start(ctx, conf, logger)
+ },
+ Bind: []interface{}{
+ clusterSvc,
+ secretsSvc,
+ httpsrvSvc,
+ persistentVolumeClaimsSvc,
+ persistentVolumesSvc,
+ },
+ LogLevel: wailsLogLevel,
+ })
+ if err != nil {
+ logger.Error(err.Error())
+ os.Exit(1)
+ }
+}
+{
+ "$schema": "https://wails.io/schemas/config.v2.json",
+ "name": "kd",
+ "outputfilename": "kd",
+ "frontend:install": "npm install",
+ "frontend:build": "npm run build",
+ "frontend:dev:watcher": "npm run dev",
+ "frontend:dev:serverUrl": "auto",
+ "author": {
+ "name": "Rene Cunningham",
+ "email": "rene@compounddata.com"
+ }
+}