diff --git a/.eslintrc b/.eslintrc index f5af1b0e..00926e21 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,10 +1,12 @@ { + "plugins": ["@typescript-eslint", "prettier", "import"], "extends": [ "eslint:recommended", "plugin:@typescript-eslint/recommended", - "plugin:@typescript-eslint/recommended-requiring-type-checking" + "plugin:@typescript-eslint/recommended-requiring-type-checking", + "plugin:import/recommended", + "plugin:import/typescript" ], - "plugins": ["@typescript-eslint", "prettier"], "env": { "browser": true, "es6": true, @@ -26,11 +28,19 @@ "no-case-declarations": "error", "prettier/prettier": "error", "no-mixed-spaces-and-tabs": "error", - "require-await": "off", - "@typescript-eslint/require-await": "error" + "@typescript-eslint/require-await": "error", + "import/no-named-as-default-member": "off", + "import/no-cycle": "warn" }, "parser": "@typescript-eslint/parser", "parserOptions": { "project": "./tsconfig.json" + }, + "settings": { + "import/extensions": [ ".ts" ], + "import/resolver": { + "typescript": true, + "node": true + } } } diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2f265a60..375beec1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -19,6 +19,7 @@ jobs: - run: npm run lint:ci - run: npm run prettier - run: npm run update-translations + - run: npm run fix-imports - name: Fail if there are uncommitted changes run: | if [[ -n "$(git status --porcelain)" ]]; then diff --git a/config.json.example b/config.json.example index bb0c1cf2..66276fb3 100644 --- a/config.json.example +++ b/config.json.example @@ -78,7 +78,9 @@ "nightwaveOverride": "", "allTheFissures": "", "circuitGameModes": null, - "darvoStockMultiplier": 1 + "darvoStockMultiplier": 1, + "varziaOverride": "", + "varziaFullyStocked": false }, "dev": { "keepVendorsExpired": false diff --git a/package-lock.json b/package-lock.json index 7fbb4684..ca86e2cc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,7 @@ "ncp": "^2.0.0", "typescript": "^5.5", "undici": "^7.10.0", - "warframe-public-export-plus": "^0.5.76", + "warframe-public-export-plus": "^0.5.77", "warframe-riven-info": "^0.1.2", "winston": "^3.17.0", "winston-daily-rotate-file": "^5.0.0", @@ -33,6 +33,8 @@ "@typescript-eslint/eslint-plugin": "^8.28.0", "@typescript-eslint/parser": "^8.28.0", "eslint": "^8", + "eslint-import-resolver-typescript": "^4.4.4", + "eslint-plugin-import": "^2.32.0", "eslint-plugin-prettier": "^5.2.5", "prettier": "^3.5.3", "tree-kill": "^1.2.2" @@ -58,6 +60,40 @@ "kuler": "^2.0.0" } }, + "node_modules/@emnapi/core": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.3.tgz", + "integrity": "sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.0.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz", + "integrity": "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.2.tgz", + "integrity": "sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", @@ -216,6 +252,19 @@ "sparse-bitfield": "^3.0.3" } }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.11.tgz", + "integrity": "sha512-9DPkXtvHydrcOsopiYpUgPHpmj0HWZKMUnL2dZqpvC42lsratuBG06V5ipyno0fUek5VlFsNQ+AcFATSrJXgMA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.9.0" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -267,6 +316,24 @@ "url": "https://opencollective.com/pkgr" } }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tybys/wasm-util": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz", + "integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@types/body-parser": { "version": "1.19.5", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", @@ -315,6 +382,13 @@ "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", "license": "MIT" }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", @@ -744,6 +818,275 @@ "dev": true, "license": "ISC" }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.10.1.tgz", + "integrity": "sha512-zohDKXT1Ok0yhbVGff4YAg9HUs5ietG5GpvJBPFSApZnGe7uf2cd26DRhKZbn0Be6xHUZrSzP+RAgMmzyc71EA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.10.1.tgz", + "integrity": "sha512-tAN6k5UrTd4nicpA7s2PbjR/jagpDzAmvXFjbpTazUe5FRsFxVcBlS1F5Lzp5jtWU6bdiqRhSvd4X8rdpCffeA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.10.1.tgz", + "integrity": "sha512-+FCsag8WkauI4dQ50XumCXdfvDCZEpMUnvZDsKMxfOisnEklpDFXc6ThY0WqybBYZbiwR5tWcFaZmI0G6b4vrg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.10.1.tgz", + "integrity": "sha512-qYKGGm5wk71ONcXTMZ0+J11qQeOAPz3nw6VtqrBUUELRyXFyvK8cHhHsLBFR4GHnilc2pgY1HTB2TvdW9wO26Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.10.1.tgz", + "integrity": "sha512-hOHMAhbvIQ63gkpgeNsXcWPSyvXH7ZEyeg254hY0Lp/hX8NdW+FsUWq73g9946Pc/BrcVI/I3C1cmZ4RCX9bNw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.10.1.tgz", + "integrity": "sha512-6ds7+zzHJgTDmpe0gmFcOTvSUhG5oZukkt+cCsSb3k4Uiz2yEQB4iCRITX2hBwSW+p8gAieAfecITjgqCkswXw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.10.1.tgz", + "integrity": "sha512-P7A0G2/jW00diNJyFeq4W9/nxovD62Ay8CMP4UK9OymC7qO7rG1a8Upad68/bdfpIOn7KSp7Aj/6lEW3yyznAA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.10.1.tgz", + "integrity": "sha512-Cg6xzdkrpltcTPO4At+A79zkC7gPDQIgosJmVV8M104ImB6KZi1MrNXgDYIAfkhUYjPzjNooEDFRAwwPadS7ZA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.10.1.tgz", + "integrity": "sha512-aNeg99bVkXa4lt+oZbjNRPC8ZpjJTKxijg/wILrJdzNyAymO2UC/HUK1UfDjt6T7U5p/mK24T3CYOi3/+YEQSA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.10.1.tgz", + "integrity": "sha512-ylz5ojeXrkPrtnzVhpCO+YegG63/aKhkoTlY8PfMfBfLaUG8v6m6iqrL7sBUKdVBgOB4kSTUPt9efQdA/Y3Z/w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.10.1.tgz", + "integrity": "sha512-xcWyhmJfXXOxK7lvE4+rLwBq+on83svlc0AIypfe6x4sMJR+S4oD7n9OynaQShfj2SufPw2KJAotnsNb+4nN2g==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.10.1.tgz", + "integrity": "sha512-mW9JZAdOCyorgi1eLJr4gX7xS67WNG9XNPYj5P8VuttK72XNsmdw9yhOO4tDANMgiLXFiSFaiL1gEpoNtRPw/A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.10.1.tgz", + "integrity": "sha512-NZGKhBy6xkJ0k09cWNZz4DnhBcGlhDd3W+j7EYoNvf5TSwj2K6kbmfqTWITEgkvjsMUjm1wsrc4IJaH6VtjyHQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.10.1.tgz", + "integrity": "sha512-VsjgckJ0gNMw7p0d8In6uPYr+s0p16yrT2rvG4v2jUpEMYkpnfnCiALa9SWshbvlGjKQ98Q2x19agm3iFk8w8Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.10.1.tgz", + "integrity": "sha512-idMnajMeejnaFi0Mx9UTLSYFDAOTfAEP7VjXNgxKApso3Eu2Njs0p2V95nNIyFi4oQVGFmIuCkoznAXtF/Zbmw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.10.1.tgz", + "integrity": "sha512-7jyhjIRNFjzlr8x5pth6Oi9hv3a7ubcVYm2GBFinkBQKcFhw4nIs5BtauSNtDW1dPIGrxF0ciynCZqzxMrYMsg==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.11" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.10.1.tgz", + "integrity": "sha512-TY79+N+Gkoo7E99K+zmsKNeiuNJYlclZJtKqsHSls8We2iGhgxtletVsiBYie93MSTDRDMI8pkBZJlIJSZPrdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.10.1.tgz", + "integrity": "sha512-BAJN5PEPlEV+1m8+PCtFoKm3LQ1P57B4Z+0+efU0NzmCaGk7pUaOxuPgl+m3eufVeeNBKiPDltG0sSB9qEfCxw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.10.1.tgz", + "integrity": "sha512-2v3erKKmmCyIVvvhI2nF15qEbdBpISTq44m9pyd5gfIJB1PN94oePTLWEd82XUbIbvKhv76xTSeUQSCOGesLeg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/accepts": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", @@ -830,12 +1173,160 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/async": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", "license": "MIT" }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -937,6 +1428,25 @@ "node": ">= 0.8" } }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "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", @@ -1145,10 +1655,64 @@ "node": ">= 8" } }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "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==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -1169,6 +1733,42 @@ "dev": true, "license": "MIT" }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -1226,6 +1826,75 @@ "node": ">= 0.8" } }, + "node_modules/es-abstract": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -1256,6 +1925,53 @@ "node": ">= 0.4" } }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -1332,6 +2048,207 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-import-context": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/eslint-import-context/-/eslint-import-context-0.1.9.tgz", + "integrity": "sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-tsconfig": "^4.10.1", + "stable-hash-x": "^0.2.0" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-context" + }, + "peerDependencies": { + "unrs-resolver": "^1.0.0" + }, + "peerDependenciesMeta": { + "unrs-resolver": { + "optional": true + } + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/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", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-4.4.4.tgz", + "integrity": "sha512-1iM2zeBvrYmUNTj2vSC/90JTHDth+dfOfiNKkxApWRsTJYNrc8rOdxxIf5vazX+BiAXTeOT0UvWpGI/7qIWQOw==", + "dev": true, + "license": "ISC", + "dependencies": { + "debug": "^4.4.1", + "eslint-import-context": "^0.1.8", + "get-tsconfig": "^4.10.1", + "is-bun-module": "^2.0.0", + "stable-hash-x": "^0.2.0", + "tinyglobby": "^0.2.14", + "unrs-resolver": "^1.7.11" + }, + "engines": { + "node": "^16.17.0 || >=18.6.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-resolver-typescript" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*", + "eslint-plugin-import-x": "*" + }, + "peerDependenciesMeta": { + "eslint-plugin-import": { + "optional": true + }, + "eslint-plugin-import-x": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/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", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-import/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", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/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/eslint-plugin-import/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/eslint-plugin-prettier": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.4.0.tgz", @@ -1703,6 +2620,22 @@ "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==", "license": "MIT" }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -1737,6 +2670,37 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -1774,6 +2738,37 @@ "node": ">= 0.4" } }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", + "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -1849,6 +2844,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -1868,6 +2880,19 @@ "dev": true, "license": "MIT" }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -1878,6 +2903,35 @@ "node": ">=8" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", @@ -1890,6 +2944,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -1985,6 +3055,21 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -1994,12 +3079,157 @@ "node": ">= 0.10" } }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-arrayish": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", "license": "MIT" }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bun-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", + "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.7.1" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -2010,6 +3240,41 @@ "node": ">=0.10.0" } }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -2023,6 +3288,32 @@ "node": ">=0.10.0" } }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -2033,6 +3324,23 @@ "node": ">=0.12.0" } }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", @@ -2049,6 +3357,54 @@ "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", "license": "MIT" }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -2061,6 +3417,110 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -2108,6 +3568,19 @@ "integrity": "sha512-AhpYAAaZsPjU7smaBomDt1SOQshi9rEm6BlTbfVwsG1vNmeHKtEedJi62sHZzJTyKNtwzmNnrsd55kjwJ7054A==", "license": "MIT" }, + "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", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, "node_modules/kareem": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz", @@ -2284,6 +3757,16 @@ "url": "https://github.com/sponsors/isaacs" } }, + "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", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/moment": { "version": "2.30.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", @@ -2441,6 +3924,22 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, + "node_modules/napi-postinstall": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.0.tgz", + "integrity": "sha512-M7NqKyhODKV1gRLdkwE7pDsZP2/SC2a2vHkOYh9MCpKMbWVfyVfUw5MaH83Fv6XMjxr5jryUp3IDDL9rlxsTeA==", + "dev": true, + "license": "MIT", + "bin": { + "napi-postinstall": "lib/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -2500,6 +3999,90 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -2557,6 +4140,24 @@ "node": ">= 0.8.0" } }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -2641,6 +4242,13 @@ "node": ">=8" } }, + "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": "8.2.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", @@ -2663,6 +4271,16 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -2811,6 +4429,71 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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", @@ -2821,6 +4504,16 @@ "node": ">=4" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", @@ -2889,6 +4582,26 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -2909,6 +4622,41 @@ ], "license": "MIT" }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safe-stable-stringify": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", @@ -2974,6 +4722,55 @@ "node": ">= 18" } }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -3099,6 +4896,16 @@ "memory-pager": "^1.0.2" } }, + "node_modules/stable-hash-x": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/stable-hash-x/-/stable-hash-x-0.2.0.tgz", + "integrity": "sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", @@ -3117,6 +4924,20 @@ "node": ">= 0.8" } }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -3126,6 +4947,65 @@ "safe-buffer": "~5.2.0" } }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -3139,6 +5019,16 @@ "node": ">=8" } }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -3165,6 +5055,19 @@ "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/synckit": { "version": "0.11.4", "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.4.tgz", @@ -3195,6 +5098,51 @@ "dev": true, "license": "MIT" }, + "node_modules/tinyglobby": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -3261,6 +5209,19 @@ "typescript": ">=4.8.4" } }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -3308,6 +5269,84 @@ "node": ">= 0.6" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/typescript": { "version": "5.8.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", @@ -3321,6 +5360,25 @@ "node": ">=14.17" } }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/undici": { "version": "7.10.0", "resolved": "https://registry.npmjs.org/undici/-/undici-7.10.0.tgz", @@ -3345,6 +5403,41 @@ "node": ">= 0.8" } }, + "node_modules/unrs-resolver": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.10.1.tgz", + "integrity": "sha512-EFrL7Hw4kmhZdwWO3dwwFJo6hO3FXuQ6Bg8BK/faHZ9m1YxqBS31BNSTxklIQkxK/4LlV8zTYnPsIRLBzTzjCA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.0" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.10.1", + "@unrs/resolver-binding-android-arm64": "1.10.1", + "@unrs/resolver-binding-darwin-arm64": "1.10.1", + "@unrs/resolver-binding-darwin-x64": "1.10.1", + "@unrs/resolver-binding-freebsd-x64": "1.10.1", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.10.1", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.10.1", + "@unrs/resolver-binding-linux-arm64-gnu": "1.10.1", + "@unrs/resolver-binding-linux-arm64-musl": "1.10.1", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.10.1", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.10.1", + "@unrs/resolver-binding-linux-riscv64-musl": "1.10.1", + "@unrs/resolver-binding-linux-s390x-gnu": "1.10.1", + "@unrs/resolver-binding-linux-x64-gnu": "1.10.1", + "@unrs/resolver-binding-linux-x64-musl": "1.10.1", + "@unrs/resolver-binding-wasm32-wasi": "1.10.1", + "@unrs/resolver-binding-win32-arm64-msvc": "1.10.1", + "@unrs/resolver-binding-win32-ia32-msvc": "1.10.1", + "@unrs/resolver-binding-win32-x64-msvc": "1.10.1" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -3386,9 +5479,9 @@ } }, "node_modules/warframe-public-export-plus": { - "version": "0.5.76", - "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.76.tgz", - "integrity": "sha512-0gX3NTWaxFyzUmqBSUHhPY8pMRX92iXQFqoBuMQlMG1+6uC6JMKtwP5t8cuXR3pvV2vkaCi/cDWjP1JUChkZ9g==" + "version": "0.5.77", + "resolved": "https://registry.npmjs.org/warframe-public-export-plus/-/warframe-public-export-plus-0.5.77.tgz", + "integrity": "sha512-Th/b82pYB4i95afC/s8MDDXsVMl3vyy1qDwLO/AzV6peVBTs2kCSO68nNh7yXDiviGlNl0HRq+LR25jMjtFwSg==" }, "node_modules/warframe-riven-info": { "version": "0.1.2", @@ -3433,6 +5526,95 @@ "node": ">= 8" } }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/winston": { "version": "3.17.0", "resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz", diff --git a/package.json b/package.json index eed277ae..640a0a0b 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,9 @@ "lint:ci": "eslint --ext .ts --rule \"prettier/prettier: off\" .", "lint:fix": "eslint --fix --ext .ts .", "prettier": "prettier --write .", - "update-translations": "cd scripts && node update-translations.js" + "update-translations": "cd scripts && node update-translations.js", + "fix-imports": "cd scripts && node fix-imports.js", + "fix": "npm run update-translations && npm run fix-imports && npm run prettier" }, "license": "GNU", "dependencies": { @@ -37,7 +39,7 @@ "ncp": "^2.0.0", "typescript": "^5.5", "undici": "^7.10.0", - "warframe-public-export-plus": "^0.5.76", + "warframe-public-export-plus": "^0.5.77", "warframe-riven-info": "^0.1.2", "winston": "^3.17.0", "winston-daily-rotate-file": "^5.0.0", @@ -47,6 +49,8 @@ "@typescript-eslint/eslint-plugin": "^8.28.0", "@typescript-eslint/parser": "^8.28.0", "eslint": "^8", + "eslint-import-resolver-typescript": "^4.4.4", + "eslint-plugin-import": "^2.32.0", "eslint-plugin-prettier": "^5.2.5", "prettier": "^3.5.3", "tree-kill": "^1.2.2" diff --git a/scripts/fix-imports.js b/scripts/fix-imports.js new file mode 100644 index 00000000..66878694 --- /dev/null +++ b/scripts/fix-imports.js @@ -0,0 +1,46 @@ +/* eslint-disable */ +const fs = require("fs"); +const path = require("path"); + +const root = path.join(process.cwd(), ".."); + +function listFiles(dir) { + const entries = fs.readdirSync(dir, { withFileTypes: true }); + let results = []; + for (const entry of entries) { + const fullPath = path.join(dir, entry.name); + if (entry.isDirectory()) { + results = results.concat(listFiles(fullPath)); + } else { + results.push(fullPath); + } + } + return results; +} + +const files = listFiles(path.join(root, "src")); + +for (const file of files) { + let content; + try { + content = fs.readFileSync(file, "utf8"); + } catch (e) { + continue; + } + const dir = path.dirname(file); + const fixedContent = content.replaceAll(/} from "([^"]+)";/g, (sub, importPath) => { + if (!importPath.startsWith("@/")) { + const fullImportPath = path.resolve(dir, importPath); + if (fs.existsSync(fullImportPath + ".ts")) { + const relative = path.relative(root, fullImportPath).replace(/\\/g, "/"); + const fixedPath = "@/" + relative; + console.log(`${importPath} -> ${fixedPath}`); + return sub.split(importPath).join(fixedPath); + } + } + return sub; + }); + if (content != fixedContent) { + fs.writeFileSync(file, fixedContent, "utf8"); + } +} diff --git a/src/controllers/api/artifactsController.ts b/src/controllers/api/artifactsController.ts index 3cef399a..85c92592 100644 --- a/src/controllers/api/artifactsController.ts +++ b/src/controllers/api/artifactsController.ts @@ -24,7 +24,6 @@ export const artifactsController: RequestHandler = async (req, res) => { if (itemIndex !== -1) { Upgrades[itemIndex].UpgradeFingerprint = stringifiedUpgradeFingerprint; - inventory.markModified(`Upgrades.${itemIndex}.UpgradeFingerprint`); } else { itemIndex = Upgrades.push({ diff --git a/src/controllers/api/claimCompletedRecipeController.ts b/src/controllers/api/claimCompletedRecipeController.ts index c70a40be..afbb95ad 100644 --- a/src/controllers/api/claimCompletedRecipeController.ts +++ b/src/controllers/api/claimCompletedRecipeController.ts @@ -17,12 +17,12 @@ import { addKubrowPetPrint } from "@/src/services/inventoryService"; import { IInventoryChanges } from "@/src/types/purchaseTypes"; -import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes"; -import { InventorySlot, IPendingRecipeDatabase, Status } from "@/src/types/inventoryTypes/inventoryTypes"; +import { InventorySlot, IPendingRecipeDatabase } from "@/src/types/inventoryTypes/inventoryTypes"; import { toOid2 } from "@/src/helpers/inventoryHelpers"; import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; import { IRecipe } from "warframe-public-export-plus"; import { config } from "@/src/services/configService"; +import { IEquipmentClient, Status } from "@/src/types/equipmentTypes"; interface IClaimCompletedRecipeRequest { RecipeIds: IOid[]; diff --git a/src/controllers/api/contributeToVaultController.ts b/src/controllers/api/contributeToVaultController.ts index 77a93097..e6a33443 100644 --- a/src/controllers/api/contributeToVaultController.ts +++ b/src/controllers/api/contributeToVaultController.ts @@ -21,7 +21,8 @@ import { updateCurrency } from "@/src/services/inventoryService"; import { getAccountIdForRequest } from "@/src/services/loginService"; -import { IFusionTreasure, IMiscItem, ITypeCount } from "@/src/types/inventoryTypes/inventoryTypes"; +import { ITypeCount } from "@/src/types/commonTypes"; +import { IFusionTreasure, IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes"; import { RequestHandler } from "express"; export const contributeToVaultController: RequestHandler = async (req, res) => { diff --git a/src/controllers/api/crewShipIdentifySalvageController.ts b/src/controllers/api/crewShipIdentifySalvageController.ts index cc77589e..83a9d7cb 100644 --- a/src/controllers/api/crewShipIdentifySalvageController.ts +++ b/src/controllers/api/crewShipIdentifySalvageController.ts @@ -12,7 +12,7 @@ import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { IInventoryChanges } from "@/src/types/purchaseTypes"; import { getRandomInt } from "@/src/services/rngService"; import { IFingerprintStat } from "@/src/helpers/rivenHelper"; -import { IEquipmentDatabase } from "@/src/types/inventoryTypes/commonInventoryTypes"; +import { IEquipmentDatabase } from "@/src/types/equipmentTypes"; export const crewShipIdentifySalvageController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); diff --git a/src/controllers/api/customObstacleCourseLeaderboardController.ts b/src/controllers/api/customObstacleCourseLeaderboardController.ts index 9b768def..de5c4217 100644 --- a/src/controllers/api/customObstacleCourseLeaderboardController.ts +++ b/src/controllers/api/customObstacleCourseLeaderboardController.ts @@ -1,12 +1,15 @@ import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { Guild } from "@/src/models/guildModel"; -import { getAccountForRequest } from "@/src/services/loginService"; +import { hasAccessToDojo, hasGuildPermission } from "@/src/services/guildService"; +import { getInventory } from "@/src/services/inventoryService"; +import { getAccountForRequest, getAccountIdForRequest } from "@/src/services/loginService"; +import { GuildPermission } from "@/src/types/guildTypes"; import { logger } from "@/src/utils/logger"; import { RequestHandler } from "express"; export const customObstacleCourseLeaderboardController: RequestHandler = async (req, res) => { const data = getJSONfromString(String(req.body)); - const guild = (await Guild.findById(data.g, "DojoComponents"))!; + const guild = (await Guild.findById(data.g, "DojoComponents Ranks"))!; const component = guild.DojoComponents.id(data.c)!; if (req.query.act == "f") { res.json({ @@ -34,6 +37,19 @@ export const customObstacleCourseLeaderboardController: RequestHandler = async ( entry.r = ++r; } await guild.save(); + res.status(200).end(); + } else if (req.query.act == "c") { + // TOVERIFY: What clan permission is actually needed for this? + const accountId = await getAccountIdForRequest(req); + const inventory = await getInventory(accountId, "GuildId LevelKeys"); + if (!hasAccessToDojo(inventory) || !(await hasGuildPermission(guild, accountId, GuildPermission.Decorator))) { + res.status(400).end(); + return; + } + + component.Leaderboard = undefined; + await guild.save(); + res.status(200).end(); } else { logger.debug(`data provided to ${req.path}: ${String(req.body)}`); diff --git a/src/controllers/api/evolveWeaponController.ts b/src/controllers/api/evolveWeaponController.ts index 395b3340..8318f17b 100644 --- a/src/controllers/api/evolveWeaponController.ts +++ b/src/controllers/api/evolveWeaponController.ts @@ -3,7 +3,7 @@ import { getAccountIdForRequest } from "@/src/services/loginService"; import { addMiscItems, getInventory } from "@/src/services/inventoryService"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { getRecipe, WeaponTypeInternal } from "@/src/services/itemDataService"; -import { EquipmentFeatures } from "@/src/types/inventoryTypes/commonInventoryTypes"; +import { EquipmentFeatures } from "@/src/types/equipmentTypes"; export const evolveWeaponController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); diff --git a/src/controllers/api/focusController.ts b/src/controllers/api/focusController.ts index c7f96a6d..b5257201 100644 --- a/src/controllers/api/focusController.ts +++ b/src/controllers/api/focusController.ts @@ -4,7 +4,6 @@ import { getInventory, addMiscItems, addEquipment, occupySlot } from "@/src/serv import { IMiscItem, TFocusPolarity, TEquipmentKey, InventorySlot } from "@/src/types/inventoryTypes/inventoryTypes"; import { logger } from "@/src/utils/logger"; import { ExportFocusUpgrades } from "warframe-public-export-plus"; -import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes"; import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; export const focusController: RequestHandler = async (req, res) => { @@ -116,7 +115,7 @@ export const focusController: RequestHandler = async (req, res) => { }); occupySlot(inventory, InventorySlot.AMPS, false); await inventory.save(); - res.json((inventoryChanges.OperatorAmps as IEquipmentClient[])[0]); + res.json(inventoryChanges.OperatorAmps![0]); break; } case FocusOperation.UnbindUpgrade: { diff --git a/src/controllers/api/gardeningController.ts b/src/controllers/api/gardeningController.ts index 1913bd63..4cdb32fd 100644 --- a/src/controllers/api/gardeningController.ts +++ b/src/controllers/api/gardeningController.ts @@ -6,9 +6,8 @@ import { getAccountIdForRequest } from "@/src/services/loginService"; import { createGarden, getPersonalRooms } from "@/src/services/personalRoomsService"; import { IMongoDate } from "@/src/types/commonTypes"; import { IMissionReward } from "@/src/types/missionTypes"; -import { IPersonalRoomsClient } from "@/src/types/personalRoomsTypes"; +import { IGardeningClient, IPersonalRoomsClient } from "@/src/types/personalRoomsTypes"; import { IInventoryChanges } from "@/src/types/purchaseTypes"; -import { IGardeningClient } from "@/src/types/shipTypes"; import { RequestHandler } from "express"; import { dict_en, ExportResources } from "warframe-public-export-plus"; diff --git a/src/controllers/api/getNewRewardSeedController.ts b/src/controllers/api/getNewRewardSeedController.ts index cb9e1f82..9aed91f6 100644 --- a/src/controllers/api/getNewRewardSeedController.ts +++ b/src/controllers/api/getNewRewardSeedController.ts @@ -1,6 +1,6 @@ import { Inventory } from "@/src/models/inventoryModels/inventoryModel"; -import { generateRewardSeed } from "@/src/services/inventoryService"; import { getAccountIdForRequest } from "@/src/services/loginService"; +import { generateRewardSeed } from "@/src/services/rngService"; import { RequestHandler } from "express"; export const getNewRewardSeedController: RequestHandler = async (req, res) => { diff --git a/src/controllers/api/getShipController.ts b/src/controllers/api/getShipController.ts index ca22ec3d..ff04aec2 100644 --- a/src/controllers/api/getShipController.ts +++ b/src/controllers/api/getShipController.ts @@ -3,10 +3,9 @@ import { config } from "@/src/services/configService"; import allShipFeatures from "@/static/fixed_responses/allShipFeatures.json"; import { getAccountIdForRequest } from "@/src/services/loginService"; import { createGarden, getPersonalRooms } from "@/src/services/personalRoomsService"; -import { toOid } from "@/src/helpers/inventoryHelpers"; -import { IGetShipResponse } from "@/src/types/shipTypes"; -import { IPersonalRoomsClient } from "@/src/types/personalRoomsTypes"; +import { IGetShipResponse, IPersonalRoomsClient } from "@/src/types/personalRoomsTypes"; import { getLoadout } from "@/src/services/loadoutService"; +import { toOid } from "@/src/helpers/inventoryHelpers"; export const getShipController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); @@ -26,15 +25,7 @@ export const getShipController: RequestHandler = async (req, res) => { LoadOutInventory: { LoadOutPresets: loadout.toJSON() }, Ship: { ...personalRooms.Ship, - ShipId: toOid(personalRoomsDb.activeShipId), - ShipInterior: { - Colors: personalRooms.ShipInteriorColors, - ShipAttachments: { HOOD_ORNAMENT: "" }, - SkinFlavourItem: "" - }, - FavouriteLoadoutId: personalRooms.Ship.FavouriteLoadoutId - ? toOid(personalRooms.Ship.FavouriteLoadoutId) - : undefined + ShipId: toOid(personalRoomsDb.activeShipId) }, Apartment: personalRooms.Apartment, TailorShop: personalRooms.TailorShop diff --git a/src/controllers/api/gildWeaponController.ts b/src/controllers/api/gildWeaponController.ts index fac741fc..d1d02153 100644 --- a/src/controllers/api/gildWeaponController.ts +++ b/src/controllers/api/gildWeaponController.ts @@ -3,9 +3,10 @@ import { getAccountIdForRequest } from "@/src/services/loginService"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { addMiscItems, getInventory } from "@/src/services/inventoryService"; import { TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes"; -import { ArtifactPolarity, EquipmentFeatures, IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes"; +import { ArtifactPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; import { ExportRecipes } from "warframe-public-export-plus"; import { IInventoryChanges } from "@/src/types/purchaseTypes"; +import { EquipmentFeatures, IEquipmentClient } from "@/src/types/equipmentTypes"; interface IGildWeaponRequest { ItemName: string; diff --git a/src/controllers/api/giveShipDecoAndLoreFragmentController.ts b/src/controllers/api/giveShipDecoAndLoreFragmentController.ts index 08385cbf..ae998374 100644 --- a/src/controllers/api/giveShipDecoAndLoreFragmentController.ts +++ b/src/controllers/api/giveShipDecoAndLoreFragmentController.ts @@ -1,7 +1,8 @@ import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { addLoreFragmentScans, addShipDecorations, getInventory } from "@/src/services/inventoryService"; import { getAccountIdForRequest } from "@/src/services/loginService"; -import { ILoreFragmentScan, ITypeCount } from "@/src/types/inventoryTypes/inventoryTypes"; +import { ITypeCount } from "@/src/types/commonTypes"; +import { ILoreFragmentScan } from "@/src/types/inventoryTypes/inventoryTypes"; import { RequestHandler } from "express"; export const giveShipDecoAndLoreFragmentController: RequestHandler = async (req, res) => { diff --git a/src/controllers/api/inventoryController.ts b/src/controllers/api/inventoryController.ts index c1933a80..05d6aec2 100644 --- a/src/controllers/api/inventoryController.ts +++ b/src/controllers/api/inventoryController.ts @@ -5,7 +5,7 @@ import { config } from "@/src/services/configService"; import allDialogue from "@/static/fixed_responses/allDialogue.json"; import { ILoadoutDatabase } from "@/src/types/saveLoadoutTypes"; import { IInventoryClient, IShipInventory, equipmentKeys } from "@/src/types/inventoryTypes/inventoryTypes"; -import { IPolarity, ArtifactPolarity, EquipmentFeatures } from "@/src/types/inventoryTypes/commonInventoryTypes"; +import { IPolarity, ArtifactPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; import { ExportCustoms, ExportFlavour, ExportResources, ExportVirtuals } from "warframe-public-export-plus"; import { applyCheatsToInfestedFoundry, handleSubsumeCompletion } from "@/src/services/infestedFoundryService"; import { @@ -14,7 +14,6 @@ import { allDailyAffiliationKeys, cleanupInventory, createLibraryDailyTask, - generateRewardSeed, getCalendarProgress } from "@/src/services/inventoryService"; import { logger } from "@/src/utils/logger"; @@ -28,6 +27,8 @@ import { toLegacyOid, toOid, version_compare } from "@/src/helpers/inventoryHelp import { Inbox } from "@/src/models/inboxModel"; import { unixTimesInMs } from "@/src/constants/timeConstants"; import { DailyDeal } from "@/src/models/worldStateModel"; +import { EquipmentFeatures } from "@/src/types/equipmentTypes"; +import { generateRewardSeed } from "@/src/services/rngService"; export const inventoryController: RequestHandler = async (request, response) => { const account = await getAccountForRequest(request); diff --git a/src/controllers/api/inventorySlotsController.ts b/src/controllers/api/inventorySlotsController.ts index d32bc0db..3face44e 100644 --- a/src/controllers/api/inventorySlotsController.ts +++ b/src/controllers/api/inventorySlotsController.ts @@ -1,7 +1,6 @@ import { getAccountIdForRequest } from "@/src/services/loginService"; -import { getInventory, updateCurrency } from "@/src/services/inventoryService"; +import { getInventory, updateCurrency, updateSlots } from "@/src/services/inventoryService"; import { RequestHandler } from "express"; -import { updateSlots } from "@/src/services/inventoryService"; import { InventorySlot } from "@/src/types/inventoryTypes/inventoryTypes"; import { logger } from "@/src/utils/logger"; diff --git a/src/controllers/api/loginController.ts b/src/controllers/api/loginController.ts index c7b5c16d..fabc4945 100644 --- a/src/controllers/api/loginController.ts +++ b/src/controllers/api/loginController.ts @@ -8,7 +8,7 @@ import { createAccount, createNonce, getUsernameFromEmail, isCorrectPassword } f import { IDatabaseAccountJson, ILoginRequest, ILoginResponse } from "@/src/types/loginTypes"; import { logger } from "@/src/utils/logger"; import { version_compare } from "@/src/helpers/inventoryHelpers"; -import { sendWsBroadcastTo } from "@/src/services/webService"; +import { sendWsBroadcastTo } from "@/src/services/wsService"; export const loginController: RequestHandler = async (request, response) => { const loginRequest = JSON.parse(String(request.body)) as ILoginRequest; // parse octet stream of json data to json object diff --git a/src/controllers/api/loginRewardsController.ts b/src/controllers/api/loginRewardsController.ts index 7678722f..547724c2 100644 --- a/src/controllers/api/loginRewardsController.ts +++ b/src/controllers/api/loginRewardsController.ts @@ -9,7 +9,7 @@ import { } from "@/src/services/loginRewardService"; import { getInventory } from "@/src/services/inventoryService"; import { config } from "@/src/services/configService"; -import { sendWsBroadcastTo } from "@/src/services/webService"; +import { sendWsBroadcastTo } from "@/src/services/wsService"; export const loginRewardsController: RequestHandler = async (req, res) => { const account = await getAccountForRequest(req); diff --git a/src/controllers/api/loginRewardsSelectionController.ts b/src/controllers/api/loginRewardsSelectionController.ts index 63e160f6..174c5659 100644 --- a/src/controllers/api/loginRewardsSelectionController.ts +++ b/src/controllers/api/loginRewardsSelectionController.ts @@ -6,7 +6,7 @@ import { } from "@/src/services/loginRewardService"; import { getAccountForRequest } from "@/src/services/loginService"; import { handleStoreItemAcquisition } from "@/src/services/purchaseService"; -import { sendWsBroadcastTo } from "@/src/services/webService"; +import { sendWsBroadcastTo } from "@/src/services/wsService"; import { IInventoryChanges } from "@/src/types/purchaseTypes"; import { logger } from "@/src/utils/logger"; import { RequestHandler } from "express"; diff --git a/src/controllers/api/logoutController.ts b/src/controllers/api/logoutController.ts index e2074f76..d290b1ee 100644 --- a/src/controllers/api/logoutController.ts +++ b/src/controllers/api/logoutController.ts @@ -1,6 +1,6 @@ import { RequestHandler } from "express"; import { Account } from "@/src/models/loginModel"; -import { sendWsBroadcastTo } from "@/src/services/webService"; +import { sendWsBroadcastTo } from "@/src/services/wsService"; export const logoutController: RequestHandler = async (req, res) => { if (!req.query.accountId) { diff --git a/src/controllers/api/missionInventoryUpdateController.ts b/src/controllers/api/missionInventoryUpdateController.ts index e3b86b71..49eb6e1b 100644 --- a/src/controllers/api/missionInventoryUpdateController.ts +++ b/src/controllers/api/missionInventoryUpdateController.ts @@ -3,11 +3,12 @@ import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { getAccountForRequest } from "@/src/services/loginService"; import { IMissionInventoryUpdateRequest } from "@/src/types/requestTypes"; import { addMissionInventoryUpdates, addMissionRewards } from "@/src/services/missionInventoryUpdateService"; -import { generateRewardSeed, getInventory } from "@/src/services/inventoryService"; -import { getInventoryResponse } from "./inventoryController"; +import { getInventory } from "@/src/services/inventoryService"; +import { getInventoryResponse } from "@/src/controllers/api/inventoryController"; import { logger } from "@/src/utils/logger"; import { IMissionInventoryUpdateResponse } from "@/src/types/missionTypes"; -import { sendWsBroadcastTo } from "@/src/services/webService"; +import { sendWsBroadcastTo } from "@/src/services/wsService"; +import { generateRewardSeed } from "@/src/services/rngService"; /* **** INPUT **** diff --git a/src/controllers/api/modularWeaponCraftingController.ts b/src/controllers/api/modularWeaponCraftingController.ts index 6034132c..7a4fc45a 100644 --- a/src/controllers/api/modularWeaponCraftingController.ts +++ b/src/controllers/api/modularWeaponCraftingController.ts @@ -15,10 +15,9 @@ import { import { IInventoryChanges } from "@/src/types/purchaseTypes"; import { getDefaultUpgrades } from "@/src/services/itemDataService"; import { modularWeaponTypes } from "@/src/helpers/modularWeaponHelper"; -import { IEquipmentDatabase } from "@/src/types/inventoryTypes/commonInventoryTypes"; import { getRandomInt } from "@/src/services/rngService"; import { ExportSentinels, ExportWeapons, IDefaultUpgrade } from "warframe-public-export-plus"; -import { Status } from "@/src/types/inventoryTypes/inventoryTypes"; +import { IEquipmentDatabase, Status } from "@/src/types/equipmentTypes"; interface IModularCraftRequest { WeaponType: string; diff --git a/src/controllers/api/modularWeaponSaleController.ts b/src/controllers/api/modularWeaponSaleController.ts index 767d1a94..45e5b1dd 100644 --- a/src/controllers/api/modularWeaponSaleController.ts +++ b/src/controllers/api/modularWeaponSaleController.ts @@ -3,7 +3,7 @@ import { ExportWeapons } from "warframe-public-export-plus"; import { IMongoDate } from "@/src/types/commonTypes"; import { toMongoDate } from "@/src/helpers/inventoryHelpers"; import { SRng } from "@/src/services/rngService"; -import { ArtifactPolarity, EquipmentFeatures } from "@/src/types/inventoryTypes/commonInventoryTypes"; +import { ArtifactPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { addEquipment, @@ -17,6 +17,7 @@ import { getDefaultUpgrades } from "@/src/services/itemDataService"; import { getAccountIdForRequest } from "@/src/services/loginService"; import { modularWeaponTypes } from "@/src/helpers/modularWeaponHelper"; import { IInventoryChanges } from "@/src/types/purchaseTypes"; +import { EquipmentFeatures } from "@/src/types/equipmentTypes"; export const modularWeaponSaleController: RequestHandler = async (req, res) => { const partTypeToParts: Record = {}; diff --git a/src/controllers/api/nameWeaponController.ts b/src/controllers/api/nameWeaponController.ts index 8d378feb..c3c899ba 100644 --- a/src/controllers/api/nameWeaponController.ts +++ b/src/controllers/api/nameWeaponController.ts @@ -3,7 +3,7 @@ import { getAccountIdForRequest } from "@/src/services/loginService"; import { getInventory, updateCurrency } from "@/src/services/inventoryService"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes"; -import { sendWsBroadcastTo } from "@/src/services/webService"; +import { sendWsBroadcastTo } from "@/src/services/wsService"; interface INameWeaponRequest { ItemName: string; diff --git a/src/controllers/api/nemesisController.ts b/src/controllers/api/nemesisController.ts index dbdb10e3..2d361c80 100644 --- a/src/controllers/api/nemesisController.ts +++ b/src/controllers/api/nemesisController.ts @@ -1,7 +1,6 @@ import { version_compare } from "@/src/helpers/inventoryHelpers"; import { antivirusMods, - consumeModCharge, decodeNemesisGuess, encodeNemesisGuess, getInfNodes, @@ -17,12 +16,13 @@ import { parseUpgrade } from "@/src/helpers/nemesisHelpers"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; +import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; import { Loadout } from "@/src/models/inventoryModels/loadoutModel"; -import { freeUpSlot, getInventory } from "@/src/services/inventoryService"; +import { addMods, freeUpSlot, getInventory } from "@/src/services/inventoryService"; import { getAccountForRequest } from "@/src/services/loginService"; import { SRng } from "@/src/services/rngService"; import { IMongoDate, IOid } from "@/src/types/commonTypes"; -import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes"; +import { IEquipmentClient } from "@/src/types/equipmentTypes"; import { IInnateDamageFingerprint, IInventoryClient, @@ -36,6 +36,7 @@ import { } from "@/src/types/inventoryTypes/inventoryTypes"; import { logger } from "@/src/utils/logger"; import { RequestHandler } from "express"; +import { Types } from "mongoose"; export const nemesisController: RequestHandler = async (req, res) => { const account = await getAccountForRequest(req); @@ -391,3 +392,54 @@ interface IKnife { AttachedUpgrades: IUpgradeClient[]; HiddenWhenHolstered: boolean; } + +const consumeModCharge = ( + response: IKnifeResponse, + inventory: TInventoryDatabaseDocument, + upgrade: { ItemId: IOid; ItemType: string }, + dataknifeUpgrades: string[] +): void => { + response.UpgradeIds ??= []; + response.UpgradeTypes ??= []; + response.UpgradeFingerprints ??= []; + response.UpgradeNew ??= []; + response.HasKnife = true; + + if (upgrade.ItemId.$oid != "000000000000000000000000") { + const dbUpgrade = inventory.Upgrades.id(upgrade.ItemId.$oid)!; + const fingerprint = JSON.parse(dbUpgrade.UpgradeFingerprint!) as { lvl: number }; + fingerprint.lvl += 1; + dbUpgrade.UpgradeFingerprint = JSON.stringify(fingerprint); + + response.UpgradeIds.push(upgrade.ItemId.$oid); + response.UpgradeTypes.push(upgrade.ItemType); + response.UpgradeFingerprints.push(fingerprint); + response.UpgradeNew.push(false); + } else { + const id = new Types.ObjectId(); + inventory.Upgrades.push({ + _id: id, + ItemType: upgrade.ItemType, + UpgradeFingerprint: `{"lvl":1}` + }); + + addMods(inventory, [ + { + ItemType: upgrade.ItemType, + ItemCount: -1 + } + ]); + + const dataknifeRawUpgradeIndex = dataknifeUpgrades.indexOf(upgrade.ItemType); + if (dataknifeRawUpgradeIndex != -1) { + dataknifeUpgrades[dataknifeRawUpgradeIndex] = id.toString(); + } else { + logger.warn(`${upgrade.ItemType} not found in dataknife config`); + } + + response.UpgradeIds.push(id.toString()); + response.UpgradeTypes.push(upgrade.ItemType); + response.UpgradeFingerprints.push({ lvl: 1 }); + response.UpgradeNew.push(true); + } +}; diff --git a/src/controllers/api/purchaseController.ts b/src/controllers/api/purchaseController.ts index 390e8d72..69175739 100644 --- a/src/controllers/api/purchaseController.ts +++ b/src/controllers/api/purchaseController.ts @@ -3,7 +3,7 @@ import { getAccountIdForRequest } from "@/src/services/loginService"; import { IPurchaseRequest } from "@/src/types/purchaseTypes"; import { handlePurchase } from "@/src/services/purchaseService"; import { getInventory } from "@/src/services/inventoryService"; -import { sendWsBroadcastTo } from "@/src/services/webService"; +import { sendWsBroadcastTo } from "@/src/services/wsService"; export const purchaseController: RequestHandler = async (req, res) => { const purchaseRequest = JSON.parse(String(req.body)) as IPurchaseRequest; diff --git a/src/controllers/api/renamePetController.ts b/src/controllers/api/renamePetController.ts index 40b4ec37..f3fe0c89 100644 --- a/src/controllers/api/renamePetController.ts +++ b/src/controllers/api/renamePetController.ts @@ -1,7 +1,7 @@ import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { getInventory, updateCurrency } from "@/src/services/inventoryService"; import { getAccountIdForRequest } from "@/src/services/loginService"; -import { sendWsBroadcastTo } from "@/src/services/webService"; +import { sendWsBroadcastTo } from "@/src/services/wsService"; import { IInventoryChanges } from "@/src/types/purchaseTypes"; import { RequestHandler } from "express"; diff --git a/src/controllers/api/retrievePetFromStasisController.ts b/src/controllers/api/retrievePetFromStasisController.ts index 8547f7f4..eb332f9c 100644 --- a/src/controllers/api/retrievePetFromStasisController.ts +++ b/src/controllers/api/retrievePetFromStasisController.ts @@ -1,7 +1,7 @@ import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { getInventory } from "@/src/services/inventoryService"; import { getAccountIdForRequest } from "@/src/services/loginService"; -import { Status } from "@/src/types/inventoryTypes/inventoryTypes"; +import { Status } from "@/src/types/equipmentTypes"; import { RequestHandler } from "express"; export const retrievePetFromStasisController: RequestHandler = async (req, res) => { diff --git a/src/controllers/api/saveSettingsController.ts b/src/controllers/api/saveSettingsController.ts index 15304626..8aba0cfe 100644 --- a/src/controllers/api/saveSettingsController.ts +++ b/src/controllers/api/saveSettingsController.ts @@ -2,7 +2,7 @@ import { getAccountIdForRequest } from "@/src/services/loginService"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { getInventory } from "@/src/services/inventoryService"; import { RequestHandler } from "express"; -import { ISettings } from "../../types/inventoryTypes/inventoryTypes"; +import { ISettings } from "@/src/types/inventoryTypes/inventoryTypes"; interface ISaveSettingsRequest { Settings: ISettings; diff --git a/src/controllers/api/sellController.ts b/src/controllers/api/sellController.ts index 7e2926ae..c82d3b6b 100644 --- a/src/controllers/api/sellController.ts +++ b/src/controllers/api/sellController.ts @@ -15,7 +15,7 @@ import { InventorySlot } from "@/src/types/inventoryTypes/inventoryTypes"; import { ExportDojoRecipes } from "warframe-public-export-plus"; import { IInventoryChanges } from "@/src/types/purchaseTypes"; import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; -import { sendWsBroadcastTo } from "@/src/services/webService"; +import { sendWsBroadcastTo } from "@/src/services/wsService"; export const sellController: RequestHandler = async (req, res) => { const payload = JSON.parse(String(req.body)) as ISellRequest; diff --git a/src/controllers/api/setBootLocationController.ts b/src/controllers/api/setBootLocationController.ts index 1baa5daa..dfccd1d7 100644 --- a/src/controllers/api/setBootLocationController.ts +++ b/src/controllers/api/setBootLocationController.ts @@ -1,7 +1,7 @@ import { RequestHandler } from "express"; import { getAccountIdForRequest } from "@/src/services/loginService"; import { getPersonalRooms } from "@/src/services/personalRoomsService"; -import { TBootLocation } from "@/src/types/shipTypes"; +import { TBootLocation } from "@/src/types/personalRoomsTypes"; import { getInventory } from "@/src/services/inventoryService"; export const setBootLocationController: RequestHandler = async (req, res) => { diff --git a/src/controllers/api/setPlacedDecoInfoController.ts b/src/controllers/api/setPlacedDecoInfoController.ts index 19f76061..83b44009 100644 --- a/src/controllers/api/setPlacedDecoInfoController.ts +++ b/src/controllers/api/setPlacedDecoInfoController.ts @@ -1,5 +1,5 @@ import { getAccountIdForRequest } from "@/src/services/loginService"; -import { IPictureFrameInfo, ISetPlacedDecoInfoRequest } from "@/src/types/shipTypes"; +import { IPictureFrameInfo, ISetPlacedDecoInfoRequest } from "@/src/types/personalRoomsTypes"; import { RequestHandler } from "express"; import { handleSetPlacedDecoInfo } from "@/src/services/shipCustomizationsService"; diff --git a/src/controllers/api/setShipCustomizationsController.ts b/src/controllers/api/setShipCustomizationsController.ts index 01198665..286e416b 100644 --- a/src/controllers/api/setShipCustomizationsController.ts +++ b/src/controllers/api/setShipCustomizationsController.ts @@ -1,6 +1,6 @@ import { getAccountIdForRequest } from "@/src/services/loginService"; import { setShipCustomizations } from "@/src/services/shipCustomizationsService"; -import { ISetShipCustomizationsRequest } from "@/src/types/shipTypes"; +import { ISetShipCustomizationsRequest } from "@/src/types/personalRoomsTypes"; import { logger } from "@/src/utils/logger"; import { RequestHandler } from "express"; diff --git a/src/controllers/api/setShipFavouriteLoadoutController.ts b/src/controllers/api/setShipFavouriteLoadoutController.ts index a7df934f..07b646df 100644 --- a/src/controllers/api/setShipFavouriteLoadoutController.ts +++ b/src/controllers/api/setShipFavouriteLoadoutController.ts @@ -3,7 +3,7 @@ import { RequestHandler } from "express"; import { getPersonalRooms } from "@/src/services/personalRoomsService"; import { IOid } from "@/src/types/commonTypes"; import { Types } from "mongoose"; -import { IFavouriteLoadoutDatabase, TBootLocation } from "@/src/types/shipTypes"; +import { IFavouriteLoadoutDatabase, TBootLocation } from "@/src/types/personalRoomsTypes"; export const setShipFavouriteLoadoutController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); diff --git a/src/controllers/api/setSuitInfectionController.ts b/src/controllers/api/setSuitInfectionController.ts index b4a169d9..84bd0a4b 100644 --- a/src/controllers/api/setSuitInfectionController.ts +++ b/src/controllers/api/setSuitInfectionController.ts @@ -2,7 +2,7 @@ import { fromMongoDate, fromOid } from "@/src/helpers/inventoryHelpers"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { getInventory } from "@/src/services/inventoryService"; import { getAccountIdForRequest } from "@/src/services/loginService"; -import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes"; +import { IEquipmentClient } from "@/src/types/equipmentTypes"; import { RequestHandler } from "express"; export const setSuitInfectionController: RequestHandler = async (req, res) => { diff --git a/src/controllers/api/shipDecorationsController.ts b/src/controllers/api/shipDecorationsController.ts index be09fe9f..c56c0a8d 100644 --- a/src/controllers/api/shipDecorationsController.ts +++ b/src/controllers/api/shipDecorationsController.ts @@ -1,5 +1,5 @@ import { getAccountIdForRequest } from "@/src/services/loginService"; -import { IShipDecorationsRequest } from "@/src/types/shipTypes"; +import { IShipDecorationsRequest } from "@/src/types/personalRoomsTypes"; import { logger } from "@/src/utils/logger"; import { RequestHandler } from "express"; import { handleSetShipDecorations } from "@/src/services/shipCustomizationsService"; diff --git a/src/controllers/api/syndicateStandingBonusController.ts b/src/controllers/api/syndicateStandingBonusController.ts index f5f0a5d2..1691aa68 100644 --- a/src/controllers/api/syndicateStandingBonusController.ts +++ b/src/controllers/api/syndicateStandingBonusController.ts @@ -6,7 +6,7 @@ import { IOid } from "@/src/types/commonTypes"; import { ExportSyndicates, ExportWeapons } from "warframe-public-export-plus"; import { logger } from "@/src/utils/logger"; import { IAffiliationMods, IInventoryChanges } from "@/src/types/purchaseTypes"; -import { EquipmentFeatures } from "@/src/types/inventoryTypes/commonInventoryTypes"; +import { EquipmentFeatures } from "@/src/types/equipmentTypes"; export const syndicateStandingBonusController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); diff --git a/src/controllers/api/umbraController.ts b/src/controllers/api/umbraController.ts index e89ca74d..88529662 100644 --- a/src/controllers/api/umbraController.ts +++ b/src/controllers/api/umbraController.ts @@ -2,7 +2,7 @@ import { fromMongoDate, fromOid } from "@/src/helpers/inventoryHelpers"; import { getJSONfromString } from "@/src/helpers/stringHelpers"; import { addMiscItem, getInventory } from "@/src/services/inventoryService"; import { getAccountIdForRequest } from "@/src/services/loginService"; -import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes"; +import { IEquipmentClient } from "@/src/types/equipmentTypes"; import { RequestHandler } from "express"; export const umbraController: RequestHandler = async (req, res) => { diff --git a/src/controllers/api/upgradesController.ts b/src/controllers/api/upgradesController.ts index 7b112ce3..545e0038 100644 --- a/src/controllers/api/upgradesController.ts +++ b/src/controllers/api/upgradesController.ts @@ -1,11 +1,6 @@ import { RequestHandler } from "express"; import { IUpgradesRequest } from "@/src/types/requestTypes"; -import { - ArtifactPolarity, - IEquipmentDatabase, - EquipmentFeatures, - IAbilityOverride -} from "@/src/types/inventoryTypes/commonInventoryTypes"; +import { ArtifactPolarity, IAbilityOverride } from "@/src/types/inventoryTypes/commonInventoryTypes"; import { IInventoryClient, IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes"; import { getAccountIdForRequest } from "@/src/services/loginService"; import { addMiscItems, addRecipes, getInventory, updateCurrency } from "@/src/services/inventoryService"; @@ -13,7 +8,8 @@ import { getRecipeByResult } from "@/src/services/itemDataService"; import { IInventoryChanges } from "@/src/types/purchaseTypes"; import { addInfestedFoundryXP, applyCheatsToInfestedFoundry } from "@/src/services/infestedFoundryService"; import { config } from "@/src/services/configService"; -import { sendWsBroadcastTo } from "@/src/services/webService"; +import { sendWsBroadcastTo } from "@/src/services/wsService"; +import { EquipmentFeatures, IEquipmentDatabase } from "@/src/types/equipmentTypes"; export const upgradesController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); diff --git a/src/controllers/custom/addXpController.ts b/src/controllers/custom/addXpController.ts index 7e42deb3..575fe978 100644 --- a/src/controllers/custom/addXpController.ts +++ b/src/controllers/custom/addXpController.ts @@ -1,7 +1,7 @@ import { applyClientEquipmentUpdates, getInventory } from "@/src/services/inventoryService"; import { getAccountIdForRequest } from "@/src/services/loginService"; import { IOid } from "@/src/types/commonTypes"; -import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes"; +import { IEquipmentClient } from "@/src/types/equipmentTypes"; import { TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes"; import { RequestHandler } from "express"; import { ExportMisc } from "warframe-public-export-plus"; diff --git a/src/controllers/custom/configController.ts b/src/controllers/custom/configController.ts index 2249f48f..d64a3e3b 100644 --- a/src/controllers/custom/configController.ts +++ b/src/controllers/custom/configController.ts @@ -2,7 +2,7 @@ import { RequestHandler } from "express"; import { config } from "@/src/services/configService"; import { getAccountForRequest, isAdministrator } from "@/src/services/loginService"; import { saveConfig } from "@/src/services/configWatcherService"; -import { sendWsBroadcastExcept } from "@/src/services/webService"; +import { sendWsBroadcastExcept } from "@/src/services/wsService"; export const getConfigController: RequestHandler = async (req, res) => { const account = await getAccountForRequest(req); diff --git a/src/controllers/custom/getItemListsController.ts b/src/controllers/custom/getItemListsController.ts index 95f85b01..d065d2e2 100644 --- a/src/controllers/custom/getItemListsController.ts +++ b/src/controllers/custom/getItemListsController.ts @@ -21,6 +21,7 @@ import { TRelicQuality } from "warframe-public-export-plus"; import allIncarnons from "@/static/fixed_responses/allIncarnonList.json"; +import varzia from "@/static/fixed_responses/worldState/varzia.json"; interface ListedItem { uniqueName: string; @@ -55,6 +56,7 @@ interface ItemLists { EvolutionProgress: ListedItem[]; mods: ListedItem[]; Boosters: ListedItem[]; + VarziaOffers: ListedItem[]; //circuitGameModes: ListedItem[]; } @@ -91,7 +93,8 @@ const getItemListsController: RequestHandler = (req, response) => { KubrowPets: [], EvolutionProgress: [], mods: [], - Boosters: [] + Boosters: [], + VarziaOffers: [] /*circuitGameModes: [ { uniqueName: "Survival", @@ -338,6 +341,13 @@ const getItemListsController: RequestHandler = (req, response) => { }); } + for (const item of Object.values(varzia.primeDualPacks)) { + res.VarziaOffers.push({ + uniqueName: item.ItemType, + name: getString(getItemName(item.ItemType) || "", lang) + }); + } + response.json(res); }; diff --git a/src/controllers/custom/webuiFileChangeDetectedController.ts b/src/controllers/custom/webuiFileChangeDetectedController.ts index aa6af978..5078b679 100644 --- a/src/controllers/custom/webuiFileChangeDetectedController.ts +++ b/src/controllers/custom/webuiFileChangeDetectedController.ts @@ -1,5 +1,5 @@ import { args } from "@/src/helpers/commandLineArguments"; -import { sendWsBroadcast } from "@/src/services/webService"; +import { sendWsBroadcast } from "@/src/services/wsService"; import { RequestHandler } from "express"; export const webuiFileChangeDetectedController: RequestHandler = (req, res) => { diff --git a/src/controllers/dynamic/getProfileViewingDataController.ts b/src/controllers/dynamic/getProfileViewingDataController.ts index bc12c6d6..221eaebb 100644 --- a/src/controllers/dynamic/getProfileViewingDataController.ts +++ b/src/controllers/dynamic/getProfileViewingDataController.ts @@ -6,13 +6,11 @@ import { Account } from "@/src/models/loginModel"; import { Stats, TStatsDatabaseDocument } from "@/src/models/statsModel"; import { allDailyAffiliationKeys } from "@/src/services/inventoryService"; import { IMongoDate, IOid } from "@/src/types/commonTypes"; -import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes"; import { IAffiliation, IAlignment, IChallengeProgress, IDailyAffiliations, - ILoadoutConfigClient, IMission, IPlayerSkills, ITypeXPItem @@ -23,6 +21,8 @@ import { ExportCustoms, ExportDojoRecipes } from "warframe-public-export-plus"; import { IStatsClient } from "@/src/types/statTypes"; import { toStoreItem } from "@/src/services/itemDataService"; import { FlattenMaps } from "mongoose"; +import { IEquipmentClient } from "@/src/types/equipmentTypes"; +import { ILoadoutConfigClient } from "@/src/types/saveLoadoutTypes"; const getProfileViewingDataByPlayerIdImpl = async (playerId: string): Promise => { const account = await Account.findById(playerId, "DisplayName"); diff --git a/src/helpers/customHelpers/customHelpers.ts b/src/helpers/customHelpers/customHelpers.ts index 02defc8c..0f920406 100644 --- a/src/helpers/customHelpers/customHelpers.ts +++ b/src/helpers/customHelpers/customHelpers.ts @@ -1,7 +1,7 @@ import { IAccountCreation } from "@/src/types/customTypes"; import { IDatabaseAccountRequiredFields } from "@/src/types/loginTypes"; import crypto from "crypto"; -import { isString, parseEmail, parseString } from "../general"; +import { isString, parseEmail, parseString } from "@/src/helpers/general"; const getWhirlpoolHash = (rawPassword: string): string => { const whirlpool = crypto.createHash("whirlpool"); diff --git a/src/helpers/general.ts b/src/helpers/general.ts index bd30dcc9..ed448d84 100644 --- a/src/helpers/general.ts +++ b/src/helpers/general.ts @@ -9,11 +9,11 @@ export const isEmptyObject = (obj: object): boolean => { }; */ -const isString = (text: unknown): text is string => { +export const isString = (text: unknown): text is string => { return typeof text === "string" || text instanceof String; }; -const parseString = (data: unknown): string => { +export const parseString = (data: unknown): string => { if (!isString(data)) { throw new Error("data is not a string"); } @@ -21,11 +21,11 @@ const parseString = (data: unknown): string => { return data; }; -const isNumber = (number: unknown): number is number => { +export const isNumber = (number: unknown): number is number => { return typeof number === "number" && !isNaN(number); }; -const parseNumber = (data: unknown): number => { +export const parseNumber = (data: unknown): number => { if (!isNumber(data)) { throw new Error("data is not a number"); } @@ -33,11 +33,11 @@ const parseNumber = (data: unknown): number => { return Number(data); }; -const isDate = (date: string): boolean => { +export const isDate = (date: string): boolean => { return Date.parse(date) != 0; }; -const parseDateNumber = (date: unknown): string => { +export const parseDateNumber = (date: unknown): string => { if (!isString(date) || !isDate(date)) { throw new Error("date could not be parsed"); } @@ -45,18 +45,18 @@ const parseDateNumber = (date: unknown): string => { return date; }; -const parseEmail = (email: unknown): string => { +export const parseEmail = (email: unknown): string => { if (!isString(email)) { throw new Error("incorrect email"); } return email; }; -const isBoolean = (booleanCandidate: unknown): booleanCandidate is boolean => { +export const isBoolean = (booleanCandidate: unknown): booleanCandidate is boolean => { return typeof booleanCandidate === "boolean"; }; -const parseBoolean = (booleanCandidate: unknown): boolean => { +export const parseBoolean = (booleanCandidate: unknown): boolean => { if (!isBoolean(booleanCandidate)) { throw new Error("argument was not a boolean"); } @@ -70,5 +70,3 @@ export const isObject = (objectCandidate: unknown): objectCandidate is Record = { "/Lotus/Weapons/SolarisUnited/Primary/LotusModularPrimary": "LongGuns", diff --git a/src/helpers/nemesisHelpers.ts b/src/helpers/nemesisHelpers.ts index 4a5de0fb..641ccb27 100644 --- a/src/helpers/nemesisHelpers.ts +++ b/src/helpers/nemesisHelpers.ts @@ -1,12 +1,9 @@ import { ExportRegions, ExportWarframes } from "warframe-public-export-plus"; import { IInfNode, TNemesisFaction } from "@/src/types/inventoryTypes/inventoryTypes"; -import { getRewardAtPercentage, SRng } from "@/src/services/rngService"; -import { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel"; -import { logger } from "../utils/logger"; -import { IOid } from "../types/commonTypes"; -import { Types } from "mongoose"; -import { addMods, generateRewardSeed } from "../services/inventoryService"; -import { isArchwingMission } from "../services/worldStateService"; +import { generateRewardSeed, getRewardAtPercentage, SRng } from "@/src/services/rngService"; +import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; +import { IOid } from "@/src/types/commonTypes"; +import { isArchwingMission } from "@/src/services/worldStateService"; type TInnateDamageTag = | "InnateElectricityDamage" @@ -364,57 +361,6 @@ export const parseUpgrade = ( } }; -export const consumeModCharge = ( - response: IKnifeResponse, - inventory: TInventoryDatabaseDocument, - upgrade: { ItemId: IOid; ItemType: string }, - dataknifeUpgrades: string[] -): void => { - response.UpgradeIds ??= []; - response.UpgradeTypes ??= []; - response.UpgradeFingerprints ??= []; - response.UpgradeNew ??= []; - response.HasKnife = true; - - if (upgrade.ItemId.$oid != "000000000000000000000000") { - const dbUpgrade = inventory.Upgrades.id(upgrade.ItemId.$oid)!; - const fingerprint = JSON.parse(dbUpgrade.UpgradeFingerprint!) as { lvl: number }; - fingerprint.lvl += 1; - dbUpgrade.UpgradeFingerprint = JSON.stringify(fingerprint); - - response.UpgradeIds.push(upgrade.ItemId.$oid); - response.UpgradeTypes.push(upgrade.ItemType); - response.UpgradeFingerprints.push(fingerprint); - response.UpgradeNew.push(false); - } else { - const id = new Types.ObjectId(); - inventory.Upgrades.push({ - _id: id, - ItemType: upgrade.ItemType, - UpgradeFingerprint: `{"lvl":1}` - }); - - addMods(inventory, [ - { - ItemType: upgrade.ItemType, - ItemCount: -1 - } - ]); - - const dataknifeRawUpgradeIndex = dataknifeUpgrades.indexOf(upgrade.ItemType); - if (dataknifeRawUpgradeIndex != -1) { - dataknifeUpgrades[dataknifeRawUpgradeIndex] = id.toString(); - } else { - logger.warn(`${upgrade.ItemType} not found in dataknife config`); - } - - response.UpgradeIds.push(id.toString()); - response.UpgradeTypes.push(upgrade.ItemType); - response.UpgradeFingerprints.push({ lvl: 1 }); - response.UpgradeNew.push(true); - } -}; - export const getInnateDamageTag = (KillingSuit: string): TInnateDamageTag => { return ExportWarframes[KillingSuit].nemesisUpgradeTag!; }; diff --git a/src/helpers/relicHelper.ts b/src/helpers/relicHelper.ts index 6889514e..3c663692 100644 --- a/src/helpers/relicHelper.ts +++ b/src/helpers/relicHelper.ts @@ -5,8 +5,8 @@ import { getRandomWeightedReward, IRngResult } from "@/src/services/rngService"; import { logger } from "@/src/utils/logger"; import { addMiscItems, combineInventoryChanges } from "@/src/services/inventoryService"; import { handleStoreItemAcquisition } from "@/src/services/purchaseService"; -import { IInventoryChanges } from "../types/purchaseTypes"; -import { config } from "../services/configService"; +import { IInventoryChanges } from "@/src/types/purchaseTypes"; +import { config } from "@/src/services/configService"; export const crackRelic = async ( inventory: TInventoryDatabaseDocument, diff --git a/src/helpers/rivenHelper.ts b/src/helpers/rivenHelper.ts index 34a7babc..7b2be304 100644 --- a/src/helpers/rivenHelper.ts +++ b/src/helpers/rivenHelper.ts @@ -1,5 +1,5 @@ import { IUpgrade } from "warframe-public-export-plus"; -import { getRandomElement, getRandomInt, getRandomReward } from "../services/rngService"; +import { getRandomElement, getRandomInt, getRandomReward } from "@/src/services/rngService"; export type RivenFingerprint = IVeiledRivenFingerprint | IUnveiledRivenFingerprint; diff --git a/src/index.ts b/src/index.ts index 53dfcd90..383e9123 100644 --- a/src/index.ts +++ b/src/index.ts @@ -19,10 +19,10 @@ logger.info("Starting up..."); // Proceed with normal startup: bring up config watcher service, validate config, connect to MongoDB, and finally start listening for HTTP. import mongoose from "mongoose"; import { JSONStringify } from "json-with-bigint"; -import { startWebServer } from "./services/webService"; +import { startWebServer } from "@/src/services/webService"; import { syncConfigWithDatabase, validateConfig } from "@/src/services/configWatcherService"; -import { updateWorldStateCollections } from "./services/worldStateService"; +import { updateWorldStateCollections } from "@/src/services/worldStateService"; // Patch JSON.stringify to work flawlessly with Bigints. JSON.stringify = JSONStringify; diff --git a/src/middleware/errorHandler.ts b/src/middleware/errorHandler.ts index 45f69062..3ffb61cf 100644 --- a/src/middleware/errorHandler.ts +++ b/src/middleware/errorHandler.ts @@ -1,5 +1,5 @@ import { NextFunction, Request, Response } from "express"; -import { logger } from "../utils/logger"; +import { logger } from "@/src/utils/logger"; export const errorHandler = (err: Error, req: Request, res: Response, _next: NextFunction): void => { if (err.message == "Invalid accountId-nonce pair") { diff --git a/src/models/commonModel.ts b/src/models/commonModel.ts new file mode 100644 index 00000000..dd0ad85e --- /dev/null +++ b/src/models/commonModel.ts @@ -0,0 +1,25 @@ +import { Schema } from "mongoose"; +import { IColor, IShipCustomization } from "@/src/types/inventoryTypes/commonInventoryTypes"; + +export const colorSchema = new Schema( + { + t0: Number, + t1: Number, + t2: Number, + t3: Number, + en: Number, + e1: Number, + m0: Number, + m1: Number + }, + { _id: false } +); + +export const shipCustomizationSchema = new Schema( + { + SkinFlavourItem: String, + Colors: colorSchema, + ShipAttachments: { HOOD_ORNAMENT: String } + }, + { _id: false } +); diff --git a/src/models/guildModel.ts b/src/models/guildModel.ts index c393a38d..75492bc2 100644 --- a/src/models/guildModel.ts +++ b/src/models/guildModel.ts @@ -17,8 +17,8 @@ import { GuildPermission } from "@/src/types/guildTypes"; import { Document, Model, model, Schema, Types } from "mongoose"; -import { fusionTreasuresSchema, typeCountSchema } from "./inventoryModels/inventoryModel"; -import { pictureFrameInfoSchema } from "./personalRoomsModel"; +import { fusionTreasuresSchema, typeCountSchema } from "@/src/models/inventoryModels/inventoryModel"; +import { pictureFrameInfoSchema } from "@/src/models/personalRoomsModel"; const dojoDecoSchema = new Schema({ Type: String, diff --git a/src/models/inboxModel.ts b/src/models/inboxModel.ts index 793d37d8..be6b0cd5 100644 --- a/src/models/inboxModel.ts +++ b/src/models/inboxModel.ts @@ -1,8 +1,7 @@ import { model, Schema, Types } from "mongoose"; import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers"; import { typeCountSchema } from "@/src/models/inventoryModels/inventoryModel"; -import { IMongoDate, IOid } from "@/src/types/commonTypes"; -import { ITypeCount } from "@/src/types/inventoryTypes/inventoryTypes"; +import { IMongoDate, IOid, ITypeCount } from "@/src/types/commonTypes"; export interface IMessageClient extends Omit { diff --git a/src/models/inventoryModels/inventoryModel.ts b/src/models/inventoryModels/inventoryModel.ts index 067e44a5..fe9a683a 100644 --- a/src/models/inventoryModels/inventoryModel.ts +++ b/src/models/inventoryModels/inventoryModel.ts @@ -1,6 +1,5 @@ import { Document, Model, Schema, Types, model } from "mongoose"; import { - IFlavourItem, IRawUpgrade, IMiscItem, IInventoryDatabase, @@ -10,7 +9,6 @@ import { IDuviriInfo, IPendingRecipeDatabase, IPendingRecipeClient, - ITypeCount, IFocusXP, IFocusUpgrade, ITypeXPItem, @@ -39,25 +37,15 @@ import { IEvolutionProgress, IEndlessXpProgressDatabase, IEndlessXpProgressClient, - ICrewShipCustomization, - ICrewShipWeapon, - ICrewShipWeaponEmplacements, - IShipExterior, IHelminthFoodRecord, - ICrewShipMembersDatabase, IDialogueHistoryDatabase, IDialogueDatabase, IDialogueGift, ICompletedDialogue, IDialogueClient, IUpgradeDatabase, - ICrewShipMemberDatabase, - ICrewShipMemberClient, TEquipmentKey, equipmentKeys, - IKubrowPetDetailsDatabase, - ITraits, - IKubrowPetDetailsClient, IKubrowPetEggDatabase, IKubrowPetEggClient, ICustomMarkers, @@ -96,27 +84,39 @@ import { IInvasionProgressClient, IAccolades, IHubNpcCustomization, - ILotusCustomization, IEndlessXpReward, IPersonalGoalProgressDatabase, IPersonalGoalProgressClient, IKubrowPetPrintClient, IKubrowPetPrintDatabase -} from "../../types/inventoryTypes/inventoryTypes"; -import { IOid } from "../../types/commonTypes"; +} from "@/src/types/inventoryTypes/inventoryTypes"; +import { IOid, ITypeCount } from "@/src/types/commonTypes"; import { IAbilityOverride, - IColor, + ICrewShipCustomization, + IFlavourItem, IItemConfig, + ILotusCustomization, IOperatorConfigDatabase, - IPolarity, - IEquipmentDatabase, - IArchonCrystalUpgrade, - IEquipmentClient + IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers"; -import { EquipmentSelectionSchema, oidSchema } from "./loadoutModel"; +import { EquipmentSelectionSchema, oidSchema } from "@/src/models/inventoryModels/loadoutModel"; import { ICountedStoreItem } from "warframe-public-export-plus"; +import { colorSchema, shipCustomizationSchema } from "@/src/models/commonModel"; +import { + IArchonCrystalUpgrade, + ICrewShipMemberClient, + ICrewShipMemberDatabase, + ICrewShipMembersDatabase, + ICrewShipWeapon, + ICrewShipWeaponEmplacements, + IEquipmentClient, + IEquipmentDatabase, + IKubrowPetDetailsClient, + IKubrowPetDetailsDatabase, + ITraits +} from "@/src/types/equipmentTypes"; export const typeCountSchema = new Schema({ ItemType: String, ItemCount: Number }, { _id: false }); @@ -166,20 +166,6 @@ const abilityOverrideSchema = new Schema( { _id: false } ); -export const colorSchema = new Schema( - { - t0: Number, - t1: Number, - t2: Number, - t3: Number, - en: Number, - e1: Number, - m0: Number, - m1: Number - }, - { _id: false } -); - const operatorConfigSchema = new Schema( { Skins: [String], @@ -896,18 +882,9 @@ const crewShipWeaponSchema = new Schema( { _id: false } ); -const shipExteriorSchema = new Schema( - { - SkinFlavourItem: String, - Colors: colorSchema, - ShipAttachments: { HOOD_ORNAMENT: String } - }, - { _id: false } -); - const crewShipCustomizationSchema = new Schema( { - CrewshipInterior: shipExteriorSchema + CrewshipInterior: shipCustomizationSchema }, { _id: false } ); diff --git a/src/models/inventoryModels/loadoutModel.ts b/src/models/inventoryModels/loadoutModel.ts index 208b9e17..a06a7846 100644 --- a/src/models/inventoryModels/loadoutModel.ts +++ b/src/models/inventoryModels/loadoutModel.ts @@ -1,5 +1,5 @@ import { IOid } from "@/src/types/commonTypes"; -import { IEquipmentSelection } from "@/src/types/inventoryTypes/commonInventoryTypes"; +import { IEquipmentSelection } from "@/src/types/equipmentTypes"; import { ILoadoutConfigDatabase, ILoadoutDatabase } from "@/src/types/saveLoadoutTypes"; import { Document, Model, Schema, Types, model } from "mongoose"; diff --git a/src/models/leaderboardModel.ts b/src/models/leaderboardModel.ts index 2db984d3..591f36e3 100644 --- a/src/models/leaderboardModel.ts +++ b/src/models/leaderboardModel.ts @@ -1,5 +1,5 @@ import { Document, model, Schema, Types } from "mongoose"; -import { ILeaderboardEntryDatabase } from "../types/leaderboardTypes"; +import { ILeaderboardEntryDatabase } from "@/src/types/leaderboardTypes"; const leaderboardEntrySchema = new Schema( { diff --git a/src/models/personalRoomsModel.ts b/src/models/personalRoomsModel.ts index 20f94a9a..965fa1dd 100644 --- a/src/models/personalRoomsModel.ts +++ b/src/models/personalRoomsModel.ts @@ -1,19 +1,22 @@ import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers"; -import { colorSchema } from "@/src/models/inventoryModels/inventoryModel"; -import { IOrbiter, IPersonalRoomsDatabase, PersonalRoomsModelType } from "@/src/types/personalRoomsTypes"; import { + IApartmentDatabase, IFavouriteLoadoutDatabase, IGardeningDatabase, - IPlacedDecosDatabase, + IOrbiterClient, + IOrbiterDatabase, + IPersonalRoomsDatabase, IPictureFrameInfo, + IPlacedDecosDatabase, + IPlantClient, + IPlantDatabase, + IPlanterDatabase, IRoom, ITailorShopDatabase, - IApartmentDatabase, - IPlanterDatabase, - IPlantDatabase, - IPlantClient -} from "@/src/types/shipTypes"; + PersonalRoomsModelType +} from "@/src/types/personalRoomsTypes"; import { Schema, Types, model } from "mongoose"; +import { colorSchema, shipCustomizationSchema } from "@/src/models/commonModel"; export const pictureFrameInfoSchema = new Schema( { @@ -137,10 +140,11 @@ const apartmentDefault: IApartmentDatabase = { } }; -const orbiterSchema = new Schema( +const orbiterSchema = new Schema( { Features: [String], Rooms: [roomSchema], + ShipInterior: shipCustomizationSchema, VignetteFish: { type: [String], default: undefined }, FavouriteLoadoutId: Schema.Types.ObjectId, Wallpaper: String, @@ -150,7 +154,18 @@ const orbiterSchema = new Schema( }, { _id: false } ); -const orbiterDefault: IOrbiter = { +orbiterSchema.set("toJSON", { + virtuals: true, + transform(_doc, obj) { + const db = obj as IOrbiterDatabase; + const client = obj as IOrbiterClient; + + if (db.FavouriteLoadoutId) { + client.FavouriteLoadoutId = toOid(db.FavouriteLoadoutId); + } + } +}); +const orbiterDefault: IOrbiterDatabase = { Features: ["/Lotus/Types/Items/ShipFeatureItems/EarthNavigationFeatureItem"], //TODO: potentially remove after missionstarting gear Rooms: [ { Name: "AlchemyRoom", MaxCapacity: 1600 }, @@ -197,7 +212,6 @@ const tailorShopDefault: ITailorShopDatabase = { export const personalRoomsSchema = new Schema({ personalRoomsOwnerId: Schema.Types.ObjectId, activeShipId: Schema.Types.ObjectId, - ShipInteriorColors: colorSchema, Ship: { type: orbiterSchema, default: orbiterDefault }, Apartment: { type: apartmentSchema, default: apartmentDefault }, TailorShop: { type: tailorShopSchema, default: tailorShopDefault } diff --git a/src/models/shipModel.ts b/src/models/shipModel.ts index a1cd1457..9b4bd98d 100644 --- a/src/models/shipModel.ts +++ b/src/models/shipModel.ts @@ -1,7 +1,7 @@ import { Document, Schema, Types, model } from "mongoose"; -import { IShipDatabase } from "../types/shipTypes"; +import { IShipDatabase } from "@/src/types/shipTypes"; import { toOid } from "@/src/helpers/inventoryHelpers"; -import { colorSchema } from "@/src/models/inventoryModels/inventoryModel"; +import { colorSchema } from "@/src/models/commonModel"; import { IShipInventory } from "@/src/types/inventoryTypes/inventoryTypes"; const shipSchema = new Schema( diff --git a/src/services/configService.ts b/src/services/configService.ts index 6b20c91d..36efe7e2 100644 --- a/src/services/configService.ts +++ b/src/services/configService.ts @@ -89,6 +89,8 @@ export interface IConfig { allTheFissures?: string; circuitGameModes?: string[]; darvoStockMultiplier?: number; + varziaOverride?: string; + varziaFullyStocked?: boolean; }; dev?: { keepVendorsExpired?: boolean; diff --git a/src/services/configWatcherService.ts b/src/services/configWatcherService.ts index 4dea6eea..99a0dd64 100644 --- a/src/services/configWatcherService.ts +++ b/src/services/configWatcherService.ts @@ -1,9 +1,11 @@ import chokidar from "chokidar"; import fsPromises from "fs/promises"; -import { logger } from "../utils/logger"; -import { config, configPath, loadConfig } from "./configService"; -import { getWebPorts, sendWsBroadcast, startWebServer, stopWebServer } from "./webService"; -import { Inbox } from "../models/inboxModel"; +import { logger } from "@/src/utils/logger"; +import { config, configPath, loadConfig } from "@/src/services/configService"; +import { getWebPorts, startWebServer, stopWebServer } from "@/src/services/webService"; +import { sendWsBroadcast } from "@/src/services/wsService"; +import { Inbox } from "@/src/models/inboxModel"; +import varzia from "@/static/fixed_responses/worldState/varzia.json"; let amnesia = false; chokidar.watch(configPath).on("change", () => { @@ -57,6 +59,13 @@ export const validateConfig = (): void => { config.worldState.galleonOfGhouls = 0; modified = true; } + if ( + config.worldState?.varziaOverride && + !varzia.primeDualPacks.some(p => p.ItemType === config.worldState?.varziaOverride) + ) { + config.worldState.varziaOverride = ""; + modified = true; + } if (modified) { logger.info(`Updating config file to fix some issues with it.`); void saveConfig(); diff --git a/src/services/friendService.ts b/src/services/friendService.ts index 7affefec..125dfda1 100644 --- a/src/services/friendService.ts +++ b/src/services/friendService.ts @@ -1,10 +1,10 @@ -import { IFriendInfo } from "../types/friendTypes"; -import { getInventory } from "./inventoryService"; -import { config } from "./configService"; -import { Account } from "../models/loginModel"; +import { IFriendInfo } from "@/src/types/friendTypes"; +import { getInventory } from "@/src/services/inventoryService"; +import { config } from "@/src/services/configService"; +import { Account } from "@/src/models/loginModel"; import { Types } from "mongoose"; -import { Friendship } from "../models/friendModel"; -import { fromOid, toMongoDate } from "../helpers/inventoryHelpers"; +import { Friendship } from "@/src/models/friendModel"; +import { fromOid, toMongoDate } from "@/src/helpers/inventoryHelpers"; export const addAccountDataToFriendInfo = async (info: IFriendInfo): Promise => { const account = (await Account.findById(fromOid(info._id), "DisplayName LastLogin"))!; diff --git a/src/services/guildService.ts b/src/services/guildService.ts index 87e2f721..2b4e4f2f 100644 --- a/src/services/guildService.ts +++ b/src/services/guildService.ts @@ -22,16 +22,17 @@ import { import { toMongoDate, toOid, toOid2 } from "@/src/helpers/inventoryHelpers"; import { Types } from "mongoose"; import { ExportDojoRecipes, ExportResources, IDojoBuild, IDojoResearch } from "warframe-public-export-plus"; -import { logger } from "../utils/logger"; -import { config } from "./configService"; -import { getRandomInt } from "./rngService"; -import { Inbox } from "../models/inboxModel"; -import { IFusionTreasure, ITypeCount } from "../types/inventoryTypes/inventoryTypes"; -import { IInventoryChanges } from "../types/purchaseTypes"; -import { parallelForeach } from "../utils/async-utils"; +import { logger } from "@/src/utils/logger"; +import { config } from "@/src/services/configService"; +import { getRandomInt } from "@/src/services/rngService"; +import { Inbox } from "@/src/models/inboxModel"; +import { IFusionTreasure } from "@/src/types/inventoryTypes/inventoryTypes"; +import { IInventoryChanges } from "@/src/types/purchaseTypes"; +import { parallelForeach } from "@/src/utils/async-utils"; import allDecoRecipes from "@/static/fixed_responses/allDecoRecipes.json"; -import { createMessage } from "./inboxService"; -import { addAccountDataToFriendInfo, addInventoryDataToFriendInfo } from "./friendService"; +import { createMessage } from "@/src/services/inboxService"; +import { addAccountDataToFriendInfo, addInventoryDataToFriendInfo } from "@/src/services/friendService"; +import { ITypeCount } from "@/src/types/commonTypes"; export const getGuildForRequest = async (req: Request): Promise => { const accountId = await getAccountIdForRequest(req); diff --git a/src/services/importService.ts b/src/services/importService.ts index 29eee138..0e07dbb3 100644 --- a/src/services/importService.ts +++ b/src/services/importService.ts @@ -1,18 +1,12 @@ import { Types } from "mongoose"; import { - IEquipmentClient, - IEquipmentDatabase, IItemConfig, IOperatorConfigClient, IOperatorConfigDatabase -} from "../types/inventoryTypes/commonInventoryTypes"; -import { IMongoDate } from "../types/commonTypes"; +} from "@/src/types/inventoryTypes/commonInventoryTypes"; +import { IMongoDate } from "@/src/types/commonTypes"; import { equipmentKeys, - ICrewShipMemberClient, - ICrewShipMemberDatabase, - ICrewShipMembersClient, - ICrewShipMembersDatabase, IDialogueClient, IDialogueDatabase, IDialogueHistoryClient, @@ -20,10 +14,6 @@ import { IInfestedFoundryClient, IInfestedFoundryDatabase, IInventoryClient, - IKubrowPetDetailsClient, - IKubrowPetDetailsDatabase, - ILoadoutConfigClient, - ILoadOutPresets, INemesisClient, INemesisDatabase, IPendingRecipeClient, @@ -35,10 +25,25 @@ import { IUpgradeDatabase, IWeaponSkinClient, IWeaponSkinDatabase -} from "../types/inventoryTypes/inventoryTypes"; -import { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel"; -import { ILoadoutConfigDatabase, ILoadoutDatabase } from "../types/saveLoadoutTypes"; -import { slotNames } from "../types/purchaseTypes"; +} from "@/src/types/inventoryTypes/inventoryTypes"; +import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; +import { + ILoadoutConfigClient, + ILoadoutConfigDatabase, + ILoadoutDatabase, + ILoadOutPresets +} from "@/src/types/saveLoadoutTypes"; +import { slotNames } from "@/src/types/purchaseTypes"; +import { + ICrewShipMemberClient, + ICrewShipMemberDatabase, + ICrewShipMembersClient, + ICrewShipMembersDatabase, + IEquipmentClient, + IEquipmentDatabase, + IKubrowPetDetailsClient, + IKubrowPetDetailsDatabase +} from "@/src/types/equipmentTypes"; const convertDate = (value: IMongoDate): Date => { return new Date(parseInt(value.$date.$numberLong)); diff --git a/src/services/inboxService.ts b/src/services/inboxService.ts index d623030d..7129adf3 100644 --- a/src/services/inboxService.ts +++ b/src/services/inboxService.ts @@ -2,8 +2,8 @@ import { IMessageDatabase, Inbox } from "@/src/models/inboxModel"; import { getAccountForRequest } from "@/src/services/loginService"; import { HydratedDocument, Types } from "mongoose"; import { Request } from "express"; -import { unixTimesInMs } from "../constants/timeConstants"; -import { config } from "./configService"; +import { unixTimesInMs } from "@/src/constants/timeConstants"; +import { config } from "@/src/services/configService"; export const getAllMessagesSorted = async (accountId: string): Promise[]> => { const inbox = await Inbox.find({ ownerId: accountId }).sort({ date: -1 }); diff --git a/src/services/infestedFoundryService.ts b/src/services/infestedFoundryService.ts index 5afc93fa..3349047b 100644 --- a/src/services/infestedFoundryService.ts +++ b/src/services/infestedFoundryService.ts @@ -1,8 +1,9 @@ import { ExportRecipes } from "warframe-public-export-plus"; -import { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel"; -import { IInfestedFoundryClient, IInfestedFoundryDatabase, ITypeCount } from "../types/inventoryTypes/inventoryTypes"; -import { addRecipes } from "./inventoryService"; -import { config } from "./configService"; +import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; +import { IInfestedFoundryClient, IInfestedFoundryDatabase } from "@/src/types/inventoryTypes/inventoryTypes"; +import { addRecipes } from "@/src/services/inventoryService"; +import { config } from "@/src/services/configService"; +import { ITypeCount } from "@/src/types/commonTypes"; export const addInfestedFoundryXP = (infestedFoundry: IInfestedFoundryDatabase, delta: number): ITypeCount[] => { const recipeChanges: ITypeCount[] = []; diff --git a/src/services/inventoryService.ts b/src/services/inventoryService.ts index 68e6b7cc..6042e34f 100644 --- a/src/services/inventoryService.ts +++ b/src/services/inventoryService.ts @@ -4,12 +4,10 @@ import { Types } from "mongoose"; import { SlotNames, IInventoryChanges, IBinChanges, slotNames, IAffiliationMods } from "@/src/types/purchaseTypes"; import { IChallengeProgress, - IFlavourItem, IMiscItem, IMission, IRawUpgrade, ISeasonChallenge, - ITypeCount, InventorySlot, IWeaponSkinClient, TEquipmentKey, @@ -23,25 +21,17 @@ import { TPartialStartingGear, ILoreFragmentScan, ICrewMemberClient, - Status, - IKubrowPetDetailsDatabase, - ITraits, ICalendarProgress, INemesisWeaponTargetFingerprint, INemesisPetTargetFingerprint, IDialogueDatabase, IKubrowPetPrintClient } from "@/src/types/inventoryTypes/inventoryTypes"; -import { IGenericUpdate, IUpdateNodeIntrosResponse } from "../types/genericUpdate"; -import { IKeyChainRequest, IMissionInventoryUpdateRequest } from "../types/requestTypes"; +import { IGenericUpdate, IUpdateNodeIntrosResponse } from "@/src/types/genericUpdate"; +import { IKeyChainRequest, IMissionInventoryUpdateRequest } from "@/src/types/requestTypes"; import { logger } from "@/src/utils/logger"; import { convertInboxMessage, fromStoreItem, getKeyChainItems } from "@/src/services/itemDataService"; -import { - EquipmentFeatures, - IEquipmentClient, - IEquipmentDatabase, - IItemConfig -} from "../types/inventoryTypes/commonInventoryTypes"; +import { IFlavourItem, IItemConfig } from "@/src/types/inventoryTypes/commonInventoryTypes"; import { ExportArcanes, ExportBoosters, @@ -69,7 +59,7 @@ import { ISentinel, TStandingLimitBin } from "warframe-public-export-plus"; -import { createShip } from "./shipService"; +import { createShip } from "@/src/services/shipService"; import { catbrowDetails, fromMongoDate, @@ -78,19 +68,34 @@ import { kubrowFurPatternsWeights, kubrowWeights, toOid -} from "../helpers/inventoryHelpers"; +} from "@/src/helpers/inventoryHelpers"; import { addQuestKey, completeQuest } from "@/src/services/questService"; -import { handleBundleAcqusition } from "./purchaseService"; +import { handleBundleAcqusition } from "@/src/services/purchaseService"; import libraryDailyTasks from "@/static/fixed_responses/libraryDailyTasks.json"; -import { getRandomElement, getRandomInt, getRandomWeightedReward, SRng } from "./rngService"; -import { createMessage, IMessageCreationTemplate } from "./inboxService"; +import { + generateRewardSeed, + getRandomElement, + getRandomInt, + getRandomWeightedReward, + SRng +} from "@/src/services/rngService"; +import { createMessage, IMessageCreationTemplate } from "@/src/services/inboxService"; import { getMaxStanding, getMinStanding } from "@/src/helpers/syndicateStandingHelper"; -import { getNightwaveSyndicateTag, getWorldState } from "./worldStateService"; +import { getNightwaveSyndicateTag, getWorldState } from "@/src/services/worldStateService"; import { ICalendarSeason } from "@/src/types/worldStateTypes"; -import { generateNemesisProfile, INemesisProfile } from "../helpers/nemesisHelpers"; -import { TAccountDocument } from "./loginService"; -import { unixTimesInMs } from "../constants/timeConstants"; -import { addString } from "../helpers/stringHelpers"; +import { generateNemesisProfile, INemesisProfile } from "@/src/helpers/nemesisHelpers"; +import { TAccountDocument } from "@/src/services/loginService"; +import { unixTimesInMs } from "@/src/constants/timeConstants"; +import { addString } from "@/src/helpers/stringHelpers"; +import { + EquipmentFeatures, + IEquipmentClient, + IEquipmentDatabase, + IKubrowPetDetailsDatabase, + ITraits, + Status +} from "@/src/types/equipmentTypes"; +import { ITypeCount } from "@/src/types/commonTypes"; export const createInventory = async ( accountOwnerId: Types.ObjectId, @@ -132,17 +137,6 @@ export const createInventory = async ( } }; -export const generateRewardSeed = (): bigint => { - const hiDword = getRandomInt(0, 0x7fffffff); - const loDword = getRandomInt(0, 0xffffffff); - let seed = (BigInt(hiDword) << 32n) | BigInt(loDword); - if (Math.random() < 0.5) { - seed *= -1n; - seed -= 1n; - } - return seed; -}; - //TODO: RawUpgrades might need to return a LastAdded const awakeningRewards = [ "/Lotus/Types/StoreItems/AvatarImages/AvatarImageItem1", @@ -1395,7 +1389,11 @@ export const addSkin = ( if (inventory.WeaponSkins.some(x => x.ItemType == typeName)) { logger.debug(`refusing to add WeaponSkin ${typeName} because account already owns it`); } else { - const index = inventory.WeaponSkins.push({ ItemType: typeName, IsNew: true }) - 1; + const index = + inventory.WeaponSkins.push({ + ItemType: typeName, + IsNew: typeName.startsWith("/Lotus/Upgrades/Skins/RailJack/") ? undefined : true // railjack skins are incompatible with this flag + }) - 1; // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition inventoryChanges.WeaponSkins ??= []; (inventoryChanges.WeaponSkins as IWeaponSkinClient[]).push( diff --git a/src/services/itemDataService.ts b/src/services/itemDataService.ts index e028e8c0..954099ff 100644 --- a/src/services/itemDataService.ts +++ b/src/services/itemDataService.ts @@ -17,6 +17,7 @@ import { dict_zh, ExportArcanes, ExportBoosters, + ExportBundles, ExportCustoms, ExportDrones, ExportGear, @@ -32,7 +33,7 @@ import { IRecipe, TReward } from "warframe-public-export-plus"; -import { IMessage } from "../models/inboxModel"; +import { IMessage } from "@/src/models/inboxModel"; export type WeaponTypeInternal = | "LongGuns" @@ -117,6 +118,9 @@ export const getItemName = (uniqueName: string): string | undefined => { if (uniqueName in ExportArcanes) { return ExportArcanes[uniqueName].name; } + if (uniqueName in ExportBundles) { + return ExportBundles[uniqueName].name; + } if (uniqueName in ExportCustoms) { return ExportCustoms[uniqueName].name; } diff --git a/src/services/leaderboardService.ts b/src/services/leaderboardService.ts index 2ef908f7..2032d442 100644 --- a/src/services/leaderboardService.ts +++ b/src/services/leaderboardService.ts @@ -1,6 +1,6 @@ -import { Guild } from "../models/guildModel"; -import { Leaderboard, TLeaderboardEntryDocument } from "../models/leaderboardModel"; -import { ILeaderboardEntryClient } from "../types/leaderboardTypes"; +import { Guild } from "@/src/models/guildModel"; +import { Leaderboard, TLeaderboardEntryDocument } from "@/src/models/leaderboardModel"; +import { ILeaderboardEntryClient } from "@/src/types/leaderboardTypes"; export const submitLeaderboardScore = async ( schedule: "weekly" | "daily", diff --git a/src/services/loginRewardService.ts b/src/services/loginRewardService.ts index 49a6501a..548ba1bb 100644 --- a/src/services/loginRewardService.ts +++ b/src/services/loginRewardService.ts @@ -1,10 +1,10 @@ import randomRewards from "@/static/fixed_responses/loginRewards/randomRewards.json"; -import { IInventoryChanges } from "../types/purchaseTypes"; -import { TAccountDocument } from "./loginService"; -import { mixSeeds, SRng } from "./rngService"; -import { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel"; -import { addBooster, updateCurrency } from "./inventoryService"; -import { handleStoreItemAcquisition } from "./purchaseService"; +import { IInventoryChanges } from "@/src/types/purchaseTypes"; +import { TAccountDocument } from "@/src/services/loginService"; +import { mixSeeds, SRng } from "@/src/services/rngService"; +import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; +import { addBooster, updateCurrency } from "@/src/services/inventoryService"; +import { handleStoreItemAcquisition } from "@/src/services/purchaseService"; import { ExportBoosterPacks, ExportBoosters, @@ -12,7 +12,7 @@ import { ExportWarframes, ExportWeapons } from "warframe-public-export-plus"; -import { toStoreItem } from "./itemDataService"; +import { toStoreItem } from "@/src/services/itemDataService"; export interface ILoginRewardsReponse { DailyTributeInfo: { diff --git a/src/services/loginService.ts b/src/services/loginService.ts index 44366f5c..338f43db 100644 --- a/src/services/loginService.ts +++ b/src/services/loginService.ts @@ -1,7 +1,7 @@ import { Account } from "@/src/models/loginModel"; import { createInventory } from "@/src/services/inventoryService"; import { IDatabaseAccountJson, IDatabaseAccountRequiredFields } from "@/src/types/loginTypes"; -import { createShip } from "./shipService"; +import { createShip } from "@/src/services/shipService"; import { Document, Types } from "mongoose"; import { Loadout } from "@/src/models/inventoryModels/loadoutModel"; import { PersonalRooms } from "@/src/models/personalRoomsModel"; diff --git a/src/services/missionInventoryUpdateService.ts b/src/services/missionInventoryUpdateService.ts index 69e165e7..cc8bd0c2 100644 --- a/src/services/missionInventoryUpdateService.ts +++ b/src/services/missionInventoryUpdateService.ts @@ -8,10 +8,10 @@ import { IRegion, IReward } from "warframe-public-export-plus"; -import { IMissionInventoryUpdateRequest, IRewardInfo } from "../types/requestTypes"; +import { IMissionInventoryUpdateRequest, IRewardInfo } from "@/src/types/requestTypes"; import { logger } from "@/src/utils/logger"; -import { IRngResult, SRng, getRandomElement, getRandomReward } from "@/src/services/rngService"; -import { equipmentKeys, IMission, ITypeCount, TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes"; +import { IRngResult, SRng, generateRewardSeed, getRandomElement, getRandomReward } from "@/src/services/rngService"; +import { equipmentKeys, IMission, TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes"; import { addBooster, addCalendarProgress, @@ -35,7 +35,6 @@ import { addStanding, applyClientEquipmentUpdates, combineInventoryChanges, - generateRewardSeed, getDialogue, giveNemesisPetRecipe, giveNemesisWeaponRecipe, @@ -48,11 +47,10 @@ import { IAffiliationMods, IInventoryChanges } from "@/src/types/purchaseTypes"; import { fromStoreItem, getLevelKeyRewards, isStoreItem, toStoreItem } from "@/src/services/itemDataService"; import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; import { getEntriesUnsafe } from "@/src/utils/ts-utils"; -import { IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes"; -import { handleStoreItemAcquisition } from "./purchaseService"; -import { IMissionCredits, IMissionReward } from "../types/missionTypes"; +import { handleStoreItemAcquisition } from "@/src/services/purchaseService"; +import { IMissionCredits, IMissionReward } from "@/src/types/missionTypes"; import { crackRelic } from "@/src/helpers/relicHelper"; -import { createMessage } from "./inboxService"; +import { createMessage } from "@/src/services/inboxService"; import kuriaMessage50 from "@/static/fixed_responses/kuriaMessages/fiftyPercent.json"; import kuriaMessage75 from "@/static/fixed_responses/kuriaMessages/seventyFivePercent.json"; import kuriaMessage100 from "@/static/fixed_responses/kuriaMessages/oneHundredPercent.json"; @@ -65,8 +63,8 @@ import { getNemesisManifest, getNemesisPasscode } from "@/src/helpers/nemesisHelpers"; -import { Loadout } from "../models/inventoryModels/loadoutModel"; -import { ILoadoutConfigDatabase } from "../types/saveLoadoutTypes"; +import { Loadout } from "@/src/models/inventoryModels/loadoutModel"; +import { ILoadoutConfigDatabase } from "@/src/types/saveLoadoutTypes"; import { getLiteSortie, getSortie, @@ -75,12 +73,14 @@ import { idToDay, idToWeek, pushClassicBounties -} from "./worldStateService"; -import { config } from "./configService"; +} from "@/src/services/worldStateService"; +import { config } from "@/src/services/configService"; import libraryDailyTasks from "@/static/fixed_responses/libraryDailyTasks.json"; -import { ISyndicateMissionInfo } from "../types/worldStateTypes"; -import { fromOid } from "../helpers/inventoryHelpers"; -import { TAccountDocument } from "./loginService"; +import { ISyndicateMissionInfo } from "@/src/types/worldStateTypes"; +import { fromOid } from "@/src/helpers/inventoryHelpers"; +import { TAccountDocument } from "@/src/services/loginService"; +import { ITypeCount } from "@/src/types/commonTypes"; +import { IEquipmentClient } from "@/src/types/equipmentTypes"; const getRotations = (rewardInfo: IRewardInfo, tierOverride?: number): number[] => { // For Spy missions, e.g. 3 vaults cracked = A, B, C diff --git a/src/services/personalRoomsService.ts b/src/services/personalRoomsService.ts index 8cf49ec1..2ce19289 100644 --- a/src/services/personalRoomsService.ts +++ b/src/services/personalRoomsService.ts @@ -1,8 +1,7 @@ import { PersonalRooms } from "@/src/models/personalRoomsModel"; import { addItem, getInventory } from "@/src/services/inventoryService"; -import { TPersonalRoomsDatabaseDocument } from "../types/personalRoomsTypes"; -import { IGardeningDatabase } from "../types/shipTypes"; -import { getRandomElement } from "./rngService"; +import { IGardeningDatabase, TPersonalRoomsDatabaseDocument } from "@/src/types/personalRoomsTypes"; +import { getRandomElement } from "@/src/services/rngService"; export const getPersonalRooms = async ( accountId: string, diff --git a/src/services/purchaseService.ts b/src/services/purchaseService.ts index 1d58e744..cae3743e 100644 --- a/src/services/purchaseService.ts +++ b/src/services/purchaseService.ts @@ -20,8 +20,7 @@ import { IPurchaseParams } from "@/src/types/purchaseTypes"; import { logger } from "@/src/utils/logger"; -import { getWorldState } from "./worldStateService"; -import staticWorldState from "@/static/fixed_responses/worldState/worldState.json"; +import { getWorldState } from "@/src/services/worldStateService"; import { ExportBoosterPacks, ExportBoosters, @@ -33,11 +32,11 @@ import { ExportVendors, TRarity } from "warframe-public-export-plus"; -import { config } from "./configService"; -import { TInventoryDatabaseDocument } from "../models/inventoryModels/inventoryModel"; -import { fromStoreItem, toStoreItem } from "./itemDataService"; -import { DailyDeal } from "../models/worldStateModel"; -import { fromMongoDate, toMongoDate } from "../helpers/inventoryHelpers"; +import { config } from "@/src/services/configService"; +import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; +import { fromStoreItem, toStoreItem } from "@/src/services/itemDataService"; +import { DailyDeal } from "@/src/models/worldStateModel"; +import { fromMongoDate, toMongoDate } from "@/src/helpers/inventoryHelpers"; export const getStoreItemCategory = (storeItem: string): string => { const storeItemString = getSubstringFromKeyword(storeItem, "StoreItems/"); @@ -305,14 +304,15 @@ export const handlePurchase = async ( } break; case PurchaseSource.PrimeVaultTrader: { - if (purchaseRequest.PurchaseParams.SourceId! != staticWorldState.PrimeVaultTraders[0]._id.$oid) { + const worldState = getWorldState(); + if (purchaseRequest.PurchaseParams.SourceId! != worldState.PrimeVaultTraders[0]._id.$oid) { throw new Error("invalid request source"); } const offer = - staticWorldState.PrimeVaultTraders[0].Manifest.find( + worldState.PrimeVaultTraders[0].Manifest.find( x => x.ItemType == purchaseRequest.PurchaseParams.StoreItem ) ?? - staticWorldState.PrimeVaultTraders[0].EvergreenManifest.find( + worldState.PrimeVaultTraders[0].EvergreenManifest.find( x => x.ItemType == purchaseRequest.PurchaseParams.StoreItem ); if (offer) { diff --git a/src/services/questService.ts b/src/services/questService.ts index 633f1022..550bad2f 100644 --- a/src/services/questService.ts +++ b/src/services/questService.ts @@ -4,13 +4,14 @@ import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/invento import { createMessage } from "@/src/services/inboxService"; import { addItem, addItems, addKeyChainItems, setupKahlSyndicate } from "@/src/services/inventoryService"; import { fromStoreItem, getKeyChainMessage, getLevelKeyRewards } from "@/src/services/itemDataService"; -import { IQuestKeyClient, IQuestKeyDatabase, IQuestStage, ITypeCount } from "@/src/types/inventoryTypes/inventoryTypes"; +import { IQuestKeyClient, IQuestKeyDatabase, IQuestStage } from "@/src/types/inventoryTypes/inventoryTypes"; import { logger } from "@/src/utils/logger"; import { Types } from "mongoose"; import { ExportKeys } from "warframe-public-export-plus"; -import { addFixedLevelRewards } from "./missionInventoryUpdateService"; -import { IInventoryChanges } from "../types/purchaseTypes"; +import { addFixedLevelRewards } from "@/src/services/missionInventoryUpdateService"; +import { IInventoryChanges } from "@/src/types/purchaseTypes"; import questCompletionItems from "@/static/fixed_responses/questCompletionRewards.json"; +import { ITypeCount } from "@/src/types/commonTypes"; export interface IUpdateQuestRequest { QuestKeys: Omit[]; diff --git a/src/services/rngService.ts b/src/services/rngService.ts index 01426a3f..d277c50e 100644 --- a/src/services/rngService.ts +++ b/src/services/rngService.ts @@ -18,6 +18,17 @@ export const getRandomInt = (min: number, max: number): number => { return Math.floor(Math.random() * (max - min + 1)) + min; }; +export const generateRewardSeed = (): bigint => { + const hiDword = getRandomInt(0, 0x7fffffff); + const loDword = getRandomInt(0, 0xffffffff); + let seed = (BigInt(hiDword) << 32n) | BigInt(loDword); + if (Math.random() < 0.5) { + seed *= -1n; + seed -= 1n; + } + return seed; +}; + export const getRewardAtPercentage = ( pool: T[], percentage: number diff --git a/src/services/saveLoadoutService.ts b/src/services/saveLoadoutService.ts index 5b35d079..c3f63a0a 100644 --- a/src/services/saveLoadoutService.ts +++ b/src/services/saveLoadoutService.ts @@ -13,8 +13,8 @@ import { Types } from "mongoose"; import { isEmptyObject } from "@/src/helpers/general"; import { logger } from "@/src/utils/logger"; import { equipmentKeys, TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes"; -import { IItemConfig } from "../types/inventoryTypes/commonInventoryTypes"; -import { importCrewMemberId } from "./importService"; +import { IItemConfig } from "@/src/types/inventoryTypes/commonInventoryTypes"; +import { importCrewMemberId } from "@/src/services/importService"; //TODO: setup default items on account creation or like originally in giveStartingItems.php @@ -172,6 +172,16 @@ export const handleInventoryItemConfigChange = async ( // seems always equal to the id of loadout config NORMAL[0], likely has no purpose and we're free to ignore it break; } + case "ActiveCrewShip": { + if (inventory.CrewShips.length != 1) { + logger.warn(`saving railjack changes with broken inventory?`); + } else if (!inventory.CrewShips[0]._id.equals(equipmentChanges.ActiveCrewShip.$oid)) { + logger.warn( + `client provided CrewShip id ${equipmentChanges.ActiveCrewShip.$oid} but id in inventory is ${inventory.CrewShips[0]._id.toString()}` + ); + } + break; + } default: { if (equipmentKeys.includes(equipmentName as TEquipmentKey)) { logger.debug(`general Item config saved of type ${equipmentName}`, { @@ -221,7 +231,7 @@ export const handleInventoryItemConfigChange = async ( } break; } else { - logger.error(`loadout category not implemented, changes will be lost: ${equipmentName}`, { + logger.warn(`unknown saveLoadout field: ${equipmentName}`, { config: equipment }); } diff --git a/src/services/serversideVendorsService.ts b/src/services/serversideVendorsService.ts index 9a7db1a5..50232776 100644 --- a/src/services/serversideVendorsService.ts +++ b/src/services/serversideVendorsService.ts @@ -6,7 +6,7 @@ import { mixSeeds, SRng } from "@/src/services/rngService"; import { IItemManifest, IVendorInfo, IVendorManifest } from "@/src/types/vendorTypes"; import { logger } from "@/src/utils/logger"; import { ExportVendors, IRange, IVendor, IVendorOffer } from "warframe-public-export-plus"; -import { config } from "./configService"; +import { config } from "@/src/services/configService"; interface IGeneratableVendorInfo extends Omit { cycleOffset?: number; @@ -299,9 +299,12 @@ const generateVendorManifest = ( ? numUncountedOffers + numCountedOffers : manifest.numItems ? numUncountedOffers + - (useRng - ? rng.randomInt(manifest.numItems.minValue, manifest.numItems.maxValue) - : manifest.numItems.minValue) + Math.min( + Object.values(remainingItemCapacity).reduce((a, b) => a + b, 0), + useRng + ? rng.randomInt(manifest.numItems.minValue, manifest.numItems.maxValue) + : manifest.numItems.minValue + ) : manifest.items.length; let i = 0; const rollableOffers = manifest.items.filter(x => x.probability !== undefined) as (Omit< @@ -495,4 +498,13 @@ if (args.dev) { ) { logger.warn(`self test failed for /Lotus/Types/Game/VendorManifests/Ostron/MaskSalesmanManifest`); } + + // strange case where numItems is 5 even tho only 3 offers can possibly be generated + const loid = getVendorManifestByTypeName( + "/Lotus/Types/Game/VendorManifests/EntratiLabs/EntratiLabsCommisionsManifest", + false + )!.VendorInfo.ItemManifest; + if (loid.length != 3) { + logger.warn(`self test failed for /Lotus/Types/Game/VendorManifests/EntratiLabs/EntratiLabsCommisionsManifest`); + } } diff --git a/src/services/shipCustomizationsService.ts b/src/services/shipCustomizationsService.ts index c815dc56..f49f62d8 100644 --- a/src/services/shipCustomizationsService.ts +++ b/src/services/shipCustomizationsService.ts @@ -1,21 +1,22 @@ import { getPersonalRooms } from "@/src/services/personalRoomsService"; import { getShip } from "@/src/services/shipService"; import { + ISetPlacedDecoInfoRequest, ISetShipCustomizationsRequest, IShipDecorationsRequest, IShipDecorationsResponse, - ISetPlacedDecoInfoRequest, - TBootLocation -} from "@/src/types/shipTypes"; + RoomsType, + TBootLocation, + TPersonalRoomsDatabaseDocument +} from "@/src/types/personalRoomsTypes"; import { logger } from "@/src/utils/logger"; import { Types } from "mongoose"; -import { addFusionTreasures, addShipDecorations, getInventory } from "./inventoryService"; -import { config } from "./configService"; -import { Guild } from "../models/guildModel"; -import { hasGuildPermission } from "./guildService"; -import { GuildPermission } from "../types/guildTypes"; +import { addFusionTreasures, addShipDecorations, getInventory } from "@/src/services/inventoryService"; +import { config } from "@/src/services/configService"; +import { Guild } from "@/src/models/guildModel"; +import { hasGuildPermission } from "@/src/services/guildService"; +import { GuildPermission } from "@/src/types/guildTypes"; import { ExportResources } from "warframe-public-export-plus"; -import { RoomsType, TPersonalRoomsDatabaseDocument } from "../types/personalRoomsTypes"; export const setShipCustomizations = async ( accountId: string, @@ -39,7 +40,7 @@ export const setShipCustomizations = async ( personalRooms.TailorShop.LevelDecosVisible = shipCustomization.Customization.LevelDecosVisible; personalRooms.TailorShop.CustomJson = shipCustomization.Customization.CustomJson; } else { - personalRooms.ShipInteriorColors = shipCustomization.Customization.Colors; + personalRooms.Ship.ShipInterior = shipCustomization.Customization; } await personalRooms.save(); } diff --git a/src/services/statsService.ts b/src/services/statsService.ts index a074b637..8dccd312 100644 --- a/src/services/statsService.ts +++ b/src/services/statsService.ts @@ -10,7 +10,7 @@ import { } from "@/src/types/statTypes"; import { logger } from "@/src/utils/logger"; import { addEmailItem, getInventory } from "@/src/services/inventoryService"; -import { submitLeaderboardScore } from "./leaderboardService"; +import { submitLeaderboardScore } from "@/src/services/leaderboardService"; export const createStats = async (accountId: string): Promise => { const stats = new Stats({ accountOwnerId: accountId }); diff --git a/src/services/webService.ts b/src/services/webService.ts index 11ff2654..e8162663 100644 --- a/src/services/webService.ts +++ b/src/services/webService.ts @@ -1,21 +1,15 @@ import http from "http"; import https from "https"; import fs from "node:fs"; -import { config } from "./configService"; -import { logger } from "../utils/logger"; -import { app } from "../app"; +import { config } from "@/src/services/configService"; +import { logger } from "@/src/utils/logger"; +import { app } from "@/src/app"; import { AddressInfo } from "node:net"; -import ws from "ws"; -import { Account } from "../models/loginModel"; -import { createAccount, createNonce, getUsernameFromEmail, isCorrectPassword } from "./loginService"; -import { IDatabaseAccountJson } from "../types/loginTypes"; -import { HydratedDocument } from "mongoose"; import { Agent, WebSocket as UnidiciWebSocket } from "undici"; +import { startWsServer, startWssServer, stopWsServers } from "@/src/services/wsService"; let httpServer: http.Server | undefined; let httpsServer: https.Server | undefined; -let wsServer: ws.Server | undefined; -let wssServer: ws.Server | undefined; const tlsOptions = { key: fs.readFileSync("static/certs/key.pem"), @@ -29,16 +23,14 @@ export const startWebServer = (): void => { // eslint-disable-next-line @typescript-eslint/no-misused-promises httpServer = http.createServer(app); httpServer.listen(httpPort, () => { - wsServer = new ws.Server({ server: httpServer }); - wsServer.on("connection", wsOnConnect); + startWsServer(httpServer!); logger.info("HTTP server started on port " + httpPort); // eslint-disable-next-line @typescript-eslint/no-misused-promises httpsServer = https.createServer(tlsOptions, app); httpsServer.listen(httpsPort, () => { - wssServer = new ws.Server({ server: httpsServer }); - wssServer.on("connection", wsOnConnect); + startWssServer(httpsServer!); logger.info("HTTPS server started on port " + httpsPort); @@ -115,182 +107,6 @@ export const stopWebServer = async (): Promise => { }) ); } - if (wsServer) { - promises.push( - new Promise(resolve => { - wsServer!.close(() => { - resolve(); - }); - }) - ); - } - if (wssServer) { - promises.push( - new Promise(resolve => { - wssServer!.close(() => { - resolve(); - }); - }) - ); - } + stopWsServers(promises); await Promise.all(promises); }; - -let lastWsid: number = 0; - -interface IWsCustomData extends ws { - id?: number; - accountId?: string; -} - -interface IWsMsgFromClient { - auth?: { - email: string; - password: string; - isRegister: boolean; - }; - logout?: boolean; -} - -interface IWsMsgToClient { - //wsid?: number; - reload?: boolean; - ports?: { - http: number | undefined; - https: number | undefined; - }; - config_reloaded?: boolean; - auth_succ?: { - id: string; - DisplayName: string; - Nonce: number; - }; - auth_fail?: { - isRegister: boolean; - }; - logged_out?: boolean; - update_inventory?: boolean; -} - -const wsOnConnect = (ws: ws, req: http.IncomingMessage): void => { - if (req.url == "/custom/selftest") { - ws.send("SpaceNinjaServer"); - ws.close(); - return; - } - - (ws as IWsCustomData).id = ++lastWsid; - ws.send(JSON.stringify({ wsid: lastWsid })); - - // eslint-disable-next-line @typescript-eslint/no-misused-promises - ws.on("message", async msg => { - const data = JSON.parse(String(msg)) as IWsMsgFromClient; - if (data.auth) { - let account: IDatabaseAccountJson | null = await Account.findOne({ email: data.auth.email }); - if (account) { - if (isCorrectPassword(data.auth.password, account.password)) { - if (!account.Nonce) { - account.ClientType = "webui"; - account.Nonce = createNonce(); - await (account as HydratedDocument).save(); - } - } else { - account = null; - } - } else if (data.auth.isRegister) { - const name = await getUsernameFromEmail(data.auth.email); - account = await createAccount({ - email: data.auth.email, - password: data.auth.password, - ClientType: "webui", - LastLogin: new Date(), - DisplayName: name, - Nonce: createNonce() - }); - } - if (account) { - (ws as IWsCustomData).accountId = account.id; - ws.send( - JSON.stringify({ - auth_succ: { - id: account.id, - DisplayName: account.DisplayName, - Nonce: account.Nonce - } - } satisfies IWsMsgToClient) - ); - } else { - ws.send( - JSON.stringify({ - auth_fail: { - isRegister: data.auth.isRegister - } - } satisfies IWsMsgToClient) - ); - } - } - if (data.logout) { - const accountId = (ws as IWsCustomData).accountId; - (ws as IWsCustomData).accountId = undefined; - await Account.updateOne( - { - _id: accountId, - ClientType: "webui" - }, - { - Nonce: 0 - } - ); - } - }); -}; - -export const sendWsBroadcast = (data: IWsMsgToClient): void => { - const msg = JSON.stringify(data); - if (wsServer) { - for (const client of wsServer.clients) { - client.send(msg); - } - } - if (wssServer) { - for (const client of wssServer.clients) { - client.send(msg); - } - } -}; - -export const sendWsBroadcastTo = (accountId: string, data: IWsMsgToClient): void => { - const msg = JSON.stringify(data); - if (wsServer) { - for (const client of wsServer.clients) { - if ((client as IWsCustomData).accountId == accountId) { - client.send(msg); - } - } - } - if (wssServer) { - for (const client of wssServer.clients) { - if ((client as IWsCustomData).accountId == accountId) { - client.send(msg); - } - } - } -}; - -export const sendWsBroadcastExcept = (wsid: number | undefined, data: IWsMsgToClient): void => { - const msg = JSON.stringify(data); - if (wsServer) { - for (const client of wsServer.clients) { - if ((client as IWsCustomData).id != wsid) { - client.send(msg); - } - } - } - if (wssServer) { - for (const client of wssServer.clients) { - if ((client as IWsCustomData).id != wsid) { - client.send(msg); - } - } - } -}; diff --git a/src/services/worldStateService.ts b/src/services/worldStateService.ts index 501a6536..dcf8b786 100644 --- a/src/services/worldStateService.ts +++ b/src/services/worldStateService.ts @@ -1,5 +1,6 @@ import staticWorldState from "@/static/fixed_responses/worldState/worldState.json"; import baro from "@/static/fixed_responses/worldState/baro.json"; +import varzia from "@/static/fixed_responses/worldState/varzia.json"; import fissureMissions from "@/static/fixed_responses/worldState/fissureMissions.json"; import sortieTilesets from "@/static/fixed_responses/worldState/sortieTilesets.json"; import sortieTilesetMissions from "@/static/fixed_responses/worldState/sortieTilesetMissions.json"; @@ -15,6 +16,8 @@ import { ICalendarEvent, ICalendarSeason, ILiteSortie, + IPrimeVaultTrader, + IPrimeVaultTraderOffer, ISeasonChallenge, ISortie, ISortieMission, @@ -25,10 +28,10 @@ import { IVoidTraderOffer, IWorldState, TCircuitGameMode -} from "../types/worldStateTypes"; -import { toMongoDate, toOid, version_compare } from "../helpers/inventoryHelpers"; -import { logger } from "../utils/logger"; -import { DailyDeal, Fissure } from "../models/worldStateModel"; +} from "@/src/types/worldStateTypes"; +import { toMongoDate, toOid, version_compare } from "@/src/helpers/inventoryHelpers"; +import { logger } from "@/src/utils/logger"; +import { DailyDeal, Fissure } from "@/src/models/worldStateModel"; const sortieBosses = [ "SORTIE_BOSS_HYENA", @@ -1101,6 +1104,80 @@ const doesTimeSatsifyConstraints = (timeSecs: number): boolean => { return true; }; +const getVarziaRotation = (week: number): string => { + const seed = new SRng(week).randomInt(0, 100_000); + const rng = new SRng(seed); + return rng.randomElement(varzia.primeDualPacks)!.ItemType; +}; + +const getVarziaManifest = (dualPack: string): IPrimeVaultTraderOffer[] => { + const rotrationManifest = varzia.primeDualPacks.find(pack => pack.ItemType === dualPack); + if (!rotrationManifest) return []; + + const mainPack = [{ ItemType: rotrationManifest.ItemType, PrimePrice: 10 }]; + const singlePacks: IPrimeVaultTraderOffer[] = []; + const items: IPrimeVaultTraderOffer[] = []; + const bobbleHeads: IPrimeVaultTraderOffer[] = []; + + for (const singlePackType of rotrationManifest.SinglePacks) { + singlePacks.push({ ItemType: singlePackType, PrimePrice: 6 }); + + const sp = varzia.primeSinglePacks.find(pack => pack.ItemType === singlePackType); + if (sp) { + items.push(...sp.Items); + sp.BobbleHeads.forEach(bobbleHead => { + bobbleHeads.push({ ItemType: bobbleHead, PrimePrice: 1 }); + }); + } + } + + const relics = rotrationManifest.Relics.map(relic => ({ ItemType: relic, RegularPrice: 1 })); + + return [singlePacks[0], ...mainPack, singlePacks[1], ...items, ...bobbleHeads, ...relics]; +}; + +const getAllVarziaManifests = (): IPrimeVaultTraderOffer[] => { + const dualPacks: IPrimeVaultTraderOffer[] = []; + const singlePacks: IPrimeVaultTraderOffer[] = []; + const items: IPrimeVaultTraderOffer[] = []; + const bobbleHeads: IPrimeVaultTraderOffer[] = []; + const relics: IPrimeVaultTraderOffer[] = []; + + const singlePackSet = new Set(); + const itemsSet = new Set(); + const bobbleHeadsSet = new Set(); + + varzia.primeDualPacks.forEach(dualPack => { + dualPacks.push({ ItemType: dualPack.ItemType, PrimePrice: 10 }); + + dualPack.SinglePacks.forEach(singlePackType => { + if (!singlePackSet.has(singlePackType)) { + singlePackSet.add(singlePackType); + singlePacks.push({ ItemType: singlePackType, PrimePrice: 6 }); + } + + const sp = varzia.primeSinglePacks.find(pack => pack.ItemType === singlePackType)!; + sp.Items.forEach(item => { + if (!itemsSet.has(item.ItemType)) { + itemsSet.add(item.ItemType); + items.push(item); + } + }); + + sp.BobbleHeads.forEach(bobbleHead => { + if (!bobbleHeadsSet.has(bobbleHead)) { + bobbleHeadsSet.add(bobbleHead); + bobbleHeads.push({ ItemType: bobbleHead, PrimePrice: 1 }); + } + }); + }); + + relics.push(...dualPack.Relics.map(relic => ({ ItemType: relic, RegularPrice: 1 }))); + }); + + return [...dualPacks, ...singlePacks, ...items, ...bobbleHeads, ...relics]; +}; + export const getWorldState = (buildLabel?: string): IWorldState => { let timeSecs = Math.round(Date.now() / 1000); while (!doesTimeSatsifyConstraints(timeSecs)) { @@ -1122,6 +1199,7 @@ export const getWorldState = (buildLabel?: string): IWorldState => { ActiveMissions: [], GlobalUpgrades: [], VoidTraders: [], + PrimeVaultTraders: [], VoidStorms: [], DailyDeals: [], EndlessXpChoices: [], @@ -1393,6 +1471,30 @@ export const getWorldState = (buildLabel?: string): IWorldState => { } } + // Varzia + { + const pt: IPrimeVaultTrader = { + _id: { $oid: ((weekStart / 1000) & 0xffffffff).toString(16).padStart(8, "0") + "c36af423770eaa97" }, + Activation: { $date: { $numberLong: weekStart.toString() } }, + Expiry: { $date: { $numberLong: weekEnd.toString() } }, + Node: "TradeHUB1", + Manifest: [], + EvergreenManifest: varzia.evergreen, + ScheduleInfo: [] + }; + worldState.PrimeVaultTraders.push(pt); + const rotation = config.worldState?.varziaOverride || getVarziaRotation(week); + pt.Manifest = config.worldState?.varziaFullyStocked ? getAllVarziaManifests() : getVarziaManifest(rotation); + if (config.worldState?.varziaOverride || config.worldState?.varziaFullyStocked) { + pt.Expiry = { $date: { $numberLong: "2000000000000" } }; + } else { + pt.ScheduleInfo.push({ + Expiry: { $date: { $numberLong: (weekEnd + unixTimesInMs.week).toString() } }, + FeaturedItem: getVarziaRotation(week + 1) + }); + } + } + // Sortie & syndicate missions cycling every day (at 16:00 or 17:00 UTC depending on if London, OT is observing DST) { const rollover = getSortieTime(day); diff --git a/src/services/wsService.ts b/src/services/wsService.ts new file mode 100644 index 00000000..209b1bc9 --- /dev/null +++ b/src/services/wsService.ts @@ -0,0 +1,200 @@ +import http from "http"; +import https from "https"; +import ws from "ws"; +import { Account } from "@/src/models/loginModel"; +import { createAccount, createNonce, getUsernameFromEmail, isCorrectPassword } from "@/src/services/loginService"; +import { IDatabaseAccountJson } from "@/src/types/loginTypes"; +import { HydratedDocument } from "mongoose"; + +let wsServer: ws.Server | undefined; +let wssServer: ws.Server | undefined; + +export const startWsServer = (httpServer: http.Server): void => { + wsServer = new ws.Server({ server: httpServer }); + wsServer.on("connection", wsOnConnect); +}; + +export const startWssServer = (httpsServer: https.Server): void => { + wssServer = new ws.Server({ server: httpsServer }); + wssServer.on("connection", wsOnConnect); +}; + +export const stopWsServers = (promises: Promise[]): void => { + if (wsServer) { + promises.push( + new Promise(resolve => { + wsServer!.close(() => { + resolve(); + }); + }) + ); + } + if (wssServer) { + promises.push( + new Promise(resolve => { + wssServer!.close(() => { + resolve(); + }); + }) + ); + } +}; + +let lastWsid: number = 0; + +interface IWsCustomData extends ws { + id?: number; + accountId?: string; +} + +interface IWsMsgFromClient { + auth?: { + email: string; + password: string; + isRegister: boolean; + }; + logout?: boolean; +} + +interface IWsMsgToClient { + //wsid?: number; + reload?: boolean; + ports?: { + http: number | undefined; + https: number | undefined; + }; + config_reloaded?: boolean; + auth_succ?: { + id: string; + DisplayName: string; + Nonce: number; + }; + auth_fail?: { + isRegister: boolean; + }; + logged_out?: boolean; + update_inventory?: boolean; +} + +const wsOnConnect = (ws: ws, req: http.IncomingMessage): void => { + if (req.url == "/custom/selftest") { + ws.send("SpaceNinjaServer"); + ws.close(); + return; + } + + (ws as IWsCustomData).id = ++lastWsid; + ws.send(JSON.stringify({ wsid: lastWsid })); + + // eslint-disable-next-line @typescript-eslint/no-misused-promises + ws.on("message", async msg => { + const data = JSON.parse(String(msg)) as IWsMsgFromClient; + if (data.auth) { + let account: IDatabaseAccountJson | null = await Account.findOne({ email: data.auth.email }); + if (account) { + if (isCorrectPassword(data.auth.password, account.password)) { + if (!account.Nonce) { + account.ClientType = "webui"; + account.Nonce = createNonce(); + await (account as HydratedDocument).save(); + } + } else { + account = null; + } + } else if (data.auth.isRegister) { + const name = await getUsernameFromEmail(data.auth.email); + account = await createAccount({ + email: data.auth.email, + password: data.auth.password, + ClientType: "webui", + LastLogin: new Date(), + DisplayName: name, + Nonce: createNonce() + }); + } + if (account) { + (ws as IWsCustomData).accountId = account.id; + ws.send( + JSON.stringify({ + auth_succ: { + id: account.id, + DisplayName: account.DisplayName, + Nonce: account.Nonce + } + } satisfies IWsMsgToClient) + ); + } else { + ws.send( + JSON.stringify({ + auth_fail: { + isRegister: data.auth.isRegister + } + } satisfies IWsMsgToClient) + ); + } + } + if (data.logout) { + const accountId = (ws as IWsCustomData).accountId; + (ws as IWsCustomData).accountId = undefined; + await Account.updateOne( + { + _id: accountId, + ClientType: "webui" + }, + { + Nonce: 0 + } + ); + } + }); +}; + +export const sendWsBroadcast = (data: IWsMsgToClient): void => { + const msg = JSON.stringify(data); + if (wsServer) { + for (const client of wsServer.clients) { + client.send(msg); + } + } + if (wssServer) { + for (const client of wssServer.clients) { + client.send(msg); + } + } +}; + +export const sendWsBroadcastTo = (accountId: string, data: IWsMsgToClient): void => { + const msg = JSON.stringify(data); + if (wsServer) { + for (const client of wsServer.clients) { + if ((client as IWsCustomData).accountId == accountId) { + client.send(msg); + } + } + } + if (wssServer) { + for (const client of wssServer.clients) { + if ((client as IWsCustomData).accountId == accountId) { + client.send(msg); + } + } + } +}; + +export const sendWsBroadcastExcept = (wsid: number | undefined, data: IWsMsgToClient): void => { + const msg = JSON.stringify(data); + if (wsServer) { + for (const client of wsServer.clients) { + if ((client as IWsCustomData).id != wsid) { + client.send(msg); + } + } + } + if (wssServer) { + for (const client of wssServer.clients) { + if ((client as IWsCustomData).id != wsid) { + client.send(msg); + } + } + } +}; diff --git a/src/types/commonTypes.ts b/src/types/commonTypes.ts index a9335fff..915614bd 100644 --- a/src/types/commonTypes.ts +++ b/src/types/commonTypes.ts @@ -1,5 +1,3 @@ -import { ITypeCount } from "@/src/types/inventoryTypes/inventoryTypes"; - export interface IOid { $oid: string; } @@ -15,6 +13,11 @@ export interface IMongoDate { }; } +export interface ITypeCount { + ItemType: string; + ItemCount: number; +} + export interface IReward { items: ITypeCount[]; credits: number; diff --git a/src/types/equipmentTypes.ts b/src/types/equipmentTypes.ts new file mode 100644 index 00000000..4053430a --- /dev/null +++ b/src/types/equipmentTypes.ts @@ -0,0 +1,155 @@ +import { Types } from "mongoose"; +import { IMongoDate, IOid, IOidWithLegacySupport } from "@/src/types/commonTypes"; +import { + ICrewShipCustomization, + IFlavourItem, + IItemConfig, + IPolarity +} from "@/src/types/inventoryTypes/commonInventoryTypes"; + +export interface IEquipmentSelection { + ItemId: IOid; + mod?: number; + cus?: number; + ItemType?: string; + hide?: boolean; +} + +export enum EquipmentFeatures { + DOUBLE_CAPACITY = 1, + UTILITY_SLOT = 2, + GRAVIMAG_INSTALLED = 4, + GILDED = 8, + ARCANE_SLOT = 32, + INCARNON_GENESIS = 512, + VALENCE_SWAP = 1024 +} + +export interface IEquipmentDatabase { + ItemType: string; + ItemName?: string; + Configs: IItemConfig[]; + UpgradeVer?: number; + XP?: number; + Features?: number; + Polarized?: number; + Polarity?: IPolarity[]; + FocusLens?: string; + ModSlotPurchases?: number; + CustomizationSlotPurchases?: number; + UpgradeType?: string; + UpgradeFingerprint?: string; + InfestationDate?: Date; + InfestationDays?: number; + InfestationType?: string; + ModularParts?: string[]; + UnlockLevel?: number; + Expiry?: Date; + SkillTree?: string; + OffensiveUpgrade?: string; + DefensiveUpgrade?: string; + UpgradesExpiry?: Date; + UmbraDate?: Date; // related to scrapped "echoes of umbra" feature + ArchonCrystalUpgrades?: IArchonCrystalUpgrade[]; + Weapon?: ICrewShipWeapon; + Customization?: ICrewShipCustomization; + RailjackImage?: IFlavourItem; + CrewMembers?: ICrewShipMembersDatabase; + Details?: IKubrowPetDetailsDatabase; + Favorite?: boolean; + IsNew?: boolean; + _id: Types.ObjectId; +} + +export interface IEquipmentClient + extends Omit< + IEquipmentDatabase, + "_id" | "InfestationDate" | "Expiry" | "UpgradesExpiry" | "UmbraDate" | "CrewMembers" | "Details" + > { + ItemId: IOidWithLegacySupport; + InfestationDate?: IMongoDate; + Expiry?: IMongoDate; + UpgradesExpiry?: IMongoDate; + UmbraDate?: IMongoDate; + CrewMembers?: ICrewShipMembersClient; + Details?: IKubrowPetDetailsClient; +} + +export interface IArchonCrystalUpgrade { + UpgradeType?: string; + Color?: string; +} + +export interface ITraits { + BaseColor: string; + SecondaryColor: string; + TertiaryColor: string; + AccentColor: string; + EyeColor: string; + FurPattern: string; + Personality: string; + BodyType: string; + Head?: string; + Tail?: string; +} + +export interface IKubrowPetDetailsDatabase { + Name?: string; + IsPuppy?: boolean; + HasCollar: boolean; + PrintsRemaining: number; + Status: Status; + HatchDate?: Date; + DominantTraits: ITraits; + RecessiveTraits: ITraits; + IsMale: boolean; + Size: number; +} + +export interface IKubrowPetDetailsClient extends Omit { + HatchDate: IMongoDate; +} + +export enum Status { + StatusAvailable = "STATUS_AVAILABLE", + StatusStasis = "STATUS_STASIS", + StatusIncubating = "STATUS_INCUBATING" +} + +// inventory.CrewShips[0].Weapon +export interface ICrewShipWeapon { + PILOT?: ICrewShipWeaponEmplacements; + PORT_GUNS?: ICrewShipWeaponEmplacements; + STARBOARD_GUNS?: ICrewShipWeaponEmplacements; + ARTILLERY?: ICrewShipWeaponEmplacements; + SCANNER?: ICrewShipWeaponEmplacements; +} + +export interface ICrewShipWeaponEmplacements { + PRIMARY_A?: IEquipmentSelection; + PRIMARY_B?: IEquipmentSelection; + SECONDARY_A?: IEquipmentSelection; + SECONDARY_B?: IEquipmentSelection; +} + +export interface ICrewShipMembersClient { + SLOT_A?: ICrewShipMemberClient; + SLOT_B?: ICrewShipMemberClient; + SLOT_C?: ICrewShipMemberClient; +} + +export interface ICrewShipMembersDatabase { + SLOT_A?: ICrewShipMemberDatabase; + SLOT_B?: ICrewShipMemberDatabase; + SLOT_C?: ICrewShipMemberDatabase; +} + +export interface ICrewShipMemberClient { + ItemId?: IOid; + NemesisFingerprint?: number | bigint; +} + +export interface ICrewShipMemberDatabase { + ItemId?: Types.ObjectId; + NemesisFingerprint?: bigint; +} diff --git a/src/types/friendTypes.ts b/src/types/friendTypes.ts index f4799201..0318c0ae 100644 --- a/src/types/friendTypes.ts +++ b/src/types/friendTypes.ts @@ -1,5 +1,5 @@ import { Types } from "mongoose"; -import { IMongoDate, IOidWithLegacySupport } from "./commonTypes"; +import { IMongoDate, IOidWithLegacySupport } from "@/src/types/commonTypes"; export interface IFriendInfo { _id: IOidWithLegacySupport; diff --git a/src/types/genericUpdate.ts b/src/types/genericUpdate.ts index 93551b05..e51d41bc 100644 --- a/src/types/genericUpdate.ts +++ b/src/types/genericUpdate.ts @@ -1,4 +1,4 @@ -import { IInventoryChanges } from "./purchaseTypes"; +import { IInventoryChanges } from "@/src/types/purchaseTypes"; export interface IGenericUpdate { NodeIntrosCompleted: string | string[]; diff --git a/src/types/guildTypes.ts b/src/types/guildTypes.ts index 7913c5fe..ec1b4899 100644 --- a/src/types/guildTypes.ts +++ b/src/types/guildTypes.ts @@ -1,8 +1,8 @@ import { Types } from "mongoose"; -import { IOid, IMongoDate, IOidWithLegacySupport } from "@/src/types/commonTypes"; -import { IFusionTreasure, IMiscItem, ITypeCount } from "@/src/types/inventoryTypes/inventoryTypes"; -import { IPictureFrameInfo } from "./shipTypes"; -import { IFriendInfo } from "./friendTypes"; +import { IOid, IMongoDate, IOidWithLegacySupport, ITypeCount } from "@/src/types/commonTypes"; +import { IFusionTreasure, IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes"; +import { IPictureFrameInfo } from "@/src/types/personalRoomsTypes"; +import { IFriendInfo } from "@/src/types/friendTypes"; export interface IGuildClient { _id: IOidWithLegacySupport; diff --git a/src/types/inventoryTypes/commonInventoryTypes.ts b/src/types/inventoryTypes/commonInventoryTypes.ts index 8cc0d56f..3e40d104 100644 --- a/src/types/inventoryTypes/commonInventoryTypes.ts +++ b/src/types/inventoryTypes/commonInventoryTypes.ts @@ -1,14 +1,5 @@ -import { IMongoDate, IOid, IOidWithLegacySupport } from "@/src/types/commonTypes"; +import { IOid } from "@/src/types/commonTypes"; import { Types } from "mongoose"; -import { - ICrewShipCustomization, - ICrewShipMembersClient, - ICrewShipMembersDatabase, - ICrewShipWeapon, - IFlavourItem, - IKubrowPetDetailsClient, - IKubrowPetDetailsDatabase -} from "@/src/types/inventoryTypes/inventoryTypes"; export interface IPolarity { Slot: number; @@ -79,75 +70,24 @@ export interface IOperatorConfigClient extends Omit { - ItemId: IOidWithLegacySupport; - InfestationDate?: IMongoDate; - Expiry?: IMongoDate; - UpgradesExpiry?: IMongoDate; - UmbraDate?: IMongoDate; - CrewMembers?: ICrewShipMembersClient; - Details?: IKubrowPetDetailsClient; -} - -export enum EquipmentFeatures { - DOUBLE_CAPACITY = 1, - UTILITY_SLOT = 2, - GRAVIMAG_INSTALLED = 4, - GILDED = 8, - ARCANE_SLOT = 32, - INCARNON_GENESIS = 512, - VALENCE_SWAP = 1024 -} - -export interface IEquipmentDatabase { +export interface IFlavourItem { ItemType: string; - ItemName?: string; - Configs: IItemConfig[]; - UpgradeVer?: number; - XP?: number; - Features?: number; - Polarized?: number; - Polarity?: IPolarity[]; - FocusLens?: string; - ModSlotPurchases?: number; - CustomizationSlotPurchases?: number; - UpgradeType?: string; - UpgradeFingerprint?: string; - InfestationDate?: Date; - InfestationDays?: number; - InfestationType?: string; - ModularParts?: string[]; - UnlockLevel?: number; - Expiry?: Date; - SkillTree?: string; - OffensiveUpgrade?: string; - DefensiveUpgrade?: string; - UpgradesExpiry?: Date; - UmbraDate?: Date; // related to scrapped "echoes of umbra" feature - ArchonCrystalUpgrades?: IArchonCrystalUpgrade[]; - Weapon?: ICrewShipWeapon; - Customization?: ICrewShipCustomization; - RailjackImage?: IFlavourItem; - CrewMembers?: ICrewShipMembersDatabase; - Details?: IKubrowPetDetailsDatabase; - Favorite?: boolean; - IsNew?: boolean; - _id: Types.ObjectId; } -export interface IArchonCrystalUpgrade { - UpgradeType?: string; - Color?: string; +export interface IShipAttachments { + HOOD_ORNAMENT?: string; +} + +export interface IShipCustomization { + SkinFlavourItem?: string; + Colors?: IColor; + ShipAttachments?: IShipAttachments; +} + +export interface ICrewShipCustomization { + CrewshipInterior: IShipCustomization; } diff --git a/src/types/inventoryTypes/inventoryTypes.ts b/src/types/inventoryTypes/inventoryTypes.ts index 06c47147..b10d3282 100644 --- a/src/types/inventoryTypes/inventoryTypes.ts +++ b/src/types/inventoryTypes/inventoryTypes.ts @@ -1,18 +1,20 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { Types } from "mongoose"; -import { IOid, IMongoDate, IOidWithLegacySupport } from "../commonTypes"; +import { IOid, IMongoDate, IOidWithLegacySupport, ITypeCount } from "@/src/types/commonTypes"; import { IColor, IItemConfig, IOperatorConfigClient, - IEquipmentSelection, - IEquipmentDatabase, - IEquipmentClient, - IOperatorConfigDatabase + IOperatorConfigDatabase, + IFlavourItem, + ILotusCustomization, + IShipCustomization } from "@/src/types/inventoryTypes/commonInventoryTypes"; import { IFingerprintStat, RivenFingerprint } from "@/src/helpers/rivenHelper"; -import { IOrbiter } from "../personalRoomsTypes"; +import { IOrbiterClient } from "@/src/types/personalRoomsTypes"; import { ICountedStoreItem } from "warframe-public-export-plus"; +import { IEquipmentClient, IEquipmentDatabase, ITraits } from "@/src/types/equipmentTypes"; +import { ILoadOutPresets } from "@/src/types/saveLoadoutTypes"; export type InventoryDatabaseEquipment = { [_ in TEquipmentKey]: IEquipmentDatabase[]; @@ -110,11 +112,6 @@ export interface IQuestKeyDatabase { CompletionDate?: Date; } -export interface ITypeCount { - ItemType: string; - ItemCount: number; -} - export const equipmentKeys = [ "Suits", "LongGuns", @@ -381,7 +378,7 @@ export interface IInventoryClient extends IDailyAffiliations, InventoryClientEqu BrandedSuits?: IOidWithLegacySupport[]; LockedWeaponGroup?: ILockedWeaponGroupClient; HubNpcCustomizations?: IHubNpcCustomization[]; - Ship?: IOrbiter; // U22 and below, response only + Ship?: IOrbiterClient; // U22 and below, response only ClaimedJunctionChallengeRewards?: string[]; // U39 SpecialItemRewardAttenuation?: IRewardAttenuation[]; // Baro's Void Surplus } @@ -552,64 +549,8 @@ export interface IUpgradeFromClient { LastAdded: IOidWithLegacySupport; } -export interface ICrewShipMembersClient { - SLOT_A?: ICrewShipMemberClient; - SLOT_B?: ICrewShipMemberClient; - SLOT_C?: ICrewShipMemberClient; -} - -export interface ICrewShipMembersDatabase { - SLOT_A?: ICrewShipMemberDatabase; - SLOT_B?: ICrewShipMemberDatabase; - SLOT_C?: ICrewShipMemberDatabase; -} - -export interface ICrewShipMemberClient { - ItemId?: IOid; - NemesisFingerprint?: number | bigint; -} - -export interface ICrewShipMemberDatabase { - ItemId?: Types.ObjectId; - NemesisFingerprint?: bigint; -} - -export interface ICrewShipCustomization { - CrewshipInterior: IShipExterior; -} - -export interface IShipExterior { - SkinFlavourItem?: string; - Colors?: IColor; - ShipAttachments?: IShipAttachments; -} - -export interface IShipAttachments { - HOOD_ORNAMENT: string; -} - -export interface IFlavourItem { - ItemType: string; -} - export type IMiscItem = ITypeCount; -// inventory.CrewShips[0].Weapon -export interface ICrewShipWeapon { - PILOT?: ICrewShipWeaponEmplacements; - PORT_GUNS?: ICrewShipWeaponEmplacements; - STARBOARD_GUNS?: ICrewShipWeaponEmplacements; - ARTILLERY?: ICrewShipWeaponEmplacements; - SCANNER?: ICrewShipWeaponEmplacements; -} - -export interface ICrewShipWeaponEmplacements { - PRIMARY_A?: IEquipmentSelection; - PRIMARY_B?: IEquipmentSelection; - SECONDARY_A?: IEquipmentSelection; - SECONDARY_B?: IEquipmentSelection; -} - export interface IDiscoveredMarker { tag: string; discoveryState: number[]; @@ -740,42 +681,6 @@ export interface IKubrowPetPrintDatabase extends Omit { - HatchDate: IMongoDate; -} - -export enum Status { - StatusAvailable = "STATUS_AVAILABLE", - StatusStasis = "STATUS_STASIS", - StatusIncubating = "STATUS_INCUBATING" -} - export interface ILastSortieRewardClient { SortieId: IOid; StoreItem: string; @@ -808,45 +713,6 @@ export interface ILibraryPersonalProgress { Completed: boolean; } -// keep in sync with ILoadoutDatabase -export interface ILoadOutPresets { - NORMAL: ILoadoutConfigClient[]; - NORMAL_PVP: ILoadoutConfigClient[]; - LUNARO: ILoadoutConfigClient[]; - ARCHWING: ILoadoutConfigClient[]; - SENTINEL: ILoadoutConfigClient[]; - OPERATOR: ILoadoutConfigClient[]; - GEAR: ILoadoutConfigClient[]; - KDRIVE: ILoadoutConfigClient[]; - DATAKNIFE: ILoadoutConfigClient[]; - MECH: ILoadoutConfigClient[]; - OPERATOR_ADULT: ILoadoutConfigClient[]; - DRIFTER: ILoadoutConfigClient[]; -} - -export enum FocusSchool { - Attack = "AP_ATTACK", - Defense = "AP_DEFENSE", - Power = "AP_POWER", - Tactic = "AP_TACTIC", - Ward = "AP_WARD" -} - -export interface ILoadoutConfigClient { - FocusSchool?: FocusSchool; - PresetIcon?: string; - Favorite?: boolean; - n?: string; // Loadout name - s?: IEquipmentSelection; // Suit - p?: IEquipmentSelection; // Secondary weapon - l?: IEquipmentSelection; // Primary weapon - m?: IEquipmentSelection; // Melee weapon - h?: IEquipmentSelection; // Gravimag weapon - a?: IEquipmentSelection; // Necromech exalted weapon - ItemId: IOid; - Remove?: boolean; // when client wants to remove a config, it only includes ItemId & Remove. -} - export enum UpgradeType { LotusWeaponsGrineerKuvaLichUpgradesInnateDamageRandomMod = "/Lotus/Weapons/Grineer/KuvaLich/Upgrades/InnateDamageRandomMod" } @@ -857,10 +723,6 @@ export interface ILoreFragmentScan { ItemType: string; } -export interface ILotusCustomization extends IItemConfig { - Persona: string; -} - export interface IMissionDatabase { Tag: string; Completes: number; @@ -1104,7 +966,7 @@ export interface ISettings { export interface IShipInventory { ItemType: string; - ShipExterior: IShipExterior; + ShipExterior: IShipCustomization; AirSupportPower: string; ItemId: IOid; } diff --git a/src/types/missionTypes.ts b/src/types/missionTypes.ts index bb70fc30..04317c3a 100644 --- a/src/types/missionTypes.ts +++ b/src/types/missionTypes.ts @@ -1,4 +1,4 @@ -import { IAffiliationMods, IInventoryChanges } from "./purchaseTypes"; +import { IAffiliationMods, IInventoryChanges } from "@/src/types/purchaseTypes"; export const inventoryFields = ["RawUpgrades", "MiscItems", "Consumables", "Recipes"] as const; export type IInventoryFieldType = (typeof inventoryFields)[number]; diff --git a/src/types/personalRoomsTypes.ts b/src/types/personalRoomsTypes.ts index 325ab9e4..d418fafc 100644 --- a/src/types/personalRoomsTypes.ts +++ b/src/types/personalRoomsTypes.ts @@ -1,18 +1,35 @@ -import { IColor } from "@/src/types/inventoryTypes/commonInventoryTypes"; -import { - IRoom, - IPlacedDecosDatabase, - ITailorShop, - ITailorShopDatabase, - TBootLocation, - IApartmentDatabase, - IApartmentClient -} from "@/src/types/shipTypes"; +import { IColor, IShipAttachments, IShipCustomization } from "@/src/types/inventoryTypes/commonInventoryTypes"; import { Document, Model, Types } from "mongoose"; +import { ILoadoutClient } from "@/src/types/saveLoadoutTypes"; +import { IMongoDate, IOid } from "@/src/types/commonTypes"; -export interface IOrbiter { +export interface IGetShipResponse { + ShipOwnerId: string; + Ship: IOrbiterClient; + Apartment: IApartmentClient; + TailorShop: ITailorShop; + LoadOutInventory: { LoadOutPresets: ILoadoutClient }; +} + +export type TBootLocation = "LISET" | "DRIFTER_CAMP" | "APARTMENT" | "SHOP"; + +export interface IOrbiterClient { + Features: string[]; + ShipId: IOid; + ShipInterior: IShipCustomization; + Rooms: IRoom[]; + VignetteFish?: string[]; + FavouriteLoadoutId?: IOid; + Wallpaper?: string; + Vignette?: string; + BootLocation?: TBootLocation; + ContentUrlSignature?: string; +} + +export interface IOrbiterDatabase { Features: string[]; Rooms: IRoom[]; + ShipInterior?: IShipCustomization; VignetteFish?: string[]; FavouriteLoadoutId?: Types.ObjectId; Wallpaper?: string; @@ -22,25 +39,169 @@ export interface IOrbiter { } export interface IPersonalRoomsClient { - ShipInteriorColors: IColor; - Ship: IOrbiter; + Ship: IOrbiterClient; Apartment: IApartmentClient; TailorShop: ITailorShop; } export interface IPersonalRoomsDatabase { - ShipInteriorColors: IColor; personalRoomsOwnerId: Types.ObjectId; activeShipId: Types.ObjectId; - Ship: IOrbiter; + + Ship: IOrbiterDatabase; Apartment: IApartmentDatabase; TailorShop: ITailorShopDatabase; } +export interface IRoom { + Name: string; + MaxCapacity: number; + PlacedDecos?: IPlacedDecosDatabase[]; +} + +export interface IPlantClient { + PlantType: string; + EndTime: IMongoDate; + PlotIndex: number; +} + +export interface IPlantDatabase extends Omit { + EndTime: Date; +} + +export interface IPlanterClient { + Name: string; + Plants: IPlantClient[]; +} + +export interface IPlanterDatabase { + Name: string; + Plants: IPlantDatabase[]; +} + +export interface IGardeningClient { + Planters: IPlanterClient[]; +} + +export interface IGardeningDatabase { + Planters: IPlanterDatabase[]; +} + +export interface IApartmentClient { + Gardening: IGardeningClient; + Rooms: IRoom[]; + FavouriteLoadouts: IFavouriteLoadout[]; +} + +export interface IApartmentDatabase { + Gardening: IGardeningDatabase; + Rooms: IRoom[]; + FavouriteLoadouts: IFavouriteLoadoutDatabase[]; +} + +export interface IPlacedDecosDatabase { + Type: string; + Pos: [number, number, number]; + Rot: [number, number, number]; + Scale?: number; + Sockets?: number; + PictureFrameInfo?: IPictureFrameInfo; + _id: Types.ObjectId; +} + +export interface IPlacedDecosClient extends Omit { + id: IOid; +} + +export interface ISetShipCustomizationsRequest { + ShipId: string; + Customization: { + SkinFlavourItem?: string; + Colors?: IColor; + ShipAttachments?: IShipAttachments; + LevelDecosVisible?: boolean; + CustomJson?: string; + }; + IsExterior: boolean; + AirSupportPower?: string; + IsShop?: boolean; +} + +export interface IShipDecorationsRequest { + Type: string; + Pos: [number, number, number]; + Rot: [number, number, number]; + Room: string; + BootLocation?: TBootLocation; + IsApartment?: boolean; + RemoveId?: string; + MoveId?: string; + OldRoom?: string; + Scale?: number; + Sockets?: number; +} + +export interface IShipDecorationsResponse { + DecoId?: string; + Room?: string; + IsApartment?: boolean; + MaxCapacityIncrease?: number; + OldRoom?: string; + NewRoom?: string; +} + +export interface ISetPlacedDecoInfoRequest { + DecoType: string; + DecoId: string; + Room: string; + PictureFrameInfo: IPictureFrameInfo; + BootLocation?: TBootLocation; + ComponentId?: string; + GuildId?: string; +} + +export interface IPictureFrameInfo { + Image: string; + Filter: string; + XOffset: number; + YOffset: number; + Scale: number; + InvertX: boolean; + InvertY: boolean; + ColorCorrection: number; + Text: string; + TextScale: number; + TextColorA: number; + TextColorB: number; + TextOrientation: number; +} + +export interface IFavouriteLoadout { + Tag: string; + LoadoutId: IOid; +} + +export interface IFavouriteLoadoutDatabase { + Tag: string; + LoadoutId: Types.ObjectId; +} + +export interface ITailorShopDatabase { + FavouriteLoadouts: IFavouriteLoadoutDatabase[]; + Colors?: IColor; + CustomJson?: string; + LevelDecosVisible?: boolean; + Rooms: IRoom[]; +} + +export interface ITailorShop extends Omit { + FavouriteLoadouts: IFavouriteLoadout[]; +} + export type RoomsType = { Name: string; MaxCapacity: number; PlacedDecos: Types.DocumentArray }; export type PersonalRoomsDocumentProps = { - Ship: Omit & { + Ship: Omit & { Rooms: RoomsType[]; }; Apartment: Omit & { diff --git a/src/types/purchaseTypes.ts b/src/types/purchaseTypes.ts index a1f475aa..1dcb0914 100644 --- a/src/types/purchaseTypes.ts +++ b/src/types/purchaseTypes.ts @@ -1,15 +1,15 @@ -import { IEquipmentClient } from "./inventoryTypes/commonInventoryTypes"; +import { ITypeCount } from "@/src/types/commonTypes"; +import { IEquipmentClient } from "@/src/types/equipmentTypes"; import { IDroneClient, IInfestedFoundryClient, IMiscItem, INemesisClient, - ITypeCount, IRecentVendorPurchaseClient, TEquipmentKey, ICrewMemberClient, IKubrowPetPrintClient -} from "./inventoryTypes/inventoryTypes"; +} from "@/src/types/inventoryTypes/inventoryTypes"; export enum PurchaseSource { Market = 0, diff --git a/src/types/requestTypes.ts b/src/types/requestTypes.ts index e2e5da92..c9292fc4 100644 --- a/src/types/requestTypes.ts +++ b/src/types/requestTypes.ts @@ -1,10 +1,9 @@ -import { IOid } from "./commonTypes"; -import { ArtifactPolarity, IPolarity, IEquipmentClient } from "@/src/types/inventoryTypes/commonInventoryTypes"; +import { IOid, ITypeCount } from "@/src/types/commonTypes"; +import { ArtifactPolarity, IPolarity } from "@/src/types/inventoryTypes/commonInventoryTypes"; import { IBooster, IChallengeProgress, IEvolutionProgress, - ITypeCount, IMission, IRawUpgrade, ISeasonChallenge, @@ -19,13 +18,14 @@ import { ICollectibleEntry, IDiscoveredMarker, ILockedWeaponGroupClient, - ILoadOutPresets, IInvasionProgressClient, IWeaponSkinClient, IKubrowPetEggClient, INemesisClient -} from "./inventoryTypes/inventoryTypes"; -import { IGroup } from "./loginTypes"; +} from "@/src/types/inventoryTypes/inventoryTypes"; +import { IGroup } from "@/src/types/loginTypes"; +import { ILoadOutPresets } from "@/src/types/saveLoadoutTypes"; +import { IEquipmentClient } from "@/src/types/equipmentTypes"; export interface IAffiliationChange { Tag: string; diff --git a/src/types/saveLoadoutTypes.ts b/src/types/saveLoadoutTypes.ts index 18d692c1..a4f76e12 100644 --- a/src/types/saveLoadoutTypes.ts +++ b/src/types/saveLoadoutTypes.ts @@ -1,14 +1,13 @@ import { IOid } from "@/src/types/commonTypes"; -import { IItemConfig, IOperatorConfigClient } from "@/src/types/inventoryTypes/commonInventoryTypes"; -import { Types } from "mongoose"; import { ICrewShipCustomization, - ICrewShipMembersClient, - ICrewShipWeapon, IFlavourItem, - ILoadoutConfigClient, - ILotusCustomization -} from "./inventoryTypes/inventoryTypes"; + IItemConfig, + ILotusCustomization, + IOperatorConfigClient +} from "@/src/types/inventoryTypes/commonInventoryTypes"; +import { Types } from "mongoose"; +import { ICrewShipMembersClient, ICrewShipWeapon, IEquipmentSelection } from "@/src/types/equipmentTypes"; export interface ISaveLoadoutRequest { LoadOuts: ILoadoutClient; @@ -40,6 +39,7 @@ export interface ISaveLoadoutRequest { CrewShips: IItemEntry; CurrentLoadOutIds: IOid[]; ValidNewLoadoutId: string; + ActiveCrewShip: IOid; EquippedGear: string[]; EquippedEmotes: string[]; UseAdultOperatorLoadout: boolean; @@ -72,7 +72,6 @@ export type IConfigEntry = { export type ILoadoutClient = Omit; -// keep in sync with ILoadOutPresets export interface ILoadoutDatabase { NORMAL: ILoadoutConfigDatabase[]; SENTINEL: ILoadoutConfigDatabase[]; @@ -89,9 +88,48 @@ export interface ILoadoutDatabase { loadoutOwnerId: Types.ObjectId; } +export interface ILoadOutPresets { + NORMAL: ILoadoutConfigClient[]; + NORMAL_PVP: ILoadoutConfigClient[]; + LUNARO: ILoadoutConfigClient[]; + ARCHWING: ILoadoutConfigClient[]; + SENTINEL: ILoadoutConfigClient[]; + OPERATOR: ILoadoutConfigClient[]; + GEAR: ILoadoutConfigClient[]; + KDRIVE: ILoadoutConfigClient[]; + DATAKNIFE: ILoadoutConfigClient[]; + MECH: ILoadoutConfigClient[]; + OPERATOR_ADULT: ILoadoutConfigClient[]; + DRIFTER: ILoadoutConfigClient[]; +} + export interface ILoadoutEntry { [key: string]: ILoadoutConfigClient; } + export interface ILoadoutConfigDatabase extends Omit { _id: Types.ObjectId; } + +export enum FocusSchool { + Attack = "AP_ATTACK", + Defense = "AP_DEFENSE", + Power = "AP_POWER", + Tactic = "AP_TACTIC", + Ward = "AP_WARD" +} + +export interface ILoadoutConfigClient { + FocusSchool?: FocusSchool; + PresetIcon?: string; + Favorite?: boolean; + n?: string; // Loadout name + s?: IEquipmentSelection; // Suit + p?: IEquipmentSelection; // Secondary weapon + l?: IEquipmentSelection; // Primary weapon + m?: IEquipmentSelection; // Melee weapon + h?: IEquipmentSelection; // Gravimag weapon + a?: IEquipmentSelection; // Necromech exalted weapon + ItemId: IOid; + Remove?: boolean; // when client wants to remove a config, it only includes ItemId & Remove. +} diff --git a/src/types/shipTypes.ts b/src/types/shipTypes.ts index 25555af7..4b070f65 100644 --- a/src/types/shipTypes.ts +++ b/src/types/shipTypes.ts @@ -1,40 +1,5 @@ import { Types } from "mongoose"; -import { IMongoDate, IOid } from "@/src/types/commonTypes"; -import { IColor } from "@/src/types/inventoryTypes/commonInventoryTypes"; -import { ILoadoutClient } from "./saveLoadoutTypes"; - -export interface IGetShipResponse { - ShipOwnerId: string; - Ship: IShip; - Apartment: IApartmentClient; - TailorShop: ITailorShop; - LoadOutInventory: { LoadOutPresets: ILoadoutClient }; -} - -export interface IShipAttachments { - HOOD_ORNAMENT: string; -} - -export interface IShipInterior { - Colors?: IColor; - ShipAttachments?: IShipAttachments; - SkinFlavourItem?: string; -} - -export type TBootLocation = "LISET" | "DRIFTER_CAMP" | "APARTMENT" | "SHOP"; - -export interface IShip { - Features: string[]; - ShipId: IOid; - ShipInterior: IShipInterior; - Rooms: IRoom[]; - VignetteFish?: string[]; - FavouriteLoadoutId?: IOid; - Wallpaper?: string; - Vignette?: string; - BootLocation?: TBootLocation; - ContentUrlSignature?: string; -} +import { IColor, IShipAttachments } from "@/src/types/inventoryTypes/commonInventoryTypes"; export interface IShipDatabase { ItemType: string; @@ -44,155 +9,3 @@ export interface IShipDatabase { ShipAttachments?: IShipAttachments; SkinFlavourItem?: string; } - -export interface IRoom { - Name: string; - MaxCapacity: number; - PlacedDecos?: IPlacedDecosDatabase[]; -} - -export interface IPlantClient { - PlantType: string; - EndTime: IMongoDate; - PlotIndex: number; -} - -export interface IPlantDatabase extends Omit { - EndTime: Date; -} - -export interface IPlanterClient { - Name: string; - Plants: IPlantClient[]; -} - -export interface IPlanterDatabase { - Name: string; - Plants: IPlantDatabase[]; -} - -export interface IGardeningClient { - Planters: IPlanterClient[]; -} - -export interface IGardeningDatabase { - Planters: IPlanterDatabase[]; -} - -export interface IApartmentClient { - Gardening: IGardeningClient; - Rooms: IRoom[]; - FavouriteLoadouts: IFavouriteLoadout[]; -} - -export interface IApartmentDatabase { - Gardening: IGardeningDatabase; - Rooms: IRoom[]; - FavouriteLoadouts: IFavouriteLoadoutDatabase[]; -} - -export interface IPlacedDecosDatabase { - Type: string; - Pos: [number, number, number]; - Rot: [number, number, number]; - Scale?: number; - Sockets?: number; - PictureFrameInfo?: IPictureFrameInfo; - _id: Types.ObjectId; -} - -export interface IPlacedDecosClient extends Omit { - id: IOid; -} - -export interface ISetShipCustomizationsRequest { - ShipId: string; - Customization: Customization; - IsExterior: boolean; - AirSupportPower?: string; - IsShop?: boolean; -} - -export interface Customization { - SkinFlavourItem: string; - Colors: IColor; - ShipAttachments: ShipAttachments; - LevelDecosVisible: boolean; - CustomJson: string; -} - -//TODO: check for more attachments -export interface ShipAttachments { - HOOD_ORNAMENT: string; -} - -export interface IShipDecorationsRequest { - Type: string; - Pos: [number, number, number]; - Rot: [number, number, number]; - Room: string; - BootLocation?: TBootLocation; - IsApartment?: boolean; - RemoveId?: string; - MoveId?: string; - OldRoom?: string; - Scale?: number; - Sockets?: number; -} - -export interface IShipDecorationsResponse { - DecoId?: string; - Room?: string; - IsApartment?: boolean; - MaxCapacityIncrease?: number; - OldRoom?: string; - NewRoom?: string; -} - -export interface ISetPlacedDecoInfoRequest { - DecoType: string; - DecoId: string; - Room: string; - PictureFrameInfo: IPictureFrameInfo; - BootLocation?: TBootLocation; - ComponentId?: string; - GuildId?: string; -} - -export interface IPictureFrameInfo { - Image: string; - Filter: string; - XOffset: number; - YOffset: number; - Scale: number; - InvertX: boolean; - InvertY: boolean; - ColorCorrection: number; - Text: string; - TextScale: number; - TextColorA: number; - TextColorB: number; - TextOrientation: number; -} - -export interface IFavouriteLoadout { - Tag: string; - LoadoutId: IOid; -} - -export interface IFavouriteLoadoutDatabase { - Tag: string; - LoadoutId: Types.ObjectId; -} - -export interface ITailorShopDatabase { - FavouriteLoadouts: IFavouriteLoadoutDatabase[]; - Colors?: IColor; - CustomJson: string; - LevelDecosVisible: boolean; - Rooms: IRoom[]; -} - -export interface ITailorShop extends Omit { - FavouriteLoadouts: IFavouriteLoadout[]; -} diff --git a/src/types/vendorTypes.ts b/src/types/vendorTypes.ts index 9249a9a0..2b64b5a3 100644 --- a/src/types/vendorTypes.ts +++ b/src/types/vendorTypes.ts @@ -1,4 +1,4 @@ -import { IMongoDate, IOid } from "./commonTypes"; +import { IMongoDate, IOid } from "@/src/types/commonTypes"; export interface IItemPrice { ItemType: string; diff --git a/src/types/worldStateTypes.ts b/src/types/worldStateTypes.ts index e49aa7cc..b83b787c 100644 --- a/src/types/worldStateTypes.ts +++ b/src/types/worldStateTypes.ts @@ -1,5 +1,5 @@ import { IMissionReward } from "warframe-public-export-plus"; -import { IMongoDate, IOid } from "./commonTypes"; +import { IMongoDate, IOid } from "@/src/types/commonTypes"; export interface IWorldState { Version: number; // for goals @@ -14,6 +14,7 @@ export interface IWorldState { GlobalUpgrades: IGlobalUpgrade[]; NodeOverrides: INodeOverride[]; VoidTraders: IVoidTrader[]; + PrimeVaultTraders: IPrimeVaultTrader[]; VoidStorms: IVoidStorm[]; DailyDeals: IDailyDeal[]; PVPChallengeInstances: IPVPChallengeInstance[]; @@ -171,6 +172,31 @@ export interface IVoidStorm { ActiveMissionTier: string; } +export interface IPrimeVaultTrader { + _id: IOid; + Activation: IMongoDate; + Expiry: IMongoDate; + InitialStartDate?: IMongoDate; + Node: string; + Manifest: IPrimeVaultTraderOffer[]; + EvergreenManifest: IPrimeVaultTraderOffer[]; + ScheduleInfo: IScheduleInfo[]; +} + +export interface IPrimeVaultTraderOffer { + ItemType: string; + PrimePrice?: number; + RegularPrice?: number; + StartDate?: IMongoDate; + EndDate?: IMongoDate; +} + +export interface IScheduleInfo { + Expiry: IMongoDate; + PreviewHiddenUntil?: IMongoDate; + FeaturedItem?: string; +} + export interface IDailyDeal { StoreItem: string; Activation: IMongoDate; diff --git a/static/fixed_responses/worldState/varzia.json b/static/fixed_responses/worldState/varzia.json new file mode 100644 index 00000000..8073d7e2 --- /dev/null +++ b/static/fixed_responses/worldState/varzia.json @@ -0,0 +1,1392 @@ +{ + "evergreen": [ + { "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Rifle/BratonPrime", "PrimePrice": 1 }, + { "ItemType": "/Lotus/StoreItems/Weapons/Tenno/LongGuns/PrimeBurston/PrimeBurston", "PrimePrice": 2 }, + { "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/DualDagger/FangPrimeDagger", "PrimePrice": 2 }, + { "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Pistols/PrimeLex/PrimeLex", "PrimePrice": 1 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/PrimeTwitchScarf", "PrimePrice": 2 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/TwitchPrimeScarf", "PrimePrice": 2 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/MeleeDangles/TwitchPrimeMeleeDangle", "PrimePrice": 1 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Liset/LisetSkinTwitchPrime", "RegularPrice": 10 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Sigils/TwitchPrimeSigil", "PrimePrice": 1 }, + { "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNecraloidBundle", "RegularPrice": 10 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Clan/TwitchNecraloidBadgeItem", "RegularPrice": 5 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/InfMembraneCape", "RegularPrice": 10 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/AmazonOniSyandana", "RegularPrice": 10 }, + { "ItemType": "/Lotus/StoreItems/Types/Game/ShipScenes/PrimeLisetFiligreeScene", "PrimePrice": 1 }, + { "ItemType": "/Lotus/StoreItems/Types/Game/ShipScenes/CorpusShipScene", "RegularPrice": 7 }, + { "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVVayasPrimeAccessories", "PrimePrice": 2 }, + { "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVAviaPrimeArmorSet", "PrimePrice": 2 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/PrimeAviaSyandana", "PrimePrice": 2 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/LasBackpackMedkitSyandana", "PrimePrice": 1 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Effects/TwitchEphemera", "PrimePrice": 1 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Loki/LokiTwitchSkin", "PrimePrice": 1 }, + { "ItemType": "/Lotus/StoreItems/Types/StoreItems/AvatarImages/AvatarImageLokiActionTwitch", "RegularPrice": 5 }, + { "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVVervArmorSet", "PrimePrice": 1 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Promo/Twitch/LisetSkinTwitch", "RegularPrice": 10 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Sigils/TwitchPromo2021Sigil", "RegularPrice": 5 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Clan/TwitchPromo2021BadgeItem", "RegularPrice": 5 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Weapons/Redeemer/RedeemerTwitchSkin", "RegularPrice": 7 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Promo/Twitch/Twitch2021AfurisSkin", "RegularPrice": 7 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Promo/Twitch/TwitchRubicoSkin", "RegularPrice": 7 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Promo/Twitch/TwitchPentaSkin", "RegularPrice": 7 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/Twitch2021Syandana", "RegularPrice": 10 }, + { "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVVervSentrexSentAccessories", "RegularPrice": 7 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Kubrows/Armor/Twitch2021IfritKubrowArmor", "RegularPrice": 7 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Catbrows/Armor/Twitch2021MyrdinCatbrowArmor", "RegularPrice": 7 }, + { "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/LisetPropCleaningDroneTwitch", "RegularPrice": 7 }, + { "ItemType": "/Lotus/StoreItems/Types/Game/QuartersWallpapers/TwitchPrimeWallpaper", "RegularPrice": 5 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/FlameScarfRefresh", "RegularPrice": 10 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/MeleeDangles/FireMeleeDangleRefresh", "RegularPrice": 6 }, + { "ItemType": "/Lotus/Types/StoreItems/Packages/PrimeColorPackA", "PrimePrice": 1 }, + { "ItemType": "/Lotus/StoreItems/Types/StoreItems/SuitCustomizations/ColourPickerPrimeDayItemA", "RegularPrice": 5 }, + { "ItemType": "/Lotus/StoreItems/Types/StoreItems/SuitCustomizations/ColourPickerTwitchItemC", "RegularPrice": 5 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Promo/Twitch/TigrisTwitchSkin", "RegularPrice": 7 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Promo/Twitch/TwitchAnkyros", "RegularPrice": 7 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Sigils/TwitchProminenceSigil", "RegularPrice": 5 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Promo/Twitch/ExcaliburTwitchSkin", "RegularPrice": 12 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Volt/VoltTwitchSkin", "RegularPrice": 12 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/TnLargeCapeTwitch", "RegularPrice": 10 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Bard/BardTwitchSkin", "PrimePrice": 1 }, + { "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVIridosArmorSet", "RegularPrice": 10 }, + { "ItemType": "/Lotus/StoreItems/Characters/Tenno/Accessory/Scarves/U17IntermScarf/IridosUdyatSkin/UdyatPrimeGamingSyandana", "RegularPrice": 10 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Promo/Twitch/PyranaTwitchSkin", "RegularPrice": 7 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Promo/Twitch/OgrisTwitchSkin", "RegularPrice": 7 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Weapons/Tonfa/KronenTwitchSkin", "RegularPrice": 7 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Promo/Twitch/AkjagaraIridosSkin", "RegularPrice": 7 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Liset/LisetInsectSkinIridos", "RegularPrice": 10 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Necramech/TefilahIridosSkin", "RegularPrice": 10 }, + { "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/LisetPropShawzinTwitch", "RegularPrice": 7 }, + { "ItemType": "/Lotus/StoreItems/Types/StoreItems/AvatarImages/AvatarImageOctaviaActionTwitch", "RegularPrice": 5 }, + { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Effects/OvergrowthEphemera", "RegularPrice": 10 }, + { "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/ResourceDecoItemCetusWispTwitch", "RegularPrice": 7 }, + { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/GaussPrimeSongItem", "RegularPrice": 5 }, + { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/GaraPrimeSongItem", "RegularPrice": 5 }, + { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/GrendelPrimeSongItem", "RegularPrice": 5 }, + { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/HildrynPrimeSongItem", "RegularPrice": 5 }, + { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/HydroidPrimeSongItem", "RegularPrice": 5 }, + { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/KhoraPrimeSongItem", "RegularPrice": 5 }, + { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/NekrosPrimeSongItem", "RegularPrice": 5 }, + { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/NidusPrimeSongItem", "RegularPrice": 5 }, + { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/OberonPrimeSongItem", "RegularPrice": 5 }, + { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/OctaviaPrimeSongItem", "RegularPrice": 5 }, + { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/RevenantPrimeSongItem", "RegularPrice": 5 }, + { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/VaubanPrimeSongItem", "RegularPrice": 5 }, + { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/ProteaPrimeSongItem", "RegularPrice": 5 }, + { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/WispPrimeSongItem", "RegularPrice": 5 }, + { "ItemType": "/Lotus/StoreItems/Types/Items/MiscItems/PrimeBucks", "RegularPrice": 1 }, + { "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVVoidTraceBundle", "RegularPrice": 1 } + ], + "primeSinglePacks": [ + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVRevenantPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Revenant/RevenantPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/LongGuns/PrimePhantasma/PhantasmaPrimeShotgun", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/Swords/PrimeTatsu/PrimeTatsuWeapon", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/PrimeRevenantCape", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVVetalaPrimeArmorSet", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/RevenantPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVBaruukPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Pacifist/BaruukPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Pistols/PrimeAfuris/PrimeAFurisWeapon", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/SwordsAndBoards/PrimeCobraAndCrane/PrimeCobraAndCraneWeapon", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/PrimeAkrabuSyandana", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Effects/BaruukPrimeEphemera", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/BaruukPrimePattern", + "PrimePrice": 1 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/BaruukPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNekrosPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Necro/NekrosPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/LongGuns/PrimeTigris/PrimeTigris", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/Swords/PrimeGalatine/PrimeGalatine", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVAcanthusPrimeArmorSet", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/UruPrimeScarf", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/NekrosPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVOberonPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Paladin/PaladinPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/LongGuns/PrimeSybaris/PrimeSybarisRifle", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/PrimeSilvaAegis/PrimeSilvaAegis", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/MeleeDangles/SurakaPrimeDangle", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/PrimeOberonCape", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/OberonPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVBansheePrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Banshee/BansheePrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/PrimeScarfF", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVIctusPrimeSentAccessories", + "PrimePrice": 1 + }, + { + "ItemType": "/Lotus/StoreItems/Types/Sentinels/SentinelPowersuits/PrimeHeliosPowerSuit", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Pistols/AllNew1hSG/AllNew1hSG", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/BansheePrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVMiragePrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Banshee/MiragePrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/PrimeScarfG", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVAtavistPrimeArmorSet", + "PrimePrice": 1 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/PrimeKogake/KogakePrimeKnuckles", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Pistols/PrimeAkbolto/PrimeAkBoltoWeapon", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/MiragePrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNidusPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Infestation/InfestationPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/StoreItems/Types/Game/ShipScenes/NidusPrimeScene", + "PrimePrice": 1 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/NidusPrimeSyandana", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Necramech/InfestedNecraMechSkin", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/LongGuns/PrimeStrun/PrimeStrunWeapon", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Pistols/PrimeMagnus/PrimeMagnusWeapon", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/InfestationPrimeShipMaggot", + "PrimePrice": 1 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/NidusPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVSarynPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Saryn/SarynPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/StoreItems/Characters/Tenno/Accessory/Scarves/PrimeScarfD/Cloth/PrimeScarfDItem", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Sigils/PrimeAccessSigilSaryn", + "PrimePrice": 1 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/Swords/PrimeKatana/PrimeNikana", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/ThrowingWeapons/PrimeLiDagger/PrimeLiDagger", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/SarynPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVEmberPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Ember/EmberPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVTitanPrimeSet", + "PrimePrice": 1 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/Glaives/PrimeGlaive/PrimeGlaiveWeapon", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/PrimeFlameScarf", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Pistols/PrimeSicarus/PrimeSicarusPistol", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/EmberPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVRhinoPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Rhino/RhinoPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/NoruPrimeScarf", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVDistillingExtractorPrimeSet", + "PrimePrice": 1 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/LongGuns/PrimeBoltor/PrimeBoltor", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/Gauntlet/PrimeAnkyros/PrimeAnkyros", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/RhinoPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVInarosPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Sandman/InarosPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVMittahkPrimeArmorSet", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/PrimeInarosSyandana", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/LongGuns/PrimePanthera/PrimePanthera", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/Swords/PrimeKaryst/PrimeKrisDagger", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/InarosPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVAshPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Ninja/AshPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVUndaPrimeSentAccessories", + "PrimePrice": 1 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/YamakoPrimeScarf", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Types/Sentinels/SentinelPowersuits/PrimeCarrierPowerSuit", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/LongGuns/PrimeVectis/PrimeVectisRifle", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/AshPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVMagPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Mag/MagPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Shotgun/PrimeBoar", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/CronusSword/PrimeCronusLongSword", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVTargisPrimeArmorSet", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVDistillingExtractorPrimeSet", + "PrimePrice": 1 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/MagPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVFrostPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Frost/FrostPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVTitanPrimeSet", + "PrimePrice": 1 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/PrimeScarf", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/Scythe/ReaperWeapon", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Rifle/LatronPrime", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/FrostPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVEquinoxPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/YinYang/EquinoxPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/PrimeCapeEquinox", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNarvarrPrimeArmorSet", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/LongGuns/PrimeStradavar/PrimeStradavarGun", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/Staff/TipedoPrime/TipedoPrimeWeapon", + "PrimePrice": 2 + } + ], + "BobbleHeads": [ + "/Lotus/StoreItems/Types/Items/ShipDecos/EquinoxPrimeBobbleHead", + "/Lotus/StoreItems/Types/Items/ShipDecos/EquinoxPrimeNightBobbleHead", + "/Lotus/StoreItems/Types/Items/ShipDecos/EquinoxPrimeDayBobbleHead" + ] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVWukongPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/MonkeyKing/WukongPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/PrimeWukongSyandana", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVWukongPrimeKubrowArmor", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Effects/EphemeraPrimeA", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/LongGuns/PrimeZhuge/PrimeZhugeCrossbow", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/PrimeNinkondi/PrimeNikondi", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/WukongPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVTitaniaPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Fairy/TitaniaPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/TitaniaPrimeSyandana", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Archwing/TitaniaPrimeArchwingSkin", + "PrimePrice": 1 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/Swords/PrimePangolinSword/PrimePangolinSword", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/LongGuns/PrimeCorinth/PrimeCorinth", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/TitaniaPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVGaraPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Glass/GaraPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Effects/EphemeraGaraPrime", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVCastellanPrimeKavatArmor", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/LongGuns/PrimeAstilla/AstillaPrimeWeapon", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/PrimeVolnus/VolnusPrimeWeapon", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/GaraPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVMesaPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Cowgirl/MesaPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVOperatorPrimeAccessories", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Cowgirl/MesaPrimeAltHelmet", + "PrimePrice": 1 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/MeleeDangles/PrimeDangleF", + "PrimePrice": 1 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Pistols/PrimeAkjagara/AkJagaraPrime", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/Gunblade/RedeemerPrime/RedeemerPrimeWep", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/MesaPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVHydroidPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Pirate/HydroidPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVSpritsailPrimeArmorSet", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/MeleeDangles/PrimeDangleEMeleeDangle", + "PrimePrice": 1 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/Swords/PrimeNamiSkyla/PrimeNamiSkyla", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Pistols/PrimeBallistica/PrimeBallistica", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/HydroidPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVAtlasPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Brawler/AtlasPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/PrimeScarfAtlas", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVOrcusPrimeSentAccessories", + "PrimePrice": 1 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/PrimeTekko/PrimeTekko", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Types/Sentinels/SentinelPowersuits/PrimeDethCubePowerSuit", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/AtlasPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVVaubanPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Trapper/TrapperPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/PrimeScarfV", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/MeleeDangles/CatenoPrimeMeleeDangle", + "PrimePrice": 1 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/PrimeFragor/PrimeFragor", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Pistols/PrimeAkstiletto/PrimeAkstiletto", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/VaubanPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVVoltPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Volt/VoltPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/MeleeDangles/KazeruPrimeMeleeDangle", + "PrimePrice": 1 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVEdoPrimeArmorSet", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Powersuits/Archwing/PrimeJetPack/PrimeJetPack", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/VoltPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVLokiPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Loki/LokiPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/MeleeDangles/PrimeMeleeDangle", + "PrimePrice": 1 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVSummusPrimeSentAccessories", + "PrimePrice": 1 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/Staff/PrimeBo/PrimeBoWeapon", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Types/Sentinels/SentinelPowersuits/PrimeWyrmPowerSuit", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/LokiPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNyxPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Jade/NyxPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVTargisPrimeArmorSet", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/MeleeDangles/ValaPrimeMeleeDangle", + "PrimePrice": 1 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/Axe/PrimeScindo/PrimeScindoWeapon", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/ThrowingWeapons/PrimeThrowingStar/PrimeHikou", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/NyxPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVLimboPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Magician/LimboPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/PrimeLimboCape", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Sigils/PrimeAccessSigilLimbo", + "PrimePrice": 1 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/Swords/PRapier/DestrezaPrime", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Pistols/PrimePyrana/PrimePyranaPistol", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/LimboPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVTrinityPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Trinity/TrinityPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVKavasaPrimeKubrowArmor", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/MeleeDangles/ScrollingPrimeMeleeDangle", + "PrimePrice": 1 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/PrimeDualKamas/PrimeDualKamas", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/TrinityPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVIvaraPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Ranger/IvaraPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/IvaraPrimeCape", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVAnasaAyatanPrimeArmorSet", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/LongGuns/PrimeBaza/PrimeBazaGun", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Pistols/PrimeAksomati/PrimeAksomati", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/IvaraPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVGarudaPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Garuda/GarudaPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Effects/GarudaPrimeEphemera", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVKukriPrimeArmorSet", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/LongGuns/PrimeNagantaka/PrimeNagantakaWeapon", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Archwing/Primary/PrimeCorvas/PrimeCorvasWeapon", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/GarudaPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVKhoraPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Khora/KhoraPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Khora/KhoraPrimeAltHelmet", + "PrimePrice": 1 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/KhoraPrimeSyandana", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Types/Items/Emotes/KhoraPrimeEmote", + "PrimePrice": 1 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Pistols/PrimeHystrix/PrimeHystrixWeapon", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/Swords/PrimeDualKeres/PrimeDualKeresWeapon", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/KhoraPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVZephyrPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Tengu/ZephyrPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/LongGuns/PrimeTiberon/PrimeTiberonRifle", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/Tonfa/TonfaContestWinnerPrime/TonfaContestWinnerPrimeWeapon", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVCommodorePrimeSuit", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVTiborPrimeKavatArmor", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/ZephyrPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVChromaPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Dragon/ChromaPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/LongGuns/RubicoPrime/RubicoPrimeWeapon", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/Swords/PrimeGram/PrimeGram", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/PrimeChromaCape", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVImugiPrimeArmorSet", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/ChromaPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNovaPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/AntiMatter/NovaPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVEdoPrimeArmorSet", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Sigils/PrimeAccessSigilFive", + "PrimePrice": 1 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Pistols/PrimeVasto/PrimeVastoPistol", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/LongGuns/PrimeSoma/PrimeSomaRifle", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/NovaPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVTrinityPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Trinity/TrinityPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVKavasaPrimeKubrowArmor", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/MeleeDangles/ScrollingPrimeMeleeDangle", + "PrimePrice": 1 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/PrimeDualKamas/PrimeDualKamas", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/TrinityPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNezhaPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Nezha/NezhaPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVRanshaPrimeArmorSet", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Effects/EphemeraNezhaPrime", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/Polearms/PrimeGuandao/PrimeGuandaoWeapon", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Pistols/PrimeZakti/PrimeZaktiPistol", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/NezhaPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVOctaviaPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Bard/OctaviaPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVGlissandaPrimeArmorSet", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/PrimeOctaviaSyandana", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/LisetPropShawzinPrime", + "PrimePrice": 1 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/LongGuns/PrimeTenora/TenoraPrimeWeapon", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Pistols/PrimePandero/PanderoPrimeWeapon", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/OctaviaPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVHarrowPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Priest/HarrowPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/PrimeNaveScarf", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVTemplarPrimeSuit", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/LongGuns/PrimeScourge/PrimeScourgeWeapon", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Pistols/PrimeKnell/PrimeKnellWeapon", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/HarrowPrimeBobbleHead"] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVValkyrPrimeSinglePack", + "Items": [ + { + "ItemType": "/Lotus/StoreItems/Powersuits/Berserker/ValkyrPrime", + "PrimePrice": 3 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Bows/PrimeCernos/PrimeCernos", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/PrimeVenKa/PrimeVenkaClaws", + "PrimePrice": 2 + }, + { + "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Liset/LisetSkinPrime", + "PrimePrice": 1 + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVSaitaPrimeSuit", + "PrimePrice": 2 + } + ], + "BobbleHeads": ["/Lotus/StoreItems/Types/Items/ShipDecos/ValkyrPrimeBobbleHead"] + } + ], + "primeDualPacks": [ + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVRevenantBaruukPrimeDualPack", + "SinglePacks": ["/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVRevenantPrimeSinglePack", "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVBaruukPrimeSinglePack"], + "Relics": [ + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionRevenantBaruukVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionRevenantBaruukVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionRevenantBaruukVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionRevenantBaruukVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionRevenantBaruukVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionRevenantBaruukVaultBBronze" + ] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNekrosOberonPrimeDualPack", + "SinglePacks": ["/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNekrosPrimeSinglePack", "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVOberonPrimeSinglePack"], + "Relics": [ + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionOberonNekrosVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionOberonNekrosVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionOberonNekrosVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionOberonNekrosVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionOberonNekrosVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionOberonNekrosVaultABronze" + ] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVBansheeMiragePrimeDualPack", + "SinglePacks": ["/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVBansheePrimeSinglePack", "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVMiragePrimeSinglePack"], + "Relics": [ + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionBansheeMirageVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionBansheeMirageVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionBansheeMirageVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionBansheeMirageVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionBansheeMirageVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionBansheeMirageVaultBBronze" + ] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNidusSarynPrimeDualPack", + "SinglePacks": ["/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNidusPrimeSinglePack", "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVSarynPrimeSinglePack"], + "Relics": [ + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionNidusSarynVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionNidusSarynVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionNidusSarynVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionNidusSarynVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionNidusSarynVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionNidusSarynVaultABronze" + ] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVEmberRhinoPrimeDualPack", + "SinglePacks": ["/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVEmberPrimeSinglePack", "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVRhinoPrimeSinglePack"], + "Relics": [ + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionEmberRhinoVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionEmberRhinosVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionEmberRhinosVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionEmberRhinoVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionEmberRhinoVaultABronze" + ] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVInarosAshPrimeDualPack", + "SinglePacks": ["/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVInarosPrimeSinglePack", "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVAshPrimeSinglePack"], + "Relics": [ + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionInarosAshVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionInarosAshVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionInarosAshVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionInarosAshVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionInarosAshVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionInarosAshVaultBBronze" + ] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVFrostMagPrimeDualPack", + "SinglePacks": ["/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVMagPrimeSinglePack", "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVFrostPrimeSinglePack"], + "Relics": [ + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionFrostMagVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionFrostMagVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionFrostMagVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionFrostMagVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionFrostMagVaultABronze" + ] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVEquinoxWukongPrimeDualPack", + "SinglePacks": ["/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVEquinoxPrimeSinglePack", "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVWukongPrimeSinglePack"], + "Relics": [ + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionWukongEquinoxVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionWukongEquinoxVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionWukongEquinoxVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionWukongEquinoxVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionWukongEquinoxVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionWukongEquinoxVaultABronze" + ] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVTitaniaGaraPrimeDualPack", + "SinglePacks": ["/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVTitaniaPrimeSinglePack", "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVGaraPrimeSinglePack"], + "Relics": [ + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionTitaniaGaraVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionTitaniaGaraVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionTitaniaGaraVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionTitaniaGaraVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionTitaniaGaraVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionTitaniaGaraVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionTitaniaGaraVaultBBronze" + ] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVMesaHydroidPrimeDualPack", + "SinglePacks": ["/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVMesaPrimeSinglePack", "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVHydroidPrimeSinglePack"], + "Relics": [ + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionMesaHydroidVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionMesaHydroidVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionMesaHydroidVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionMesaHydroidVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionMesaHydroidVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionMesaHydroidVaultABronze" + ] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVAtlasVaubanPrimeDualPack", + "SinglePacks": ["/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVAtlasPrimeSinglePack", "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVVaubanPrimeSinglePack"], + "Relics": [ + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionAtlasVaubanVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionAtlasVaubanVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionAtlasVaubanVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionAtlasVaubanVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionAtlasVaubanVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionAtlasVaubanVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionAtlasVaubanVaultABronze" + ] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVVoltLokiPrimeDualPack", + "SinglePacks": ["/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVVoltPrimeSinglePack", "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVLokiPrimeSinglePack"], + "Relics": [ + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionLokiVoltVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionLokiVoltVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionLokiVoltVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionLokiVoltVaultABronze" + ] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVRhinoNyxPrimeDualPack", + "SinglePacks": ["/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVRhinoPrimeSinglePack", "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNyxPrimeSinglePack"], + "Relics": [ + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionRhinoNyxVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionRhinoNyxVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionRhinoNyxVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionRhinoNyxVaultABronze" + ] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVLimboTrinityPrimeDualPack", + "SinglePacks": ["/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVLimboPrimeSinglePack", "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVTrinityPrimeSinglePack"], + "Relics": [ + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionLimboTrinityVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionLimboTrinityVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionLimboTrinityVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionLimboTrinityVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionLimboTrinityVaultABronze" + ] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVIvaraOberonPrimeDualPack", + "SinglePacks": ["/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVIvaraPrimeSinglePack", "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVOberonPrimeSinglePack"], + "Relics": [ + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionIvaraOberonVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionIvaraOberonVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionIvaraOberonVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionIvaraOberonVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionIvaraOberonVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionIvaraOberonVaultBBronze" + ] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVGarudaKhoraPrimeDualPack", + "SinglePacks": ["/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVGarudaPrimeSinglePack", "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVKhoraPrimeSinglePack"], + "Relics": [ + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionGarudaKhoraVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionGarudaKhoraVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionGarudaKhoraVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionGarudaKhoraVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionGarudaKhoraVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionGarudaKhoraVaultBBronze" + ] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVZephyrChromaPrimeDualPack", + "SinglePacks": ["/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVZephyrPrimeSinglePack", "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVChromaPrimeSinglePack"], + "Relics": [ + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionChromaZephyrVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionChromaZephyrVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionChromaZephyrVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionChromaZephyrVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionChromaZephyrVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionChromaZephyrVaultABronze" + ] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNovaTrinityPrimeDualPack", + "SinglePacks": ["/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNovaPrimeSinglePack", "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVTrinityPrimeSinglePack"], + "Relics": [ + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionNovaTrinityVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionNovaTrinityVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionNovaTrinityVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionNovaTrinityVaultABronze" + ] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNezhaOctaviaPrimeDualPack", + "SinglePacks": ["/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNezhaPrimeSinglePack", "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVOctaviaPrimeSinglePack"], + "Relics": [ + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionNezhaOctaviaVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionNezhaOctaviaVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionNezhaOctaviaVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionNezhaOctaviaVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionNezhaOctaviaVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionNezhaOctaviaVaultABronze" + ] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVMesaLimboPrimeDualPack", + "SinglePacks": ["/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVMesaPrimeSinglePack", "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVLimboPrimeSinglePack"], + "Relics": [ + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionMesaLimboVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionMesaLimboVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionMesaLimboVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionMesaLimboVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionMesaLimboVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionMesaLimboVaultABronze" + ] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVHarrowNekrosPrimeDualPack", + "SinglePacks": ["/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVHarrowPrimeSinglePack", "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNekrosPrimeSinglePack"], + "Relics": [ + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionHarrowNekrosVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionHarrowNekrosVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionHarrowNekrosVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionHarrowNekrosVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionHarrowNekrosVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionHarrowNekrosVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionHarrowNekrosVaultBBronze" + ] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVValkyrSarynPrimeDualPack", + "SinglePacks": ["/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVValkyrPrimeSinglePack", "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVSarynPrimeSinglePack"], + "Relics": [ + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionSarynValkyrVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionSarynValkyrVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionSarynValkyrVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionSarynValkyrVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionSarynValkyrVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionSarynValkyrVaultBBronze" + ] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVMagRhinoPrimeDualPack", + "SinglePacks": ["/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVRhinoPrimeSinglePack", "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVMagPrimeSinglePack"], + "Relics": [ + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionYVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionYVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionYVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionYVaultABronze" + ] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVEmberFrostPrimeDualPack", + "SinglePacks": ["/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVEmberPrimeSinglePack", "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVFrostPrimeSinglePack"], + "Relics": [ + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionQVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionQVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionQVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionQVaultABronze" + ] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVAshVaubanPrimeDualPack", + "SinglePacks": ["/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVAshPrimeSinglePack", "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVVaubanPrimeSinglePack"], + "Relics": [ + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionAshVaubanVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionAshVaubanVaultBBronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionAshVaubanVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionAshVaubanVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionAshVaubanVaultABronze" + ] + }, + { + "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVMagNovaPrimeDualPack", + "SinglePacks": ["/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVMagPrimeSinglePack", "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNovaPrimeSinglePack"], + "Relics": [ + "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionMagNovaVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionMagNovaVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionMagNovaVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionMagNovaVaultABronze", + "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionMagNovaVaultBBronze" + ] + } + ] +} diff --git a/static/fixed_responses/worldState/worldState.json b/static/fixed_responses/worldState/worldState.json index 74d5c9ea..9afa5cc5 100644 --- a/static/fixed_responses/worldState/worldState.json +++ b/static/fixed_responses/worldState/worldState.json @@ -347,169 +347,9 @@ "Activation": { "$date": { "$numberLong": "1563030000000" } } } ], - "PrimeVaultTraders": [ - { - "_id": { "$oid": "631f8c4ac36af423770eaa97" }, - "Activation": { "$date": { "$numberLong": "1712858400000" } }, - "InitialStartDate": { "$date": { "$numberLong": "2000000000000" } }, - "Node": "TradeHUB1", - "Manifest": [ - { "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVEquinoxPrimeSinglePack", "PrimePrice": 6 }, - { "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVEquinoxWukongPrimeDualPack", "PrimePrice": 10 }, - { "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVWukongPrimeSinglePack", "PrimePrice": 6 }, - { "ItemType": "/Lotus/StoreItems/Powersuits/YinYang/EquinoxPrime", "PrimePrice": 3 }, - { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/PrimeCapeEquinox", "PrimePrice": 2 }, - { "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNarvarrPrimeArmorSet", "PrimePrice": 2 }, - { "ItemType": "/Lotus/StoreItems/Weapons/Tenno/LongGuns/PrimeStradavar/PrimeStradavarGun", "PrimePrice": 2 }, - { "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/Staff/TipedoPrime/TipedoPrimeWeapon", "PrimePrice": 2 }, - { "ItemType": "/Lotus/StoreItems/Powersuits/MonkeyKing/WukongPrime", "PrimePrice": 3 }, - { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/PrimeWukongSyandana", "PrimePrice": 2 }, - { "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVWukongPrimeKubrowArmor", "PrimePrice": 2 }, - { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Effects/EphemeraPrimeA", "PrimePrice": 2 }, - { "ItemType": "/Lotus/StoreItems/Weapons/Tenno/LongGuns/PrimeZhuge/PrimeZhugeCrossbow", "PrimePrice": 2 }, - { "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/PrimeNinkondi/PrimeNikondi", "PrimePrice": 2 }, - { "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/EquinoxPrimeBobbleHead", "PrimePrice": 1 }, - { "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/EquinoxPrimeNightBobbleHead", "PrimePrice": 1 }, - { "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/EquinoxPrimeDayBobbleHead", "PrimePrice": 1 }, - { "ItemType": "/Lotus/StoreItems/Types/Items/ShipDecos/WukongPrimeBobbleHead", "PrimePrice": 1 }, - { "ItemType": "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionWukongEquinoxVaultABronze", "RegularPrice": 1 }, - { "ItemType": "/Lotus/StoreItems/Types/Game/Projections/T1VoidProjectionWukongEquinoxVaultBBronze", "RegularPrice": 1 }, - { "ItemType": "/Lotus/StoreItems/Types/Game/Projections/T2VoidProjectionWukongEquinoxVaultABronze", "RegularPrice": 1 }, - { "ItemType": "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionWukongEquinoxVaultABronze", "RegularPrice": 1 }, - { "ItemType": "/Lotus/StoreItems/Types/Game/Projections/T3VoidProjectionWukongEquinoxVaultBBronze", "RegularPrice": 1 }, - { "ItemType": "/Lotus/StoreItems/Types/Game/Projections/T4VoidProjectionWukongEquinoxVaultABronze", "RegularPrice": 1 } - ], - "Expiry": { "$date": { "$numberLong": "2000000000000" } }, - "EvergreenManifest": [ - { "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Melee/DualDagger/FangPrimeDagger", "PrimePrice": 2 }, - { "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Pistols/PrimeLex/PrimeLex", "PrimePrice": 1 }, - { "ItemType": "/Lotus/StoreItems/Types/Game/ShipScenes/PrimeLisetFiligreeScene", "PrimePrice": 1 }, - { "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVAviaPrimeArmorSet", "PrimePrice": 2 }, - { "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVVayasPrimeAccessories", "PrimePrice": 2 }, - { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/MeleeDangles/TwitchPrimeMeleeDangle", "PrimePrice": 1 }, - { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/PrimeAviaSyandana", "PrimePrice": 2 }, - { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/PrimeTwitchScarf", "PrimePrice": 2 }, - { "ItemType": "/Lotus/StoreItems/Weapons/Tenno/LongGuns/PrimeBurston/PrimeBurston", "PrimePrice": 2 }, - { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/TwitchPrimeScarf", "PrimePrice": 2 }, - { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Sigils/TwitchPrimeSigil", "PrimePrice": 1 }, - { "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNecraloidBundle", "RegularPrice": 10 }, - { "ItemType": "/Lotus/StoreItems/Weapons/Tenno/Rifle/BratonPrime", "PrimePrice": 1 }, - { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Liset/LisetSkinTwitchPrime", "RegularPrice": 10 }, - { "ItemType": "/Lotus/StoreItems/Upgrades/Skins/Scarves/InfMembraneCape", "RegularPrice": 10 }, - { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/GaraPrimeSongItem", "RegularPrice": 5 }, - { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/GaussPrimeSongItem", "RegularPrice": 5 }, - { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/GrendelPrimeSongItem", "RegularPrice": 5 }, - { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/HildrynPrimeSongItem", "RegularPrice": 5 }, - { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/HydroidPrimeSongItem", "RegularPrice": 5 }, - { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/KhoraPrimeSongItem", "RegularPrice": 5 }, - { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/NekrosPrimeSongItem", "RegularPrice": 5 }, - { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/NidusPrimeSongItem", "RegularPrice": 5 }, - { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/OberonPrimeSongItem", "RegularPrice": 5 }, - { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/OctaviaPrimeSongItem", "RegularPrice": 5 }, - { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/RevenantPrimeSongItem", "RegularPrice": 5 }, - { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/VaubanPrimeSongItem", "RegularPrice": 5 }, - { "ItemType": "/Lotus/StoreItems/Types/Items/SongItems/ProteaPrimeSongItem", "RegularPrice": 5 }, - { "ItemType": "/Lotus/StoreItems/Types/Items/MiscItems/PrimeBucks", "RegularPrice": 1 }, - { "ItemType": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVVoidTraceBundle", "RegularPrice": 1 } - ], - "ScheduleInfo": [ - { "Expiry": { "$date": { "$numberLong": "1667498400000" } }, "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVEquinoxWukongPrimeDualPack" }, - { "Expiry": { "$date": { "$numberLong": "1669921200000" } }, "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVValkyrSarynPrimeDualPack" }, - { - "Expiry": { "$date": { "$numberLong": "1672945200000" } }, - "PreviewHiddenUntil": { "$date": { "$numberLong": "1668711600000" } }, - "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVOberonPrimeSinglePack" - }, - { - "Expiry": { "$date": { "$numberLong": "1675364400000" } }, - "PreviewHiddenUntil": { "$date": { "$numberLong": "1671130800000" } }, - "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVVoltLokiPrimeDualPack" - }, - { - "Expiry": { "$date": { "$numberLong": "1677783600000" } }, - "PreviewHiddenUntil": { "$date": { "$numberLong": "1674154800000" } }, - "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVAtlasVaubanPrimeDualPack" - }, - { - "Expiry": { "$date": { "$numberLong": "1680804000000" } }, - "PreviewHiddenUntil": { "$date": { "$numberLong": "1676473200000" } }, - "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNekrosOberonPrimeDualPack" - }, - { - "Expiry": { "$date": { "$numberLong": "1683223200000" } }, - "PreviewHiddenUntil": { "$date": { "$numberLong": "1679594400000" } }, - "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVMagRhinoPrimeDualPack" - }, - { - "Expiry": { "$date": { "$numberLong": "1685718000000" } }, - "PreviewHiddenUntil": { "$date": { "$numberLong": "1682013600000" } }, - "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNekrosOberonPrimeDualPack" - }, - { - "Expiry": { "$date": { "$numberLong": "1688666400000" } }, - "PreviewHiddenUntil": { "$date": { "$numberLong": "1684433100000" } }, - "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVInarosAshPrimeDualPack" - }, - { - "Expiry": { "$date": { "$numberLong": "1691085600000" } }, - "PreviewHiddenUntil": { "$date": { "$numberLong": "1687456800000" } }, - "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVBansheeMiragePrimeDualPack" - }, - { - "Expiry": { "$date": { "$numberLong": "1694109600000" } }, - "PreviewHiddenUntil": { "$date": { "$numberLong": "1689876000000" } }, - "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVFrostMagPrimeDualPack" - }, - { - "Expiry": { "$date": { "$numberLong": "1696528800000" } }, - "PreviewHiddenUntil": { "$date": { "$numberLong": "1692900000000" } }, - "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVEquinoxWukongPrimeDualPack" - }, - { - "Expiry": { "$date": { "$numberLong": "1698948000000" } }, - "PreviewHiddenUntil": { "$date": { "$numberLong": "1695319200000" } }, - "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVZephyrChromaPrimeDualPack" - }, - { - "Expiry": { "$date": { "$numberLong": "1703185200000" } }, - "PreviewHiddenUntil": { "$date": { "$numberLong": "1697738400000" } }, - "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVNezhaOctaviaPrimeDualPack" - }, - { - "Expiry": { "$date": { "$numberLong": "1704394800000" } }, - "PreviewHiddenUntil": { "$date": { "$numberLong": "1697738400000" } }, - "FeaturedItem": "/Lotus/StoreItems/Types/StoreItems/Packages/MegaPrimeVault/LastChanceItemC" - }, - { "Expiry": { "$date": { "$numberLong": "1705604400000" } }, "FeaturedItem": "/Lotus/StoreItems/Types/StoreItems/Packages/MegaPrimeVault/LastChanceItemC" }, - { "Expiry": { "$date": { "$numberLong": "1706814000000" } }, "FeaturedItem": "/Lotus/StoreItems/Types/StoreItems/Packages/MegaPrimeVault/LastChanceItemC" }, - { "Expiry": { "$date": { "$numberLong": "1708023600000" } }, "FeaturedItem": "/Lotus/StoreItems/Types/StoreItems/Packages/MegaPrimeVault/LastChanceItemC" }, - { - "Expiry": { "$date": { "$numberLong": "1710439200000" } }, - "PreviewHiddenUntil": { "$date": { "$numberLong": "1706814000000" } }, - "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVBansheeMiragePrimeDualPack" - }, - { - "Expiry": { "$date": { "$numberLong": "1712858400000" } }, - "PreviewHiddenUntil": { "$date": { "$numberLong": "1709233200000" } }, - "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVTitaniaGaraPrimeDualPack" - }, - { - "Expiry": { "$date": { "$numberLong": "1715277600000" } }, - "PreviewHiddenUntil": { "$date": { "$numberLong": "1711648800000" } }, - "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVInarosAshPrimeDualPack" - }, - { - "Expiry": { "$date": { "$numberLong": "1717696800000" } }, - "PreviewHiddenUntil": { "$date": { "$numberLong": "1714068000000" } }, - "FeaturedItem": "/Lotus/Types/StoreItems/Packages/MegaPrimeVault/MPVEquinoxWukongPrimeDualPack" - }, - { "Expiry": { "$date": { "$numberLong": "1720116000000" } }, "PreviewHiddenUntil": { "$date": { "$numberLong": "1716487200000" } } } - ] - } - ], "PrimeAccessAvailability": { "State": "PRIME1" }, "PrimeVaultAvailabilities": [false, false, false, false, false], - "PrimeTokenAvailability": true, + "PrimeTokenAvailability": false, "LibraryInfo": { "LastCompletedTargetType": "/Lotus/Types/Game/Library/Targets/Research7Target" }, "PVPChallengeInstances": [ { diff --git a/static/webui/index.html b/static/webui/index.html index 20064f77..a258ad35 100644 --- a/static/webui/index.html +++ b/static/webui/index.html @@ -864,9 +864,13 @@ +
+ + +
- @@ -875,7 +879,7 @@
- @@ -883,7 +887,7 @@
- @@ -891,7 +895,7 @@
- @@ -902,7 +906,7 @@
- @@ -924,12 +928,16 @@
-
+
+ + +
diff --git a/static/webui/script.js b/static/webui/script.js index 4d726036..05ccc157 100644 --- a/static/webui/script.js +++ b/static/webui/script.js @@ -285,6 +285,7 @@ function fetchItemList() { document.getElementById("changeSyndicate").appendChild(syndicateNone); document.getElementById("valenceBonus-innateDamage").innerHTML = ""; + document.getElementById("worldState.varziaOverride").innerHTML = ""; // prettier-ignore data.archonCrystalUpgrades = { @@ -420,6 +421,11 @@ function fetchItemList() { name: loc("code_pigment") }); + data.VarziaOffers.unshift({ + uniqueName: "", + name: loc("disabled") + }); + const itemMap = { // Generics for rivens "/Lotus/Weapons/Tenno/Archwing/Primary/ArchGun": { name: loc("code_archgun") }, @@ -469,6 +475,13 @@ function fetchItemList() { option.textContent = name; document.getElementById("valenceBonus-innateDamage").appendChild(option); }); + } else if (type == "VarziaOffers") { + items.forEach(item => { + const option = document.createElement("option"); + option.value = item.uniqueName; + option.textContent = item.name; + document.getElementById("worldState.varziaOverride").appendChild(option); + }); } else if (type == "uniqueLevelCaps") { uniqueLevelCaps = items; } else if (type == "Syndicates") { diff --git a/static/webui/translations/de.js b/static/webui/translations/de.js index 26d9fd19..f660562c 100644 --- a/static/webui/translations/de.js +++ b/static/webui/translations/de.js @@ -246,6 +246,8 @@ dict = { worldState_allAtOnceSteelPath: `[UNTRANSLATED] All At Once, Steel Path`, worldState_theCircuitOverride: `[UNTRANSLATED] The Circuit Override`, worldState_darvoStockMultiplier: `[UNTRANSLATED] Darvo Stock Multiplier`, + worldState_varziaFullyStocked: `[UNTRANSLATED] Varzia Fully Stocked`, + worldState_varziaOverride: `[UNTRANSLATED] Varzia Rotation Override`, import_importNote: `Du kannst hier eine vollständige oder teilweise Inventarantwort (Client-Darstellung) einfügen. Alle Felder, die vom Importer unterstützt werden, werden in deinem Account überschrieben.`, import_submit: `Absenden`, @@ -300,8 +302,8 @@ dict = { upgrade_OnExecutionBlind: `[UNTRANSLATED] Blind enemies within 18m on Mercy`, upgrade_OnExecutionDrainPower: `[UNTRANSLATED] +100% chance for next ability cast to gain +50% Ability Strength on Mercy`, upgrade_OnHackSprintSpeed: `[UNTRANSLATED] +75% Sprint Speed for 15s after Hacking`, - upgrade_SwiftExecute: `[UNTRANSLATED] Speed of Mercy Kills increased by 50%`, - upgrade_OnHackInvis: `[UNTRANSLATED] Invisible for 15 seconds after hacking`, + upgrade_SwiftExecute: `[UNTRANSLATED] +50% Mercy Kill Speed`, + upgrade_OnHackInvis: `[UNTRANSLATED] Invisible for 15 seconds after Hacking`, damageType_Electricity: `Elektrizität`, damageType_Fire: `Hitze`, diff --git a/static/webui/translations/en.js b/static/webui/translations/en.js index e94c94bc..ebe474ec 100644 --- a/static/webui/translations/en.js +++ b/static/webui/translations/en.js @@ -245,6 +245,8 @@ dict = { worldState_allAtOnceSteelPath: `All At Once, Steel Path`, worldState_theCircuitOverride: `The Circuit Override`, worldState_darvoStockMultiplier: `Darvo Stock Multiplier`, + worldState_varziaFullyStocked: `Varzia Fully Stocked`, + worldState_varziaOverride: `Varzia Rotation Override`, import_importNote: `You can provide a full or partial inventory response (client respresentation) here. All fields that are supported by the importer will be overwritten in your account.`, import_submit: `Submit`, @@ -299,8 +301,8 @@ dict = { upgrade_OnExecutionBlind: `Blind enemies within 18m on Mercy`, upgrade_OnExecutionDrainPower: `+100% chance for next ability cast to gain +50% Ability Strength on Mercy`, upgrade_OnHackSprintSpeed: `+75% Sprint Speed for 15s after Hacking`, - upgrade_SwiftExecute: `Speed of Mercy Kills increased by 50%`, - upgrade_OnHackInvis: `Invisible for 15 seconds after hacking`, + upgrade_SwiftExecute: `+50% Mercy Kill Speed`, + upgrade_OnHackInvis: `Invisible for 15 seconds after Hacking`, damageType_Electricity: `Electricity`, damageType_Fire: `Heat`, diff --git a/static/webui/translations/es.js b/static/webui/translations/es.js index 6776aba6..d40839b0 100644 --- a/static/webui/translations/es.js +++ b/static/webui/translations/es.js @@ -246,6 +246,8 @@ dict = { worldState_allAtOnceSteelPath: `Todo a la vez, Camino de Acero`, worldState_theCircuitOverride: `Cambio del Circuito`, worldState_darvoStockMultiplier: `Multiplicador de stock de Darvo`, + worldState_varziaFullyStocked: `[UNTRANSLATED] Varzia Fully Stocked`, + worldState_varziaOverride: `[UNTRANSLATED] Varzia Rotation Override`, import_importNote: `Puedes proporcionar una respuesta de inventario completa o parcial (representación del cliente) aquí. Todos los campos compatibles con el importador serán sobrescritos en tu cuenta.`, import_submit: `Enviar`, @@ -300,8 +302,8 @@ dict = { upgrade_OnExecutionBlind: `Ciega a los enemigos en un radio de 18m tras una ejecución`, upgrade_OnExecutionDrainPower: `100% de probabilidad de que la siguiente habilidad tenga +50% de fuerza tras una ejecución`, upgrade_OnHackSprintSpeed: `+75% de velocidad de carrera durante 15s después de hackear`, - upgrade_SwiftExecute: `Velocidad de ejecuciones aumentada en un 50%`, - upgrade_OnHackInvis: `Invisible durante 15 segundos después de hackear`, + upgrade_SwiftExecute: `[UNTRANSLATED] +50% Mercy Kill Speed`, + upgrade_OnHackInvis: `[UNTRANSLATED] Invisible for 15 seconds after Hacking`, damageType_Electricity: `Eletricidade`, damageType_Fire: `Ígneo`, diff --git a/static/webui/translations/fr.js b/static/webui/translations/fr.js index 28112086..be690a49 100644 --- a/static/webui/translations/fr.js +++ b/static/webui/translations/fr.js @@ -246,6 +246,8 @@ dict = { worldState_allAtOnceSteelPath: `[UNTRANSLATED] All At Once, Steel Path`, worldState_theCircuitOverride: `[UNTRANSLATED] The Circuit Override`, worldState_darvoStockMultiplier: `[UNTRANSLATED] Darvo Stock Multiplier`, + worldState_varziaFullyStocked: `[UNTRANSLATED] Varzia Fully Stocked`, + worldState_varziaOverride: `[UNTRANSLATED] Varzia Rotation Override`, import_importNote: `Import manuel. Toutes les modifcations supportées par l'inventaire écraseront celles présentes dans la base de données.`, import_submit: `Soumettre`, @@ -300,8 +302,8 @@ dict = { upgrade_OnExecutionBlind: `Les ennemis sont aveuglés dans un rayon de 18 après une miséricorde`, upgrade_OnExecutionDrainPower: `100% pour le prochain pouvoir de gagner +50% de puissance de pouvoir sur miséricorde`, upgrade_OnHackSprintSpeed: `+75% de vitesse de course pendant 15s après un piratage`, - upgrade_SwiftExecute: `Vitesse des miséricordes augmentée de 50%`, - upgrade_OnHackInvis: `Invisible pendant 15 secondes après un piratage`, + upgrade_SwiftExecute: `[UNTRANSLATED] +50% Mercy Kill Speed`, + upgrade_OnHackInvis: `[UNTRANSLATED] Invisible for 15 seconds after Hacking`, damageType_Electricity: `Électrique`, damageType_Fire: `Feu`, diff --git a/static/webui/translations/ru.js b/static/webui/translations/ru.js index c3ca845b..c32aabe3 100644 --- a/static/webui/translations/ru.js +++ b/static/webui/translations/ru.js @@ -246,6 +246,8 @@ dict = { worldState_allAtOnceSteelPath: `[UNTRANSLATED] All At Once, Steel Path`, worldState_theCircuitOverride: `[UNTRANSLATED] The Circuit Override`, worldState_darvoStockMultiplier: `[UNTRANSLATED] Darvo Stock Multiplier`, + worldState_varziaFullyStocked: `Полный Ассортимент Варзии`, + worldState_varziaOverride: `Изменение Ротации Варзии`, import_importNote: `Вы можете загрузить полный или частичный ответ инвентаря (клиентское представление) здесь. Все поддерживаемые поля будут перезаписаны в вашем аккаунте.`, import_submit: `Отправить`, @@ -300,8 +302,8 @@ dict = { upgrade_OnExecutionBlind: `[UNTRANSLATED] Blind enemies within 18m on Mercy`, upgrade_OnExecutionDrainPower: `[UNTRANSLATED] +100% chance for next ability cast to gain +50% Ability Strength on Mercy`, upgrade_OnHackSprintSpeed: `[UNTRANSLATED] +75% Sprint Speed for 15s after Hacking`, - upgrade_SwiftExecute: `[UNTRANSLATED] Speed of Mercy Kills increased by 50%`, - upgrade_OnHackInvis: `[UNTRANSLATED] Invisible for 15 seconds after hacking`, + upgrade_SwiftExecute: `[UNTRANSLATED] +50% Mercy Kill Speed`, + upgrade_OnHackInvis: `[UNTRANSLATED] Invisible for 15 seconds after Hacking`, damageType_Electricity: `Электричество`, damageType_Fire: `Огонь`, diff --git a/static/webui/translations/zh.js b/static/webui/translations/zh.js index bb8677ed..b1a3100f 100644 --- a/static/webui/translations/zh.js +++ b/static/webui/translations/zh.js @@ -246,6 +246,8 @@ dict = { worldState_allAtOnceSteelPath: `全部开启(钢铁之路)`, worldState_theCircuitOverride: `无尽回廊任务循环配置:`, worldState_darvoStockMultiplier: `Darvo特惠库存倍率`, + worldState_varziaFullyStocked: `[UNTRANSLATED] Varzia Fully Stocked`, + worldState_varziaOverride: `[UNTRANSLATED] Varzia Rotation Override`, import_importNote: `您可以在此处提供完整或部分库存响应(客户端表示)。支持的所有字段将被覆盖到您的账户中。`, import_submit: `提交`, @@ -300,8 +302,8 @@ dict = { upgrade_OnExecutionBlind: `怜悯之击致盲18米范围内的敌人`, upgrade_OnExecutionDrainPower: `怜悯之击会使下一个技能有100%的机会获得+50%的技能强度`, upgrade_OnHackSprintSpeed: `入侵后+75%冲刺速度,持续15秒`, - upgrade_SwiftExecute: `怜悯之击速度提升50%`, - upgrade_OnHackInvis: `入侵后隐身15秒`, + upgrade_SwiftExecute: `[UNTRANSLATED] +50% Mercy Kill Speed`, + upgrade_OnHackInvis: `[UNTRANSLATED] Invisible for 15 seconds after Hacking`, damageType_Electricity: `电击`, damageType_Fire: `火焰`,