From cca1dc67f4695a5036e166061910d03fa410be74 Mon Sep 17 00:00:00 2001 From: Yuzu Date: Sat, 17 Aug 2024 21:11:09 +0700 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat!:=20Switched=20to=20NekoMelody?= =?UTF-8?q?=20for=20music?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitmodules | 3 + NekoMelody | 1 + package.json | 123 +- pnpm-lock.yaml | 3766 ++++++++++++++++++++ src/discord/Developer/Debug.ts | 2 +- src/discord/Developer/VRChatLogin.ts | 2 - src/discord/MusicPlayer/Join.ts | 75 +- src/discord/MusicPlayer/Leave.ts | 2 +- src/discord/MusicPlayer/Loop.ts | 4 +- src/discord/MusicPlayer/NowPlaying.ts | 58 +- src/discord/MusicPlayer/Pause.ts | 4 +- src/discord/MusicPlayer/Play.ts | 118 +- src/discord/MusicPlayer/PlayMy.ts | 43 +- src/discord/MusicPlayer/Queue.ts | 86 +- src/discord/MusicPlayer/Resume.ts | 4 +- src/discord/MusicPlayer/Search.ts | 2 +- src/discord/MusicPlayer/Skip.ts | 6 +- src/providers/DiscordMusicPlayer.ts | 271 +- src/providers/DiscordMusicPlayerTempFix.ts | 792 ---- 19 files changed, 4097 insertions(+), 1265 deletions(-) create mode 100644 .gitmodules create mode 160000 NekoMelody create mode 100644 pnpm-lock.yaml delete mode 100644 src/providers/DiscordMusicPlayerTempFix.ts diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..330d7b6 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "NekoMelody"] + path = NekoMelody + url = https://github.com/YuzuZensai/NekoMelody.git diff --git a/NekoMelody b/NekoMelody new file mode 160000 index 0000000..45a4a9f --- /dev/null +++ b/NekoMelody @@ -0,0 +1 @@ +Subproject commit 45a4a9ff64489cbee008743b75950426b7172429 diff --git a/package.json b/package.json index e1c5ddf..8027acc 100644 --- a/package.json +++ b/package.json @@ -1,62 +1,65 @@ { - "dependencies": { - "@discordjs/opus": "^0.9.0", - "@discordjs/rest": "^2.3.0", - "@discordjs/voice": "^0.17.0", - "@types/color-thief-node": "^1.0.4", - "@types/cors": "^2.8.17", - "@types/express": "^4.17.21", - "@types/os-utils": "^0.0.4", - "bluebird": "^3.7.2", - "bufferutil": "^4.0.8", - "color-thief-node": "^1.0.4", - "cors": "^2.8.5", - "country-code-emoji": "^2.3.0", - "country-code-lookup": "^0.1.3", - "discord-api-types": "^0.37.89", - "discord.js": "^14.15.3", - "dotenv": "^16.4.5", - "express": "^4.19.2", - "i18n": "^0.15.1", - "libsodium-wrappers": "^0.7.13", - "node-osu": "^2.2.1", - "os-utils": "^0.0.14", - "ping": "^0.4.4", - "play-dl": "^1.9.7", - "ts-custom-error": "^3.3.1", - "typescript": "^5.4.5", - "utf-8-validate": "^6.0.4", - "validator": "^13.12.0", - "vrchat": "^1.17.6", - "winston": "^3.13.0", - "yt-dlp-wrap": "^2.3.12", - "zlib-sync": "^0.1.9" - }, - "devDependencies": { - "@prisma/client": "^5.15.0", - "@types/bluebird": "^3.5.42", - "@types/i18n": "^0.13.12", - "@types/node": "^20.14.2", - "@types/ping": "^0.4.4", - "@types/validator": "^13.11.10", - "copyfiles": "^2.4.1", - "prisma": "^5.15.0", - "ts-node-dev": "^2.0.0" - }, - "scripts": { - "tsc": "tsc", - "development": "ts-node-dev ./src/index.ts --respawn --transpileOnly", - "build": "tsc -b && copyfiles -u 1 configs_example/**/*.* dist/configs_example/", - "docker-build": "docker build . -t ghcr.io/kirameki-cafe/yumi:latest", - "docker-run": "docker run -d --name yumi --mount type=bind,source=\"$(pwd)\"/configs,target=/home/node/app/configs --network host --env-file .env ghcr.io/kirameki-cafe/yumi:latest", - "docker-push": "docker push ghcr.io/kirameki-cafe/yumi:latest", - "production": "tsc && node ./dist/index.js", - "test": "mocha -r ts-node/register tests/**/*.ts" - }, - "name": "yumi", - "version": "1.0.0", - "main": "index.js", - "repository": "https://github.com/kirameki-cafe/Yumi.git", - "author": "Kirameki Café ", - "license": "GPL-3.0" + "dependencies": { + "@discordjs/opus": "^0.9.0", + "@discordjs/rest": "^2.3.0", + "@discordjs/voice": "^0.17.0", + "@types/color-thief-node": "^1.0.4", + "@types/cors": "^2.8.17", + "@types/express": "^4.17.21", + "@types/os-utils": "^0.0.4", + "bluebird": "^3.7.2", + "bufferutil": "^4.0.8", + "color-thief-node": "^1.0.4", + "cors": "^2.8.5", + "country-code-emoji": "^2.3.0", + "country-code-lookup": "^0.1.3", + "discord-api-types": "^0.37.89", + "discord.js": "^14.15.3", + "dotenv": "^16.4.5", + "express": "^4.19.2", + "i18n": "^0.15.1", + "libsodium-wrappers": "^0.7.13", + "node-osu": "^2.2.1", + "os-utils": "^0.0.14", + "ping": "^0.4.4", + "play-dl": "^1.9.7", + "ts-custom-error": "^3.3.1", + "typescript": "^5.4.5", + "utf-8-validate": "^6.0.4", + "validator": "^13.12.0", + "vrchat": "^1.17.6", + "winston": "^3.13.0", + "yt-dlp-wrap": "^2.3.12", + "zlib-sync": "^0.1.9" + }, + "devDependencies": { + "@discordjs/builders": "^1.8.2", + "@prisma/client": "^5.15.0", + "@types/bluebird": "^3.5.42", + "@types/i18n": "^0.13.12", + "@types/node": "^20.14.2", + "@types/ping": "^0.4.4", + "@types/validator": "^13.11.10", + "copyfiles": "^2.4.1", + "prisma": "^5.15.0", + "ts-node-dev": "^2.0.0", + "tsup": "^8.2.4" + }, + "scripts": { + "tsc": "tsc", + "development": "ts-node-dev ./src/index.ts --respawn --transpileOnly", + "build": "tsc -b && copyfiles -u 1 configs_example/**/*.* dist/configs_example/", + "docker-build": "docker build . -t ghcr.io/kirameki-cafe/yumi:latest", + "docker-run": "docker run -d --name yumi --mount type=bind,source=\"$(pwd)\"/configs,target=/home/node/app/configs --network host --env-file .env ghcr.io/kirameki-cafe/yumi:latest", + "docker-push": "docker push ghcr.io/kirameki-cafe/yumi:latest", + "production": "tsc && node ./dist/index.js", + "test": "mocha -r ts-node/register tests/**/*.ts" + }, + "name": "yumi", + "version": "1.0.0", + "main": "index.js", + "repository": "https://github.com/kirameki-cafe/Yumi.git", + "author": "Kirameki Café ", + "license": "GPL-3.0", + "packageManager": "pnpm@9.4.0+sha512.f549b8a52c9d2b8536762f99c0722205efc5af913e77835dbccc3b0b0b2ca9e7dc8022b78062c17291c48e88749c70ce88eb5a74f1fa8c4bf5e18bb46c8bd83a" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..cd99f0b --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,3766 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@discordjs/opus': + specifier: ^0.9.0 + version: 0.9.0 + '@discordjs/rest': + specifier: ^2.3.0 + version: 2.3.0 + '@discordjs/voice': + specifier: ^0.17.0 + version: 0.17.0(@discordjs/opus@0.9.0)(bufferutil@4.0.8)(utf-8-validate@6.0.4) + '@types/color-thief-node': + specifier: ^1.0.4 + version: 1.0.4 + '@types/cors': + specifier: ^2.8.17 + version: 2.8.17 + '@types/express': + specifier: ^4.17.21 + version: 4.17.21 + '@types/os-utils': + specifier: ^0.0.4 + version: 0.0.4 + bluebird: + specifier: ^3.7.2 + version: 3.7.2 + bufferutil: + specifier: ^4.0.8 + version: 4.0.8 + color-thief-node: + specifier: ^1.0.4 + version: 1.0.4 + cors: + specifier: ^2.8.5 + version: 2.8.5 + country-code-emoji: + specifier: ^2.3.0 + version: 2.3.0 + country-code-lookup: + specifier: ^0.1.3 + version: 0.1.3 + discord-api-types: + specifier: ^0.37.89 + version: 0.37.90 + discord.js: + specifier: ^14.15.3 + version: 14.15.3(bufferutil@4.0.8)(utf-8-validate@6.0.4) + dotenv: + specifier: ^16.4.5 + version: 16.4.5 + express: + specifier: ^4.19.2 + version: 4.19.2 + i18n: + specifier: ^0.15.1 + version: 0.15.1 + libsodium-wrappers: + specifier: ^0.7.13 + version: 0.7.13 + node-osu: + specifier: ^2.2.1 + version: 2.2.1 + os-utils: + specifier: ^0.0.14 + version: 0.0.14 + ping: + specifier: ^0.4.4 + version: 0.4.4 + play-dl: + specifier: ^1.9.7 + version: 1.9.7 + ts-custom-error: + specifier: ^3.3.1 + version: 3.3.1 + typescript: + specifier: ^5.4.5 + version: 5.5.2 + utf-8-validate: + specifier: ^6.0.4 + version: 6.0.4 + validator: + specifier: ^13.12.0 + version: 13.12.0 + vrchat: + specifier: ^1.17.6 + version: 1.17.6 + winston: + specifier: ^3.13.0 + version: 3.13.0 + yt-dlp-wrap: + specifier: ^2.3.12 + version: 2.3.12 + zlib-sync: + specifier: ^0.1.9 + version: 0.1.9 + devDependencies: + '@discordjs/builders': + specifier: ^1.8.2 + version: 1.8.2 + '@prisma/client': + specifier: ^5.15.0 + version: 5.15.1(prisma@5.15.1) + '@types/bluebird': + specifier: ^3.5.42 + version: 3.5.42 + '@types/i18n': + specifier: ^0.13.12 + version: 0.13.12 + '@types/node': + specifier: ^20.14.2 + version: 20.14.8 + '@types/ping': + specifier: ^0.4.4 + version: 0.4.4 + '@types/validator': + specifier: ^13.11.10 + version: 13.12.0 + copyfiles: + specifier: ^2.4.1 + version: 2.4.1 + prisma: + specifier: ^5.15.0 + version: 5.15.1 + ts-node-dev: + specifier: ^2.0.0 + version: 2.0.0(@types/node@20.14.8)(typescript@5.5.2) + tsup: + specifier: ^8.2.4 + version: 8.2.4(typescript@5.5.2) + +packages: + + '@colors/colors@1.6.0': + resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} + engines: {node: '>=0.1.90'} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@dabh/diagnostics@2.0.3': + resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==} + + '@discordjs/builders@1.8.2': + resolution: {integrity: sha512-6wvG3QaCjtMu0xnle4SoOIeFB4y6fKMN6WZfy3BMKJdQQtPLik8KGzDwBVL/+wTtcE/ZlFjgEk74GublyEVZ7g==} + engines: {node: '>=16.11.0'} + + '@discordjs/collection@1.5.3': + resolution: {integrity: sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==} + engines: {node: '>=16.11.0'} + + '@discordjs/collection@2.1.0': + resolution: {integrity: sha512-mLcTACtXUuVgutoznkh6hS3UFqYirDYAg5Dc1m8xn6OvPjetnUlf/xjtqnnc47OwWdaoCQnHmHh9KofhD6uRqw==} + engines: {node: '>=18'} + + '@discordjs/formatters@0.4.0': + resolution: {integrity: sha512-fJ06TLC1NiruF35470q3Nr1bi95BdvKFAF+T5bNfZJ4bNdqZ3VZ+Ttg6SThqTxm6qumSG3choxLBHMC69WXNXQ==} + engines: {node: '>=16.11.0'} + + '@discordjs/node-pre-gyp@0.4.5': + resolution: {integrity: sha512-YJOVVZ545x24mHzANfYoy0BJX5PDyeZlpiJjDkUBM/V/Ao7TFX9lcUvCN4nr0tbr5ubeaXxtEBILUrHtTphVeQ==} + hasBin: true + + '@discordjs/opus@0.9.0': + resolution: {integrity: sha512-NEE76A96FtQ5YuoAVlOlB3ryMPrkXbUCTQICHGKb8ShtjXyubGicjRMouHtP1RpuDdm16cDa+oI3aAMo1zQRUQ==} + engines: {node: '>=12.0.0'} + + '@discordjs/rest@2.3.0': + resolution: {integrity: sha512-C1kAJK8aSYRv3ZwMG8cvrrW4GN0g5eMdP8AuN8ODH5DyOCbHgJspze1my3xHOAgwLJdKUbWNVyAeJ9cEdduqIg==} + engines: {node: '>=16.11.0'} + + '@discordjs/util@1.1.0': + resolution: {integrity: sha512-IndcI5hzlNZ7GS96RV3Xw1R2kaDuXEp7tRIy/KlhidpN/BQ1qh1NZt3377dMLTa44xDUNKT7hnXkA/oUAzD/lg==} + engines: {node: '>=16.11.0'} + + '@discordjs/voice@0.17.0': + resolution: {integrity: sha512-hArn9FF5ZYi1IkxdJEVnJi+OxlwLV0NJYWpKXsmNOojtGtAZHxmsELA+MZlu2KW1F/K1/nt7lFOfcMXNYweq9w==} + engines: {node: '>=16.11.0'} + + '@discordjs/ws@1.1.1': + resolution: {integrity: sha512-PZ+vLpxGCRtmr2RMkqh8Zp+BenUaJqlS6xhgWKEZcgC/vfHLEzpHtKkB0sl3nZWpwtcKk6YWy+pU3okL2I97FA==} + engines: {node: '>=16.11.0'} + + '@esbuild/aix-ppc64@0.23.1': + resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.23.1': + resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.23.1': + resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.23.1': + resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.23.1': + resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.23.1': + resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.23.1': + resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.23.1': + resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.23.1': + resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.23.1': + resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.23.1': + resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.23.1': + resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.23.1': + resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.23.1': + resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.23.1': + resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.23.1': + resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.23.1': + resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.23.1': + resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.23.1': + resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.23.1': + resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.23.1': + resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.23.1': + resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.23.1': + resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.23.1': + resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.4.15': + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@mapbox/node-pre-gyp@1.0.11': + resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==} + hasBin: true + + '@messageformat/core@3.3.0': + resolution: {integrity: sha512-YcXd3remTDdeMxAlbvW6oV9d/01/DZ8DHUFwSttO3LMzIZj3iO0NRw+u1xlsNNORFI+u0EQzD52ZX3+Udi0T3g==} + + '@messageformat/date-skeleton@1.0.1': + resolution: {integrity: sha512-jPXy8fg+WMPIgmGjxSlnGJn68h/2InfT0TNSkVx0IGXgp4ynnvYkbZ51dGWmGySEK+pBiYUttbQdu5XEqX5CRg==} + + '@messageformat/number-skeleton@1.2.0': + resolution: {integrity: sha512-xsgwcL7J7WhlHJ3RNbaVgssaIwcEyFkBqxHdcdaiJzwTZAWEOD8BuUFxnxV9k5S0qHN3v/KzUpq0IUpjH1seRg==} + + '@messageformat/parser@5.1.0': + resolution: {integrity: sha512-jKlkls3Gewgw6qMjKZ9SFfHUpdzEVdovKFtW1qRhJ3WI4FW5R/NnGDqr8SDGz+krWDO3ki94boMmQvGke1HwUQ==} + + '@messageformat/runtime@3.0.1': + resolution: {integrity: sha512-6RU5ol2lDtO8bD9Yxe6CZkl0DArdv0qkuoZC+ZwowU+cdRlVE1157wjCmlA5Rsf1Xc/brACnsZa5PZpEDfTFFg==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@prisma/client@5.15.1': + resolution: {integrity: sha512-fmZRGmsUJ9+VwC/AvfP/PwdpD0xAEyPvNsD9/B3+GYpETq9VejVRT3PiqNvl76q1uYYzNZeo8u/LmzzTetHSEg==} + engines: {node: '>=16.13'} + peerDependencies: + prisma: '*' + peerDependenciesMeta: + prisma: + optional: true + + '@prisma/debug@5.15.1': + resolution: {integrity: sha512-NQjdEplhXEcPvf84ghxExC+LD+iTimbg3sZvA3BhybVQIocBEBxFf9GTHhmRVPmjrWoBaYJBVgEEBXZT27JTbQ==} + + '@prisma/engines-version@5.15.1-1.5675a3182f972f1a8f31d16eee6abf4fd54910e3': + resolution: {integrity: sha512-7csphKGCG6n/cN1MkT1mJvQ78Ir18IknlYZ8eyEoLKdQBb0HscR/6TyPmzqrMA7Rz01K1KeXqctwAqxtA/lKQg==} + + '@prisma/engines@5.15.1': + resolution: {integrity: sha512-1iTRxJEFvpBpEWf2bYiMG6LBBQhX7X+GA5piH+tmPWgc/v+/ElxQf2kjQxby8AErmZqtZkdoKJ7FSRjNjBPE9Q==} + + '@prisma/fetch-engine@5.15.1': + resolution: {integrity: sha512-mj0wfsJ+mAdDp1ynT2JKxAXa+CoYMT267qF7g2Uv+oaVTI2CMfGWouMARht8T2QLTgl+gpXSFTwIYbcR+oWEtw==} + + '@prisma/get-platform@5.15.1': + resolution: {integrity: sha512-oFccp7bYys+ZYkmtYzjR+0cRrGKvSuF+h5QhSkyEsYQ9kzJzQRvuWt2SiHRPt8xOQ4MTmujM+bP5uOexnnAHdQ==} + + '@rollup/rollup-android-arm-eabi@4.20.0': + resolution: {integrity: sha512-TSpWzflCc4VGAUJZlPpgAJE1+V60MePDQnBd7PPkpuEmOy8i87aL6tinFGKBFKuEDikYpig72QzdT3QPYIi+oA==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.20.0': + resolution: {integrity: sha512-u00Ro/nok7oGzVuh/FMYfNoGqxU5CPWz1mxV85S2w9LxHR8OoMQBuSk+3BKVIDYgkpeOET5yXkx90OYFc+ytpQ==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.20.0': + resolution: {integrity: sha512-uFVfvzvsdGtlSLuL0ZlvPJvl6ZmrH4CBwLGEFPe7hUmf7htGAN+aXo43R/V6LATyxlKVC/m6UsLb7jbG+LG39Q==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.20.0': + resolution: {integrity: sha512-xbrMDdlev53vNXexEa6l0LffojxhqDTBeL+VUxuuIXys4x6xyvbKq5XqTXBCEUA8ty8iEJblHvFaWRJTk/icAQ==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-linux-arm-gnueabihf@4.20.0': + resolution: {integrity: sha512-jMYvxZwGmoHFBTbr12Xc6wOdc2xA5tF5F2q6t7Rcfab68TT0n+r7dgawD4qhPEvasDsVpQi+MgDzj2faOLsZjA==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.20.0': + resolution: {integrity: sha512-1asSTl4HKuIHIB1GcdFHNNZhxAYEdqML/MW4QmPS4G0ivbEcBr1JKlFLKsIRqjSwOBkdItn3/ZDlyvZ/N6KPlw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.20.0': + resolution: {integrity: sha512-COBb8Bkx56KldOYJfMf6wKeYJrtJ9vEgBRAOkfw6Ens0tnmzPqvlpjZiLgkhg6cA3DGzCmLmmd319pmHvKWWlQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.20.0': + resolution: {integrity: sha512-+it+mBSyMslVQa8wSPvBx53fYuZK/oLTu5RJoXogjk6x7Q7sz1GNRsXWjn6SwyJm8E/oMjNVwPhmNdIjwP135Q==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.20.0': + resolution: {integrity: sha512-yAMvqhPfGKsAxHN8I4+jE0CpLWD8cv4z7CK7BMmhjDuz606Q2tFKkWRY8bHR9JQXYcoLfopo5TTqzxgPUjUMfw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.20.0': + resolution: {integrity: sha512-qmuxFpfmi/2SUkAw95TtNq/w/I7Gpjurx609OOOV7U4vhvUhBcftcmXwl3rqAek+ADBwSjIC4IVNLiszoj3dPA==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.20.0': + resolution: {integrity: sha512-I0BtGXddHSHjV1mqTNkgUZLnS3WtsqebAXv11D5BZE/gfw5KoyXSAXVqyJximQXNvNzUo4GKlCK/dIwXlz+jlg==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.20.0': + resolution: {integrity: sha512-y+eoL2I3iphUg9tN9GB6ku1FA8kOfmF4oUEWhztDJ4KXJy1agk/9+pejOuZkNFhRwHAOxMsBPLbXPd6mJiCwew==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.20.0': + resolution: {integrity: sha512-hM3nhW40kBNYUkZb/r9k2FKK+/MnKglX7UYd4ZUy5DJs8/sMsIbqWK2piZtVGE3kcXVNj3B2IrUYROJMMCikNg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.20.0': + resolution: {integrity: sha512-psegMvP+Ik/Bg7QRJbv8w8PAytPA7Uo8fpFjXyCRHWm6Nt42L+JtoqH8eDQ5hRP7/XW2UiIriy1Z46jf0Oa1kA==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.20.0': + resolution: {integrity: sha512-GabekH3w4lgAJpVxkk7hUzUf2hICSQO0a/BLFA11/RMxQT92MabKAqyubzDZmMOC/hcJNlc+rrypzNzYl4Dx7A==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.20.0': + resolution: {integrity: sha512-aJ1EJSuTdGnM6qbVC4B5DSmozPTqIag9fSzXRNNo+humQLG89XpPgdt16Ia56ORD7s+H8Pmyx44uczDQ0yDzpg==} + cpu: [x64] + os: [win32] + + '@sapphire/async-queue@1.5.2': + resolution: {integrity: sha512-7X7FFAA4DngXUl95+hYbUF19bp1LGiffjJtu7ygrZrbdCSsdDDBaSjB7Akw0ZbOu6k0xpXyljnJ6/RZUvLfRdg==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + + '@sapphire/shapeshift@3.9.7': + resolution: {integrity: sha512-4It2mxPSr4OGn4HSQWGmhFMsNFGfFVhWeRPCRwbH972Ek2pzfGRZtb0pJ4Ze6oIzcyh2jw7nUDa6qGlWofgd9g==} + engines: {node: '>=v16'} + + '@sapphire/snowflake@3.5.3': + resolution: {integrity: sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@types/bluebird@3.5.42': + resolution: {integrity: sha512-Jhy+MWRlro6UjVi578V/4ZGNfeCOcNCp0YaFNIUGFKlImowqwb1O/22wDVk3FDGMLqxdpOV3qQHD5fPEH4hK6A==} + + '@types/body-parser@1.19.5': + resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} + + '@types/color-thief-node@1.0.4': + resolution: {integrity: sha512-9mHoSyLAojvDQsZWxu3FHhiwUsQC7Lfuxrii6rnYc11uJ7GH2ODaM82gyDCXnR/5eXqlOymauUXU5eCEYAHS4A==} + + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + + '@types/cors@2.8.17': + resolution: {integrity: sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==} + + '@types/estree@1.0.5': + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + + '@types/express-serve-static-core@4.19.5': + resolution: {integrity: sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==} + + '@types/express@4.17.21': + resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} + + '@types/http-errors@2.0.4': + resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} + + '@types/i18n@0.13.12': + resolution: {integrity: sha512-iAd2QjKh+0ToBXocmCS3m38GskiaGzmSV1MTQz2GaOraqSqBiLf46J7u3EGINl+st+Uk4lO3OL7QyIjTJlrWIg==} + + '@types/mime@1.3.5': + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + + '@types/node@20.14.8': + resolution: {integrity: sha512-DO+2/jZinXfROG7j7WKFn/3C6nFwxy2lLpgLjEXJz+0XKphZlTLJ14mo8Vfg8X5BWN6XjyESXq+LcYdT7tR3bA==} + + '@types/os-utils@0.0.4': + resolution: {integrity: sha512-TdQ/6GHzq8YMsDOXHfit8sDD1VjLnqC61sI7ICocwREw/68V5C/bjex+/Jya3XRD3FgGyj6fhTqhbVrXeh8UJg==} + + '@types/ping@0.4.4': + resolution: {integrity: sha512-ifvo6w2f5eJYlXm+HiVx67iJe8WZp87sfa683nlqED5Vnt9Z93onkokNoWqOG21EaE8fMxyKPobE+mkPEyxsdw==} + + '@types/qs@6.9.15': + resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==} + + '@types/range-parser@1.2.7': + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + + '@types/send@0.17.4': + resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} + + '@types/serve-static@1.15.7': + resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} + + '@types/strip-bom@3.0.0': + resolution: {integrity: sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ==} + + '@types/strip-json-comments@0.0.30': + resolution: {integrity: sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==} + + '@types/tough-cookie@4.0.5': + resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + + '@types/triple-beam@1.3.5': + resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==} + + '@types/validator@13.12.0': + resolution: {integrity: sha512-nH45Lk7oPIJ1RVOF6JgFI6Dy0QpHEzq4QecZhvguxYPDwT8c93prCMqAtiIttm39voZ+DDR+qkNnMpJmMBRqag==} + + '@types/ws@8.5.10': + resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} + + '@vladfrangu/async_event_emitter@2.3.0': + resolution: {integrity: sha512-pmkbRGAqTM3N7R4KCObOAqqoZzeURR6oC11amaXmY4ZLShu4MdLymm1/F0fZssYKAsSE79TibRbdXwfvYMIt0Q==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + + abbrev@1.1.1: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + + acorn-walk@8.3.3: + resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==} + engines: {node: '>=0.4.0'} + + acorn@8.12.0: + resolution: {integrity: sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + aproba@2.0.0: + resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} + + are-we-there-yet@2.0.0: + resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} + engines: {node: '>=10'} + deprecated: This package is no longer supported. + + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + async@3.2.5: + resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + axios-cookiejar-support@1.0.1: + resolution: {integrity: sha512-IZJxnAJ99XxiLqNeMOqrPbfR7fRyIfaoSLdPUf4AMQEGkH8URs0ghJK/xtqBsD+KsSr3pKl4DEQjCn834pHMig==} + engines: {node: '>= 10.0.0'} + peerDependencies: + '@types/tough-cookie': '>=2.3.3' + axios: '>=0.16.2' + tough-cookie: '>=2.3.3' + + axios@0.26.1: + resolution: {integrity: sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + + body-parser@1.20.2: + resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + boolean@3.2.0: + resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + bufferutil@4.0.8: + resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==} + engines: {node: '>=6.14.2'} + + bundle-require@5.0.0: + resolution: {integrity: sha512-GuziW3fSSmopcx4KRymQEJVbZUfqlCqcq7dvs6TYwKRZiegK/2buMxQTPs6MGlNv50wms1699qYO54R8XfRX4w==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.18' + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + + canvas@2.11.2: + resolution: {integrity: sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==} + engines: {node: '>=6'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + + cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color-support@1.1.3: + resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + hasBin: true + + color-thief-node@1.0.4: + resolution: {integrity: sha512-ZcGpyUnmjJISUjDwRv+DM8ySpT/Jp9BOiEPQfAXWsDF6WT3XAPIPzIRLXdKh4ZbTkhZCvYZgTo8A7hHRvxcUnQ==} + + color@3.2.1: + resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==} + + colorspace@1.1.4: + resolution: {integrity: sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + component-emitter@1.3.1: + resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + consola@3.2.3: + resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} + engines: {node: ^14.18.0 || >=16.10.0} + + console-control-strings@1.1.0: + resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + + cookie@0.6.0: + resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + engines: {node: '>= 0.6'} + + cookiejar@2.1.4: + resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} + + copyfiles@2.4.1: + resolution: {integrity: sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==} + hasBin: true + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cors@2.8.5: + resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + engines: {node: '>= 0.10'} + + country-code-emoji@2.3.0: + resolution: {integrity: sha512-MqmIWr3aucoU/3XZU44e0sz6izAlErqaUYp9/NFzdnzb9TrwwornyW3ws2da5TSnpTUr2qP2840oJW9oNKXCoQ==} + + country-code-lookup@0.1.3: + resolution: {integrity: sha512-gLu+AQKHUnkSQNTxShKgi/4tYd0vEEait3JMrLNZgYlmIZ9DJLkHUjzXE9qcs7dy3xY/kUx2/nOxZ0Z3D9JE+A==} + + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.5: + resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decompress-response@4.2.1: + resolution: {integrity: sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==} + engines: {node: '>=8'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + delegates@1.0.0: + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + detect-libc@2.0.3: + resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} + engines: {node: '>=8'} + + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + discord-api-types@0.37.83: + resolution: {integrity: sha512-urGGYeWtWNYMKnYlZnOnDHm8fVRffQs3U0SpE8RHeiuLKb/u92APS8HoQnPTFbnXmY1vVnXjXO4dOxcAn3J+DA==} + + discord-api-types@0.37.90: + resolution: {integrity: sha512-lpOJSGrqHuXoM4FV/2HtjoaJpCClGFHpRNIdZEW8zPINlsCHNSfIwA2EQ8dxeE6k1QhhTuM9ZlOGVYXoU7FLgA==} + + discord.js@14.15.3: + resolution: {integrity: sha512-/UJDQO10VuU6wQPglA4kz2bw2ngeeSbogiIPx/TsnctfzV/tNf+q+i1HlgtX1OGpeOBpJH9erZQNO5oRM2uAtQ==} + engines: {node: '>=16.11.0'} + + dotenv@16.4.5: + resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} + engines: {node: '>=12'} + + dynamic-dedupe@0.3.0: + resolution: {integrity: sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ==} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + enabled@2.0.0: + resolution: {integrity: sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==} + + encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + esbuild@0.23.1: + resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + + express@4.19.2: + resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} + engines: {node: '>= 0.10.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-printf@1.6.9: + resolution: {integrity: sha512-FChq8hbz65WMj4rstcQsFB0O7Cy++nmbNfLYnD9cYv2cRn8EG6k/MGn9kO/tjO66t09DLDugj3yL+V2o6Qftrg==} + engines: {node: '>=10.0'} + + fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + + fecha@4.2.3: + resolution: {integrity: sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + finalhandler@1.2.0: + resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} + engines: {node: '>= 0.8'} + + fn.name@1.1.0: + resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==} + + follow-redirects@1.15.6: + resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + foreground-child@3.3.0: + resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} + engines: {node: '>=14'} + + form-data@3.0.1: + resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} + engines: {node: '>= 6'} + + formidable@1.2.6: + resolution: {integrity: sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==} + deprecated: 'Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau' + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + gauge@3.0.2: + resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} + engines: {node: '>=10'} + deprecated: This package is no longer supported. + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + has-unicode@2.0.1: + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + + i18n@0.15.1: + resolution: {integrity: sha512-yue187t8MqUPMHdKjiZGrX+L+xcUsDClGO0Cz4loaKUOK9WrGw5pgan4bv130utOwX7fHE9w2iUeHFalVQWkXA==} + engines: {node: '>=10'} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-core-module@2.14.0: + resolution: {integrity: sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-redirect@1.0.0: + resolution: {integrity: sha512-cr/SlUEe5zOGmzvj9bUyC4LVvkNVAXu4GytXLNMr1pny+a65MpQ9IJzFHD5vi7FyJgb4qt27+eS3TuQnqB+RQw==} + engines: {node: '>=0.10.0'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + isarray@0.0.1: + resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + + kuler@2.0.0: + resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} + + libsodium-wrappers@0.7.13: + resolution: {integrity: sha512-kasvDsEi/r1fMzKouIDv7B8I6vNmknXwGiYodErGuESoFTohGSKZplFtVxZqHaoQ217AynyIFgnOVRitpHs0Qw==} + + libsodium@0.7.13: + resolution: {integrity: sha512-mK8ju0fnrKXXfleL53vtp9xiPq5hKM0zbDQtcxQIsSmxNgSxqCj6R7Hl9PkrNe2j29T4yoDaF7DJLK9/i5iWUw==} + + lilconfig@3.1.2: + resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lodash.snakecase@4.1.1: + resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} + + lodash.sortby@4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + logform@2.6.0: + resolution: {integrity: sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==} + engines: {node: '>= 12.0.0'} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + magic-bytes.js@1.10.0: + resolution: {integrity: sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ==} + + make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + make-plural@7.4.0: + resolution: {integrity: sha512-4/gC9KVNTV6pvYg2gFeQYTW3mWaoJt7WZE5vrp1KnQDgW92JtYZnzmZT81oj/dUTqAIu0ufI2x3dkgu3bB1tYg==} + + math-interval-parser@2.0.1: + resolution: {integrity: sha512-VmlAmb0UJwlvMyx8iPhXUDnVW1F9IrGEd9CIOmv+XL8AErCUUuozoDMrgImvnYt2A+53qVX/tPW6YJurMKYsvA==} + engines: {node: '>=0.10.0'} + + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + merge-descriptors@1.0.1: + resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + micromatch@4.0.7: + resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + mime@2.6.0: + resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} + engines: {node: '>=4.0.0'} + hasBin: true + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + mimic-response@2.1.0: + resolution: {integrity: sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==} + engines: {node: '>=8'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + + minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + moo@0.5.2: + resolution: {integrity: sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==} + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mustache@4.2.0: + resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} + hasBin: true + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nan@2.20.0: + resolution: {integrity: sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==} + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + node-addon-api@5.1.0: + resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==} + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-gyp-build@4.8.1: + resolution: {integrity: sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==} + hasBin: true + + node-osu@2.2.1: + resolution: {integrity: sha512-SM9kj+7q7j/Y5nkMSRchQi9g2RxgDQ8JjC/zds7VyzUWQPokGQW3KuiskPLHwITn3RW3V98k7Y3RB3zkLIX9jA==} + + noms@0.0.0: + resolution: {integrity: sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==} + + nopt@5.0.0: + resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} + engines: {node: '>=6'} + hasBin: true + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + npmlog@5.0.1: + resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} + deprecated: This package is no longer supported. + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.2: + resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} + engines: {node: '>= 0.4'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + one-time@1.0.0: + resolution: {integrity: sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + os-utils@0.0.14: + resolution: {integrity: sha512-ajB8csaHLBvJOYsHJkp8YdO2FvlBbf/ZxaYQwXXRDyQ84UoE+uTuLXxqd0shekXMX6Qr/pt/DDyLMRAMsgfWzg==} + + package-json-from-dist@1.0.0: + resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-to-regexp@0.1.7: + resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + pify@5.0.0: + resolution: {integrity: sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==} + engines: {node: '>=10'} + + ping@0.4.4: + resolution: {integrity: sha512-56ZMC0j7SCsMMLdOoUg12VZCfj/+ZO+yfOSjaNCRrmZZr6GLbN2X/Ui56T15dI8NhiHckaw5X2pvyfAomanwqQ==} + engines: {node: '>=4.0.0'} + + pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + + play-audio@0.5.2: + resolution: {integrity: sha512-ZAqHUKkQLix2Iga7pPbsf1LpUoBjcpwU93F1l3qBIfxYddQLhxS6GKmS0d3jV8kSVaUbr6NnOEcEMFvuX93SWQ==} + + play-dl@1.9.7: + resolution: {integrity: sha512-KpgerWxUCY4s9Mhze2qdqPhiqd8Ve6HufpH9mBH3FN+vux55qSh6WJKDabfie8IBHN7lnrAlYcT/UdGax58c2A==} + engines: {node: '>=16.0.0'} + + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + + prism-media@1.3.5: + resolution: {integrity: sha512-IQdl0Q01m4LrkN1EGIE9lphov5Hy7WWlH6ulf5QdGePLlPas9p2mhgddTEHrlaXYjjFToM1/rWuwF37VF4taaA==} + peerDependencies: + '@discordjs/opus': '>=0.8.0 <1.0.0' + ffmpeg-static: ^5.0.2 || ^4.2.7 || ^3.0.0 || ^2.4.0 + node-opus: ^0.3.3 + opusscript: ^0.0.8 + peerDependenciesMeta: + '@discordjs/opus': + optional: true + ffmpeg-static: + optional: true + node-opus: + optional: true + opusscript: + optional: true + + prisma@5.15.1: + resolution: {integrity: sha512-pYsUVpTlYvZ6mWvZKDv9rKdUa7tlfSUJY1CVtgb8Had1pHbIm9fr1MBASccr5XnSuCUrjnvKhWNwgSYy6aCajA==} + engines: {node: '>=16.13'} + hasBin: true + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + psl@1.9.0: + resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + qs@6.11.0: + resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} + engines: {node: '>=0.6'} + + qs@6.12.1: + resolution: {integrity: sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==} + engines: {node: '>=0.6'} + + querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.2: + resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + engines: {node: '>= 0.8'} + + readable-stream@1.0.34: + resolution: {integrity: sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rollup@4.20.0: + resolution: {integrity: sha512-6rbWBChcnSGzIlXeIdNIZTopKYad8ZG8ajhl78lGRLsI2rX8IkaotQhVas2Ma+GPxJav19wrSzvRvuiv0YKzWw==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-identifier@0.4.2: + resolution: {integrity: sha512-6pNbSMW6OhAi9j+N8V+U715yBQsaWJ7eyEUaOrawX+isg5ZxhUlV1NipNtgaKHmFGiABwt+ZF04Ii+3Xjkg+8w==} + + safe-stable-stringify@2.4.3: + resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==} + engines: {node: '>=10'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.6.2: + resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} + engines: {node: '>=10'} + hasBin: true + + send@0.18.0: + resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} + engines: {node: '>= 0.8.0'} + + serve-static@1.15.0: + resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} + engines: {node: '>= 0.8.0'} + + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + + simple-get@3.1.1: + resolution: {integrity: sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==} + + simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.8.0-beta.0: + resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} + engines: {node: '>= 8'} + + stack-trace@0.0.10: + resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} + + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string_decoder@0.10.31: + resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + + sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + superagent@5.3.1: + resolution: {integrity: sha512-wjJ/MoTid2/RuGCOFtlacyGNxN9QLMgcpYLDQlWFIhhdJ93kNscFonGvrpAHSCVjRVj++DGCglocF7Aej1KHvQ==} + engines: {node: '>= 7.0.0'} + deprecated: Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + tar@6.2.1: + resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} + engines: {node: '>=10'} + + text-hex@1.0.0: + resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==} + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + through2@2.0.5: + resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + tough-cookie@4.1.4: + resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} + engines: {node: '>=6'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + tr46@1.0.1: + resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} + + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + + triple-beam@1.4.1: + resolution: {integrity: sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==} + engines: {node: '>= 14.0.0'} + + ts-custom-error@3.3.1: + resolution: {integrity: sha512-5OX1tzOjxWEgsr/YEUWSuPrQ00deKLh6D7OTWcvNHm12/7QPyRh8SYpyWvA4IZv8H/+GQWQEh/kwo95Q9OVW1A==} + engines: {node: '>=14.0.0'} + + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + ts-mixer@6.0.4: + resolution: {integrity: sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==} + + ts-node-dev@2.0.0: + resolution: {integrity: sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w==} + engines: {node: '>=0.8.0'} + hasBin: true + peerDependencies: + node-notifier: '*' + typescript: '*' + peerDependenciesMeta: + node-notifier: + optional: true + + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + + tsconfig@7.0.0: + resolution: {integrity: sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==} + + tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + + tslib@2.6.3: + resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} + + tsup@8.2.4: + resolution: {integrity: sha512-akpCPePnBnC/CXgRrcy72ZSntgIEUa1jN0oJbbvpALWKNOz1B7aM+UVDWGRGIO/T/PZugAESWDJUAb5FD48o8Q==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + '@microsoft/api-extractor': ^7.36.0 + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: '>=4.5.0' + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + typescript@5.5.2: + resolution: {integrity: sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + undici@6.13.0: + resolution: {integrity: sha512-Q2rtqmZWrbP8nePMq7mOJIN98M0fYvSgV89vwl/BQRT4mDOeY2GXZngfGpcBBhtky3woM7G24wZV3Q304Bv6cw==} + engines: {node: '>=18.0'} + + universalify@0.2.0: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} + engines: {node: '>= 4.0.0'} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + untildify@4.0.0: + resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} + engines: {node: '>=8'} + + url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + + utf-8-validate@6.0.4: + resolution: {integrity: sha512-xu9GQDeFp+eZ6LnCywXN/zBancWvOpUMzgjLPSjy4BRHSmTelvn2E0DG0o1sTiw5hkCKBHo8rwSKncfRfv2EEQ==} + engines: {node: '>=6.14.2'} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + + validator@13.12.0: + resolution: {integrity: sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==} + engines: {node: '>= 0.10'} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + vrchat@1.17.6: + resolution: {integrity: sha512-DlcLoFy/cMgWrxHHMdr0HC9b4vCi1lqAtkVodaovR7/Ithhj4ZUQFJsvKhiPn4vP+EGnH+UsPPFGLtooB1JuJw==} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + webidl-conversions@4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + whatwg-url@7.1.0: + resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + wide-align@1.1.5: + resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + + winston-transport@4.7.0: + resolution: {integrity: sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==} + engines: {node: '>= 12.0.0'} + + winston@3.13.0: + resolution: {integrity: sha512-rwidmA1w3SE4j0E5MuIufFhyJPBDG7Nu71RkZor1p2+qHvJSZ9GYDA81AyleQcZbh/+V6HjeBdfnTZJm9rSeQQ==} + engines: {node: '>= 12.0.0'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@8.17.1: + resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yargs-parser@20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + + yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + + yt-dlp-wrap@2.3.12: + resolution: {integrity: sha512-P8fJ+6M1YjukyJENCTviNLiZ8mokxprR54ho3DsSKPWDcac489OjRiStGEARJr6un6ETS6goTn4CWl/b/rM3aA==} + + zlib-sync@0.1.9: + resolution: {integrity: sha512-DinB43xCjVwIBDpaIvQqHbmDsnYnSt6HJ/yiB2MZQGTqgPcwBSZqLkimXwK8BvdjQ/MaZysb5uEenImncqvCqQ==} + +snapshots: + + '@colors/colors@1.6.0': {} + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@dabh/diagnostics@2.0.3': + dependencies: + colorspace: 1.1.4 + enabled: 2.0.0 + kuler: 2.0.0 + + '@discordjs/builders@1.8.2': + dependencies: + '@discordjs/formatters': 0.4.0 + '@discordjs/util': 1.1.0 + '@sapphire/shapeshift': 3.9.7 + discord-api-types: 0.37.83 + fast-deep-equal: 3.1.3 + ts-mixer: 6.0.4 + tslib: 2.6.3 + + '@discordjs/collection@1.5.3': {} + + '@discordjs/collection@2.1.0': {} + + '@discordjs/formatters@0.4.0': + dependencies: + discord-api-types: 0.37.83 + + '@discordjs/node-pre-gyp@0.4.5': + dependencies: + detect-libc: 2.0.3 + https-proxy-agent: 5.0.1 + make-dir: 3.1.0 + node-fetch: 2.7.0 + nopt: 5.0.0 + npmlog: 5.0.1 + rimraf: 3.0.2 + semver: 7.6.2 + tar: 6.2.1 + transitivePeerDependencies: + - encoding + - supports-color + + '@discordjs/opus@0.9.0': + dependencies: + '@discordjs/node-pre-gyp': 0.4.5 + node-addon-api: 5.1.0 + transitivePeerDependencies: + - encoding + - supports-color + + '@discordjs/rest@2.3.0': + dependencies: + '@discordjs/collection': 2.1.0 + '@discordjs/util': 1.1.0 + '@sapphire/async-queue': 1.5.2 + '@sapphire/snowflake': 3.5.3 + '@vladfrangu/async_event_emitter': 2.3.0 + discord-api-types: 0.37.83 + magic-bytes.js: 1.10.0 + tslib: 2.6.3 + undici: 6.13.0 + + '@discordjs/util@1.1.0': {} + + '@discordjs/voice@0.17.0(@discordjs/opus@0.9.0)(bufferutil@4.0.8)(utf-8-validate@6.0.4)': + dependencies: + '@types/ws': 8.5.10 + discord-api-types: 0.37.83 + prism-media: 1.3.5(@discordjs/opus@0.9.0) + tslib: 2.6.3 + ws: 8.17.1(bufferutil@4.0.8)(utf-8-validate@6.0.4) + transitivePeerDependencies: + - '@discordjs/opus' + - bufferutil + - ffmpeg-static + - node-opus + - opusscript + - utf-8-validate + + '@discordjs/ws@1.1.1(bufferutil@4.0.8)(utf-8-validate@6.0.4)': + dependencies: + '@discordjs/collection': 2.1.0 + '@discordjs/rest': 2.3.0 + '@discordjs/util': 1.1.0 + '@sapphire/async-queue': 1.5.2 + '@types/ws': 8.5.10 + '@vladfrangu/async_event_emitter': 2.3.0 + discord-api-types: 0.37.83 + tslib: 2.6.3 + ws: 8.17.1(bufferutil@4.0.8)(utf-8-validate@6.0.4) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@esbuild/aix-ppc64@0.23.1': + optional: true + + '@esbuild/android-arm64@0.23.1': + optional: true + + '@esbuild/android-arm@0.23.1': + optional: true + + '@esbuild/android-x64@0.23.1': + optional: true + + '@esbuild/darwin-arm64@0.23.1': + optional: true + + '@esbuild/darwin-x64@0.23.1': + optional: true + + '@esbuild/freebsd-arm64@0.23.1': + optional: true + + '@esbuild/freebsd-x64@0.23.1': + optional: true + + '@esbuild/linux-arm64@0.23.1': + optional: true + + '@esbuild/linux-arm@0.23.1': + optional: true + + '@esbuild/linux-ia32@0.23.1': + optional: true + + '@esbuild/linux-loong64@0.23.1': + optional: true + + '@esbuild/linux-mips64el@0.23.1': + optional: true + + '@esbuild/linux-ppc64@0.23.1': + optional: true + + '@esbuild/linux-riscv64@0.23.1': + optional: true + + '@esbuild/linux-s390x@0.23.1': + optional: true + + '@esbuild/linux-x64@0.23.1': + optional: true + + '@esbuild/netbsd-x64@0.23.1': + optional: true + + '@esbuild/openbsd-arm64@0.23.1': + optional: true + + '@esbuild/openbsd-x64@0.23.1': + optional: true + + '@esbuild/sunos-x64@0.23.1': + optional: true + + '@esbuild/win32-arm64@0.23.1': + optional: true + + '@esbuild/win32-ia32@0.23.1': + optional: true + + '@esbuild/win32-x64@0.23.1': + optional: true + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.4.15': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + + '@mapbox/node-pre-gyp@1.0.11': + dependencies: + detect-libc: 2.0.3 + https-proxy-agent: 5.0.1 + make-dir: 3.1.0 + node-fetch: 2.7.0 + nopt: 5.0.0 + npmlog: 5.0.1 + rimraf: 3.0.2 + semver: 7.6.2 + tar: 6.2.1 + transitivePeerDependencies: + - encoding + - supports-color + + '@messageformat/core@3.3.0': + dependencies: + '@messageformat/date-skeleton': 1.0.1 + '@messageformat/number-skeleton': 1.2.0 + '@messageformat/parser': 5.1.0 + '@messageformat/runtime': 3.0.1 + make-plural: 7.4.0 + safe-identifier: 0.4.2 + + '@messageformat/date-skeleton@1.0.1': {} + + '@messageformat/number-skeleton@1.2.0': {} + + '@messageformat/parser@5.1.0': + dependencies: + moo: 0.5.2 + + '@messageformat/runtime@3.0.1': + dependencies: + make-plural: 7.4.0 + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@prisma/client@5.15.1(prisma@5.15.1)': + optionalDependencies: + prisma: 5.15.1 + + '@prisma/debug@5.15.1': {} + + '@prisma/engines-version@5.15.1-1.5675a3182f972f1a8f31d16eee6abf4fd54910e3': {} + + '@prisma/engines@5.15.1': + dependencies: + '@prisma/debug': 5.15.1 + '@prisma/engines-version': 5.15.1-1.5675a3182f972f1a8f31d16eee6abf4fd54910e3 + '@prisma/fetch-engine': 5.15.1 + '@prisma/get-platform': 5.15.1 + + '@prisma/fetch-engine@5.15.1': + dependencies: + '@prisma/debug': 5.15.1 + '@prisma/engines-version': 5.15.1-1.5675a3182f972f1a8f31d16eee6abf4fd54910e3 + '@prisma/get-platform': 5.15.1 + + '@prisma/get-platform@5.15.1': + dependencies: + '@prisma/debug': 5.15.1 + + '@rollup/rollup-android-arm-eabi@4.20.0': + optional: true + + '@rollup/rollup-android-arm64@4.20.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.20.0': + optional: true + + '@rollup/rollup-darwin-x64@4.20.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.20.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.20.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.20.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.20.0': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.20.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.20.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.20.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.20.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.20.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.20.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.20.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.20.0': + optional: true + + '@sapphire/async-queue@1.5.2': {} + + '@sapphire/shapeshift@3.9.7': + dependencies: + fast-deep-equal: 3.1.3 + lodash: 4.17.21 + + '@sapphire/snowflake@3.5.3': {} + + '@tsconfig/node10@1.0.11': {} + + '@tsconfig/node12@1.0.11': {} + + '@tsconfig/node14@1.0.3': {} + + '@tsconfig/node16@1.0.4': {} + + '@types/bluebird@3.5.42': {} + + '@types/body-parser@1.19.5': + dependencies: + '@types/connect': 3.4.38 + '@types/node': 20.14.8 + + '@types/color-thief-node@1.0.4': {} + + '@types/connect@3.4.38': + dependencies: + '@types/node': 20.14.8 + + '@types/cors@2.8.17': + dependencies: + '@types/node': 20.14.8 + + '@types/estree@1.0.5': {} + + '@types/express-serve-static-core@4.19.5': + dependencies: + '@types/node': 20.14.8 + '@types/qs': 6.9.15 + '@types/range-parser': 1.2.7 + '@types/send': 0.17.4 + + '@types/express@4.17.21': + dependencies: + '@types/body-parser': 1.19.5 + '@types/express-serve-static-core': 4.19.5 + '@types/qs': 6.9.15 + '@types/serve-static': 1.15.7 + + '@types/http-errors@2.0.4': {} + + '@types/i18n@0.13.12': {} + + '@types/mime@1.3.5': {} + + '@types/node@20.14.8': + dependencies: + undici-types: 5.26.5 + + '@types/os-utils@0.0.4': {} + + '@types/ping@0.4.4': {} + + '@types/qs@6.9.15': {} + + '@types/range-parser@1.2.7': {} + + '@types/send@0.17.4': + dependencies: + '@types/mime': 1.3.5 + '@types/node': 20.14.8 + + '@types/serve-static@1.15.7': + dependencies: + '@types/http-errors': 2.0.4 + '@types/node': 20.14.8 + '@types/send': 0.17.4 + + '@types/strip-bom@3.0.0': {} + + '@types/strip-json-comments@0.0.30': {} + + '@types/tough-cookie@4.0.5': {} + + '@types/triple-beam@1.3.5': {} + + '@types/validator@13.12.0': {} + + '@types/ws@8.5.10': + dependencies: + '@types/node': 20.14.8 + + '@vladfrangu/async_event_emitter@2.3.0': {} + + abbrev@1.1.1: {} + + accepts@1.3.8: + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + acorn-walk@8.3.3: + dependencies: + acorn: 8.12.0 + + acorn@8.12.0: {} + + agent-base@6.0.2: + dependencies: + debug: 4.3.5 + transitivePeerDependencies: + - supports-color + + ansi-regex@5.0.1: {} + + ansi-regex@6.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.1: {} + + any-promise@1.3.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + aproba@2.0.0: {} + + are-we-there-yet@2.0.0: + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.2 + + arg@4.1.3: {} + + array-flatten@1.1.1: {} + + array-union@2.1.0: {} + + async@3.2.5: {} + + asynckit@0.4.0: {} + + axios-cookiejar-support@1.0.1(@types/tough-cookie@4.0.5)(axios@0.26.1)(tough-cookie@4.1.4): + dependencies: + '@types/tough-cookie': 4.0.5 + axios: 0.26.1 + is-redirect: 1.0.0 + pify: 5.0.0 + tough-cookie: 4.1.4 + + axios@0.26.1: + dependencies: + follow-redirects: 1.15.6 + transitivePeerDependencies: + - debug + + balanced-match@1.0.2: {} + + binary-extensions@2.3.0: {} + + bluebird@3.7.2: {} + + body-parser@1.20.2: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.11.0 + raw-body: 2.5.2 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + boolean@3.2.0: {} + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + buffer-from@1.1.2: {} + + bufferutil@4.0.8: + dependencies: + node-gyp-build: 4.8.1 + + bundle-require@5.0.0(esbuild@0.23.1): + dependencies: + esbuild: 0.23.1 + load-tsconfig: 0.2.5 + + bytes@3.1.2: {} + + cac@6.7.14: {} + + call-bind@1.0.7: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + + canvas@2.11.2: + dependencies: + '@mapbox/node-pre-gyp': 1.0.11 + nan: 2.20.0 + simple-get: 3.1.1 + transitivePeerDependencies: + - encoding + - supports-color + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chownr@2.0.0: {} + + cliui@7.0.4: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + + color-support@1.1.3: {} + + color-thief-node@1.0.4: + dependencies: + canvas: 2.11.2 + transitivePeerDependencies: + - encoding + - supports-color + + color@3.2.1: + dependencies: + color-convert: 1.9.3 + color-string: 1.9.1 + + colorspace@1.1.4: + dependencies: + color: 3.2.1 + text-hex: 1.0.0 + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + commander@4.1.1: {} + + component-emitter@1.3.1: {} + + concat-map@0.0.1: {} + + consola@3.2.3: {} + + console-control-strings@1.1.0: {} + + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + + cookie-signature@1.0.6: {} + + cookie@0.6.0: {} + + cookiejar@2.1.4: {} + + copyfiles@2.4.1: + dependencies: + glob: 7.2.3 + minimatch: 3.1.2 + mkdirp: 1.0.4 + noms: 0.0.0 + through2: 2.0.5 + untildify: 4.0.0 + yargs: 16.2.0 + + core-util-is@1.0.3: {} + + cors@2.8.5: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + country-code-emoji@2.3.0: {} + + country-code-lookup@0.1.3: {} + + create-require@1.1.1: {} + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@4.3.5: + dependencies: + ms: 2.1.2 + + decompress-response@4.2.1: + dependencies: + mimic-response: 2.1.0 + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + delayed-stream@1.0.0: {} + + delegates@1.0.0: {} + + depd@2.0.0: {} + + destroy@1.2.0: {} + + detect-libc@2.0.3: {} + + diff@4.0.2: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + discord-api-types@0.37.83: {} + + discord-api-types@0.37.90: {} + + discord.js@14.15.3(bufferutil@4.0.8)(utf-8-validate@6.0.4): + dependencies: + '@discordjs/builders': 1.8.2 + '@discordjs/collection': 1.5.3 + '@discordjs/formatters': 0.4.0 + '@discordjs/rest': 2.3.0 + '@discordjs/util': 1.1.0 + '@discordjs/ws': 1.1.1(bufferutil@4.0.8)(utf-8-validate@6.0.4) + '@sapphire/snowflake': 3.5.3 + discord-api-types: 0.37.83 + fast-deep-equal: 3.1.3 + lodash.snakecase: 4.1.1 + tslib: 2.6.2 + undici: 6.13.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + dotenv@16.4.5: {} + + dynamic-dedupe@0.3.0: + dependencies: + xtend: 4.0.2 + + eastasianwidth@0.2.0: {} + + ee-first@1.1.1: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + enabled@2.0.0: {} + + encodeurl@1.0.2: {} + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + + esbuild@0.23.1: + optionalDependencies: + '@esbuild/aix-ppc64': 0.23.1 + '@esbuild/android-arm': 0.23.1 + '@esbuild/android-arm64': 0.23.1 + '@esbuild/android-x64': 0.23.1 + '@esbuild/darwin-arm64': 0.23.1 + '@esbuild/darwin-x64': 0.23.1 + '@esbuild/freebsd-arm64': 0.23.1 + '@esbuild/freebsd-x64': 0.23.1 + '@esbuild/linux-arm': 0.23.1 + '@esbuild/linux-arm64': 0.23.1 + '@esbuild/linux-ia32': 0.23.1 + '@esbuild/linux-loong64': 0.23.1 + '@esbuild/linux-mips64el': 0.23.1 + '@esbuild/linux-ppc64': 0.23.1 + '@esbuild/linux-riscv64': 0.23.1 + '@esbuild/linux-s390x': 0.23.1 + '@esbuild/linux-x64': 0.23.1 + '@esbuild/netbsd-x64': 0.23.1 + '@esbuild/openbsd-arm64': 0.23.1 + '@esbuild/openbsd-x64': 0.23.1 + '@esbuild/sunos-x64': 0.23.1 + '@esbuild/win32-arm64': 0.23.1 + '@esbuild/win32-ia32': 0.23.1 + '@esbuild/win32-x64': 0.23.1 + + escalade@3.1.2: {} + + escape-html@1.0.3: {} + + etag@1.8.1: {} + + execa@5.1.1: + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + express@4.19.2: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.2 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.6.0 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.2.0 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.1 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.7 + proxy-addr: 2.0.7 + qs: 6.11.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.18.0 + serve-static: 1.15.0 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.7 + + fast-printf@1.6.9: + dependencies: + boolean: 3.2.0 + + fast-safe-stringify@2.1.1: {} + + fastq@1.17.1: + dependencies: + reusify: 1.0.4 + + fecha@4.2.3: {} + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + finalhandler@1.2.0: + dependencies: + debug: 2.6.9 + encodeurl: 1.0.2 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + fn.name@1.1.0: {} + + follow-redirects@1.15.6: {} + + foreground-child@3.3.0: + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + + form-data@3.0.1: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + formidable@1.2.6: {} + + forwarded@0.2.0: {} + + fresh@0.5.2: {} + + fs-minipass@2.1.0: + dependencies: + minipass: 3.3.6 + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + gauge@3.0.2: + dependencies: + aproba: 2.0.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + object-assign: 4.1.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + + get-caller-file@2.0.5: {} + + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + + get-stream@6.0.1: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob@10.4.5: + dependencies: + foreground-child: 3.3.0 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.0 + path-scurry: 1.11.1 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.0.3: {} + + has-symbols@1.0.3: {} + + has-unicode@2.0.1: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + http-errors@2.0.0: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.3.5 + transitivePeerDependencies: + - supports-color + + human-signals@2.1.0: {} + + i18n@0.15.1: + dependencies: + '@messageformat/core': 3.3.0 + debug: 4.3.5 + fast-printf: 1.6.9 + make-plural: 7.4.0 + math-interval-parser: 2.0.1 + mustache: 4.2.0 + transitivePeerDependencies: + - supports-color + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + ignore@5.3.2: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + ipaddr.js@1.9.1: {} + + is-arrayish@0.3.2: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-core-module@2.14.0: + dependencies: + hasown: 2.0.2 + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + is-redirect@1.0.0: {} + + is-stream@2.0.1: {} + + isarray@0.0.1: {} + + isarray@1.0.0: {} + + isexe@2.0.0: {} + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + joycon@3.1.1: {} + + kuler@2.0.0: {} + + libsodium-wrappers@0.7.13: + dependencies: + libsodium: 0.7.13 + + libsodium@0.7.13: {} + + lilconfig@3.1.2: {} + + lines-and-columns@1.2.4: {} + + load-tsconfig@0.2.5: {} + + lodash.snakecase@4.1.1: {} + + lodash.sortby@4.7.0: {} + + lodash@4.17.21: {} + + logform@2.6.0: + dependencies: + '@colors/colors': 1.6.0 + '@types/triple-beam': 1.3.5 + fecha: 4.2.3 + ms: 2.1.3 + safe-stable-stringify: 2.4.3 + triple-beam: 1.4.1 + + lru-cache@10.4.3: {} + + magic-bytes.js@1.10.0: {} + + make-dir@3.1.0: + dependencies: + semver: 6.3.1 + + make-error@1.3.6: {} + + make-plural@7.4.0: {} + + math-interval-parser@2.0.1: {} + + media-typer@0.3.0: {} + + merge-descriptors@1.0.1: {} + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + methods@1.1.2: {} + + micromatch@4.0.7: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime@1.6.0: {} + + mime@2.6.0: {} + + mimic-fn@2.1.0: {} + + mimic-response@2.1.0: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + minipass@3.3.6: + dependencies: + yallist: 4.0.0 + + minipass@5.0.0: {} + + minipass@7.1.2: {} + + minizlib@2.1.2: + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + + mkdirp@1.0.4: {} + + moo@0.5.2: {} + + ms@2.0.0: {} + + ms@2.1.2: {} + + ms@2.1.3: {} + + mustache@4.2.0: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nan@2.20.0: {} + + negotiator@0.6.3: {} + + node-addon-api@5.1.0: {} + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + node-gyp-build@4.8.1: {} + + node-osu@2.2.1: + dependencies: + superagent: 5.3.1 + transitivePeerDependencies: + - supports-color + + noms@0.0.0: + dependencies: + inherits: 2.0.4 + readable-stream: 1.0.34 + + nopt@5.0.0: + dependencies: + abbrev: 1.1.1 + + normalize-path@3.0.0: {} + + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + + npmlog@5.0.1: + dependencies: + are-we-there-yet: 2.0.0 + console-control-strings: 1.1.0 + gauge: 3.0.2 + set-blocking: 2.0.0 + + object-assign@4.1.1: {} + + object-inspect@1.13.2: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + one-time@1.0.0: + dependencies: + fn.name: 1.1.0 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + os-utils@0.0.14: {} + + package-json-from-dist@1.0.0: {} + + parseurl@1.3.3: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + path-to-regexp@0.1.7: {} + + path-type@4.0.0: {} + + picocolors@1.0.1: {} + + picomatch@2.3.1: {} + + pify@5.0.0: {} + + ping@0.4.4: {} + + pirates@4.0.6: {} + + play-audio@0.5.2: {} + + play-dl@1.9.7: + dependencies: + play-audio: 0.5.2 + + postcss-load-config@6.0.1: + dependencies: + lilconfig: 3.1.2 + + prism-media@1.3.5(@discordjs/opus@0.9.0): + optionalDependencies: + '@discordjs/opus': 0.9.0 + + prisma@5.15.1: + dependencies: + '@prisma/engines': 5.15.1 + + process-nextick-args@2.0.1: {} + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + psl@1.9.0: {} + + punycode@2.3.1: {} + + qs@6.11.0: + dependencies: + side-channel: 1.0.6 + + qs@6.12.1: + dependencies: + side-channel: 1.0.6 + + querystringify@2.2.0: {} + + queue-microtask@1.2.3: {} + + range-parser@1.2.1: {} + + raw-body@2.5.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + readable-stream@1.0.34: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 0.0.1 + string_decoder: 0.10.31 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + require-directory@2.1.1: {} + + requires-port@1.0.0: {} + + resolve-from@5.0.0: {} + + resolve@1.22.8: + dependencies: + is-core-module: 2.14.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.0.4: {} + + rimraf@2.7.1: + dependencies: + glob: 7.2.3 + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + rollup@4.20.0: + dependencies: + '@types/estree': 1.0.5 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.20.0 + '@rollup/rollup-android-arm64': 4.20.0 + '@rollup/rollup-darwin-arm64': 4.20.0 + '@rollup/rollup-darwin-x64': 4.20.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.20.0 + '@rollup/rollup-linux-arm-musleabihf': 4.20.0 + '@rollup/rollup-linux-arm64-gnu': 4.20.0 + '@rollup/rollup-linux-arm64-musl': 4.20.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.20.0 + '@rollup/rollup-linux-riscv64-gnu': 4.20.0 + '@rollup/rollup-linux-s390x-gnu': 4.20.0 + '@rollup/rollup-linux-x64-gnu': 4.20.0 + '@rollup/rollup-linux-x64-musl': 4.20.0 + '@rollup/rollup-win32-arm64-msvc': 4.20.0 + '@rollup/rollup-win32-ia32-msvc': 4.20.0 + '@rollup/rollup-win32-x64-msvc': 4.20.0 + fsevents: 2.3.3 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safe-identifier@0.4.2: {} + + safe-stable-stringify@2.4.3: {} + + safer-buffer@2.1.2: {} + + semver@6.3.1: {} + + semver@7.6.2: {} + + send@0.18.0: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + serve-static@1.15.0: + dependencies: + encodeurl: 1.0.2 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.18.0 + transitivePeerDependencies: + - supports-color + + set-blocking@2.0.0: {} + + set-function-length@1.2.2: + 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 + + setprototypeof@1.2.0: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + side-channel@1.0.6: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.2 + + signal-exit@3.0.7: {} + + signal-exit@4.1.0: {} + + simple-concat@1.0.1: {} + + simple-get@3.1.1: + dependencies: + decompress-response: 4.2.1 + once: 1.4.0 + simple-concat: 1.0.1 + + simple-swizzle@0.2.2: + dependencies: + is-arrayish: 0.3.2 + + slash@3.0.0: {} + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + source-map@0.8.0-beta.0: + dependencies: + whatwg-url: 7.1.0 + + stack-trace@0.0.10: {} + + statuses@2.0.1: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + string_decoder@0.10.31: {} + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.0.1 + + strip-bom@3.0.0: {} + + strip-final-newline@2.0.0: {} + + strip-json-comments@2.0.1: {} + + sucrase@3.35.0: + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + commander: 4.1.1 + glob: 10.4.5 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.6 + ts-interface-checker: 0.1.13 + + superagent@5.3.1: + dependencies: + component-emitter: 1.3.1 + cookiejar: 2.1.4 + debug: 4.3.5 + fast-safe-stringify: 2.1.1 + form-data: 3.0.1 + formidable: 1.2.6 + methods: 1.1.2 + mime: 2.6.0 + qs: 6.12.1 + readable-stream: 3.6.2 + semver: 7.6.2 + transitivePeerDependencies: + - supports-color + + supports-preserve-symlinks-flag@1.0.0: {} + + tar@6.2.1: + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + + text-hex@1.0.0: {} + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + through2@2.0.5: + dependencies: + readable-stream: 2.3.8 + xtend: 4.0.2 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toidentifier@1.0.1: {} + + tough-cookie@4.1.4: + dependencies: + psl: 1.9.0 + punycode: 2.3.1 + universalify: 0.2.0 + url-parse: 1.5.10 + + tr46@0.0.3: {} + + tr46@1.0.1: + dependencies: + punycode: 2.3.1 + + tree-kill@1.2.2: {} + + triple-beam@1.4.1: {} + + ts-custom-error@3.3.1: {} + + ts-interface-checker@0.1.13: {} + + ts-mixer@6.0.4: {} + + ts-node-dev@2.0.0(@types/node@20.14.8)(typescript@5.5.2): + dependencies: + chokidar: 3.6.0 + dynamic-dedupe: 0.3.0 + minimist: 1.2.8 + mkdirp: 1.0.4 + resolve: 1.22.8 + rimraf: 2.7.1 + source-map-support: 0.5.21 + tree-kill: 1.2.2 + ts-node: 10.9.2(@types/node@20.14.8)(typescript@5.5.2) + tsconfig: 7.0.0 + typescript: 5.5.2 + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + - '@types/node' + + ts-node@10.9.2(@types/node@20.14.8)(typescript@5.5.2): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.14.8 + acorn: 8.12.0 + acorn-walk: 8.3.3 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.5.2 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + + tsconfig@7.0.0: + dependencies: + '@types/strip-bom': 3.0.0 + '@types/strip-json-comments': 0.0.30 + strip-bom: 3.0.0 + strip-json-comments: 2.0.1 + + tslib@2.6.2: {} + + tslib@2.6.3: {} + + tsup@8.2.4(typescript@5.5.2): + dependencies: + bundle-require: 5.0.0(esbuild@0.23.1) + cac: 6.7.14 + chokidar: 3.6.0 + consola: 3.2.3 + debug: 4.3.5 + esbuild: 0.23.1 + execa: 5.1.1 + globby: 11.1.0 + joycon: 3.1.1 + picocolors: 1.0.1 + postcss-load-config: 6.0.1 + resolve-from: 5.0.0 + rollup: 4.20.0 + source-map: 0.8.0-beta.0 + sucrase: 3.35.0 + tree-kill: 1.2.2 + optionalDependencies: + typescript: 5.5.2 + transitivePeerDependencies: + - jiti + - supports-color + - tsx + - yaml + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + typescript@5.5.2: {} + + undici-types@5.26.5: {} + + undici@6.13.0: {} + + universalify@0.2.0: {} + + unpipe@1.0.0: {} + + untildify@4.0.0: {} + + url-parse@1.5.10: + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + + utf-8-validate@6.0.4: + dependencies: + node-gyp-build: 4.8.1 + + util-deprecate@1.0.2: {} + + utils-merge@1.0.1: {} + + v8-compile-cache-lib@3.0.1: {} + + validator@13.12.0: {} + + vary@1.1.2: {} + + vrchat@1.17.6: + dependencies: + '@types/tough-cookie': 4.0.5 + axios: 0.26.1 + axios-cookiejar-support: 1.0.1(@types/tough-cookie@4.0.5)(axios@0.26.1)(tough-cookie@4.1.4) + tough-cookie: 4.1.4 + transitivePeerDependencies: + - debug + + webidl-conversions@3.0.1: {} + + webidl-conversions@4.0.2: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + whatwg-url@7.1.0: + dependencies: + lodash.sortby: 4.7.0 + tr46: 1.0.1 + webidl-conversions: 4.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + wide-align@1.1.5: + dependencies: + string-width: 4.2.3 + + winston-transport@4.7.0: + dependencies: + logform: 2.6.0 + readable-stream: 3.6.2 + triple-beam: 1.4.1 + + winston@3.13.0: + dependencies: + '@colors/colors': 1.6.0 + '@dabh/diagnostics': 2.0.3 + async: 3.2.5 + is-stream: 2.0.1 + logform: 2.6.0 + one-time: 1.0.0 + readable-stream: 3.6.2 + safe-stable-stringify: 2.4.3 + stack-trace: 0.0.10 + triple-beam: 1.4.1 + winston-transport: 4.7.0 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + wrappy@1.0.2: {} + + ws@8.17.1(bufferutil@4.0.8)(utf-8-validate@6.0.4): + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 6.0.4 + + xtend@4.0.2: {} + + y18n@5.0.8: {} + + yallist@4.0.0: {} + + yargs-parser@20.2.9: {} + + yargs@16.2.0: + dependencies: + cliui: 7.0.4 + escalade: 3.1.2 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.9 + + yn@3.1.1: {} + + yt-dlp-wrap@2.3.12: {} + + zlib-sync@0.1.9: + dependencies: + nan: 2.20.0 diff --git a/src/discord/Developer/Debug.ts b/src/discord/Developer/Debug.ts index 9bc8e43..9529346 100644 --- a/src/discord/Developer/Debug.ts +++ b/src/discord/Developer/Debug.ts @@ -11,7 +11,7 @@ import { import DiscordModule, { HybridInteractionMessage } from '../../utils/DiscordModule'; import { makeInfoEmbed, makeErrorEmbed, sendHybridInteractionMessageResponse } from '../../utils/DiscordMessage'; -import DiscordMusicPlayer from '../../providers/DiscordMusicPlayerTempFix'; +import DiscordMusicPlayer from '../../providers/DiscordMusicPlayer'; import Users from '../../services/Users'; import Cache from '../../providers/Cache'; diff --git a/src/discord/Developer/VRChatLogin.ts b/src/discord/Developer/VRChatLogin.ts index 83799ed..b67ae0b 100644 --- a/src/discord/Developer/VRChatLogin.ts +++ b/src/discord/Developer/VRChatLogin.ts @@ -16,9 +16,7 @@ import { makeSuccessEmbed } from '../../utils/DiscordMessage'; -import DiscordMusicPlayer from '../../providers/DiscordMusicPlayerTempFix'; import Users from '../../services/Users'; -import Cache from '../../providers/Cache'; import VRChatAPI from '../../providers/VRChatAPI'; const EMBEDS = { diff --git a/src/discord/MusicPlayer/Join.ts b/src/discord/MusicPlayer/Join.ts index 1d12394..f327a8b 100644 --- a/src/discord/MusicPlayer/Join.ts +++ b/src/discord/MusicPlayer/Join.ts @@ -29,12 +29,13 @@ import DiscordMusicPlayer, { DiscordMusicPlayerInstance, DiscordMusicPlayerLoopMode, TrackUtils -} from '../../providers/DiscordMusicPlayerTempFix'; +} from '../../providers/DiscordMusicPlayer'; import DiscordModule, { HybridInteractionMessage } from '../../utils/DiscordModule'; import Locale from '../../services/Locale'; import { SpotifyTrack, YouTubeVideo } from 'play-dl'; import { checkBotPermissionsInChannel } from '../../utils/DiscordPermission'; +import { AudioInformation } from '../../../NekoMelody/src/providers/base'; const EMBEDS = { VOICECHANNEL_JOINED: (data: HybridInteractionMessage, locale: I18n) => { @@ -79,9 +80,9 @@ const EMBEDS = { user: data.getUser() }); }, - NOW_PLAYING: async (data: HybridInteractionMessage, locale: I18n, track: ValidTracks) => { - const title = TrackUtils.getTitle(track); - const thumbnails = await TrackUtils.getThumbnails(track); + NOW_PLAYING: async (data: HybridInteractionMessage, locale: I18n, track: AudioInformation) => { + const title = track.metadata.title; + const thumbnails = track.metadata.thumbnail; const embed = makeInfoEmbed({ title: locale.__('musicplayer.now_playing'), @@ -90,14 +91,13 @@ const EMBEDS = { user: DiscordProvider.client.user }); - if (TrackUtils.getHighestResolutionThumbnail(thumbnails)) - embed.setImage(TrackUtils.getHighestResolutionThumbnail(thumbnails).url); + if (track.metadata.thumbnail) embed.setImage(track.metadata.thumbnail); return embed; }, - NOW_REPEATING: async (data: HybridInteractionMessage, locale: I18n, track: ValidTracks) => { - const title = TrackUtils.getTitle(track); - const thumbnails = await TrackUtils.getThumbnails(track); + NOW_REPEATING: async (data: HybridInteractionMessage, locale: I18n, track: AudioInformation) => { + const title = track.metadata.title; + const thumbnails = track.metadata.thumbnail; const embed = makeInfoEmbed({ title: locale.__('musicplayer.now_playing_repeating'), @@ -106,8 +106,7 @@ const EMBEDS = { user: DiscordProvider.client.user }); - if (TrackUtils.getHighestResolutionThumbnail(thumbnails)) - embed.setImage(TrackUtils.getHighestResolutionThumbnail(thumbnails).url); + if (track.metadata.thumbnail) embed.setImage(track.metadata.thumbnail); return embed; } @@ -230,51 +229,43 @@ export async function joinVoiceChannelProcedure( // Register Event Listeners instance.events.on('playing', async (event: PlayerPlayingEvent) => { + const current = event.instance.nekoPlayer.getCurrentAudioInformation(); + if (!current) return; + const locale = await Locale.getGuildLocale(guild.id); - if (!event.instance.queue || !event.instance.queue.track || event.instance.queue.track.length === 0) return; previousTrack = event.instance.getPreviousTrack(); - if (event.instance.queue.track[0] !== previousTrack) isLoopMessageSent = false; - else if (event.instance.queue.track[0] === previousTrack && isLoopMessageSent) return; + //if (current !== previousTrack) isLoopMessageSent = false; + //else if (current === previousTrack && isLoopMessageSent) return; const row = new ActionRowBuilder(); - if (event.instance.queue.track[0] instanceof SpotifyTrack) - row.addComponents([ - new ButtonBuilder() - .setEmoji('🟢') - .setLabel(' Open in Spotify') - .setURL(encodeURI(`https://open.spotify.com/track/${event.instance.queue.track[0].id}`)) - .setStyle(ButtonStyle.Link) - ]); - if ( - event.instance.queue.track[0] instanceof YouTubeVideo || - event.instance.queue.track[0] instanceof SpotifyTrack - ) { - const actualPlaybackURL = event.instance.getActualPlaybackURL(); - if (event.instance.queue.track[0] instanceof SpotifyTrack && !actualPlaybackURL) return; - row.addComponents([ - new ButtonBuilder() - .setEmoji('🔴') - .setLabel(' Open in YouTube') - .setURL( - event.instance.queue.track[0] instanceof YouTubeVideo - ? encodeURI(`https://www.youtube.com/watch?v=${event.instance.queue.track[0].id}`) - : encodeURI(event.instance.getActualPlaybackURL()!) - ) - .setStyle(ButtonStyle.Link) - ]); - } + // if (event.instance.queue.track[0] instanceof SpotifyTrack) + // row.addComponents([ + // new ButtonBuilder() + // .setEmoji('🟢') + // .setLabel(' Open in Spotify') + // .setURL(encodeURI(`https://open.spotify.com/track/${event.instance.queue.track[0].id}`)) + // .setStyle(ButtonStyle.Link) + // ]); + + row.addComponents([ + new ButtonBuilder() + .setEmoji('🔴') + .setLabel(' Open in YouTube') + .setURL(current.metadata.url) + .setStyle(ButtonStyle.Link) + ]); if (event.instance.textChannel) { if (event.instance.getLoopMode() === DiscordMusicPlayerLoopMode.Current) { isLoopMessageSent = true; await sendMessage(event.instance.textChannel, undefined, { - embeds: [await EMBEDS.NOW_REPEATING(data, locale, event.instance.queue.track[0])], + embeds: [await EMBEDS.NOW_REPEATING(data, locale, current)], components: [row] }); } else { await sendMessage(event.instance.textChannel, undefined, { - embeds: [await EMBEDS.NOW_PLAYING(data, locale, event.instance.queue.track[0])], + embeds: [await EMBEDS.NOW_PLAYING(data, locale, current)], components: [row] }); } diff --git a/src/discord/MusicPlayer/Leave.ts b/src/discord/MusicPlayer/Leave.ts index 567205f..b70f856 100644 --- a/src/discord/MusicPlayer/Leave.ts +++ b/src/discord/MusicPlayer/Leave.ts @@ -1,7 +1,7 @@ import { I18n } from 'i18n'; import { Message, CommandInteraction } from 'discord.js'; -import DiscordMusicPlayer from '../../providers/DiscordMusicPlayerTempFix'; +import DiscordMusicPlayer from '../../providers/DiscordMusicPlayer'; import Locale from '../../services/Locale'; import { makeSuccessEmbed, makeErrorEmbed, sendHybridInteractionMessageResponse } from '../../utils/DiscordMessage'; diff --git a/src/discord/MusicPlayer/Loop.ts b/src/discord/MusicPlayer/Loop.ts index fc981b2..e49877c 100644 --- a/src/discord/MusicPlayer/Loop.ts +++ b/src/discord/MusicPlayer/Loop.ts @@ -1,7 +1,7 @@ import { I18n } from 'i18n'; import { Message, CommandInteraction } from 'discord.js'; -import DiscordMusicPlayer, { DiscordMusicPlayerLoopMode } from '../../providers/DiscordMusicPlayerTempFix'; +import DiscordMusicPlayer, { DiscordMusicPlayerLoopMode } from '../../providers/DiscordMusicPlayer'; import Locale from '../../services/Locale'; import DiscordModule, { HybridInteractionMessage } from '../../utils/DiscordModule'; @@ -105,7 +105,7 @@ export default class Loop extends DiscordModule { true ); - if (instance.queue.track.length === 0) + if (!instance.nekoPlayer.getCurrentAudioInformation()) return await sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.NO_MUSIC_PLAYING(data, locale)] }); diff --git a/src/discord/MusicPlayer/NowPlaying.ts b/src/discord/MusicPlayer/NowPlaying.ts index ebebd2d..2690b3c 100644 --- a/src/discord/MusicPlayer/NowPlaying.ts +++ b/src/discord/MusicPlayer/NowPlaying.ts @@ -3,16 +3,17 @@ import { I18n } from 'i18n'; import { SpotifyTrack, YouTubeVideo } from 'play-dl'; import DiscordProvider from '../../providers/Discord'; -import DiscordMusicPlayer, { TrackUtils, ValidTracks } from '../../providers/DiscordMusicPlayerTempFix'; +import DiscordMusicPlayer, { TrackUtils, ValidTracks } from '../../providers/DiscordMusicPlayer'; import Locale from '../../services/Locale'; import { makeErrorEmbed, makeInfoEmbed, sendHybridInteractionMessageResponse } from '../../utils/DiscordMessage'; import DiscordModule, { HybridInteractionMessage } from '../../utils/DiscordModule'; +import { AudioInformation } from '../../../NekoMelody/src/providers/base'; const EMBEDS = { - NOW_PLAYING: async (data: HybridInteractionMessage, locale: I18n, track: ValidTracks) => { - const title = TrackUtils.getTitle(track); - const thumbnails = await TrackUtils.getThumbnails(track); + NOW_PLAYING: async (data: HybridInteractionMessage, locale: I18n, track: AudioInformation) => { + const title = track.metadata.title; + const thumbnail = track.metadata.thumbnail; const embed = makeInfoEmbed({ title: locale.__('musicplayer.now_playing'), @@ -21,8 +22,7 @@ const EMBEDS = { user: DiscordProvider.client.user }); - if (TrackUtils.getHighestResolutionThumbnail(thumbnails)) - embed.setImage(TrackUtils.getHighestResolutionThumbnail(thumbnails).url); + if (thumbnail) embed.setImage(thumbnail); return embed; }, @@ -53,38 +53,34 @@ export default class NowPlaying extends DiscordModule { const locale = await Locale.getGuildLocale(guild.id); const instance = DiscordMusicPlayer.getGuildInstance(guild.id); - if (!instance || !instance.queue.track[0]) + const current = instance?.nekoPlayer.getCurrentAudioInformation(); + + if (!instance || !current) return await sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.NO_MUSIC_PLAYING(data, locale)] }); const row = new ActionRowBuilder(); - if (instance.queue.track[0] instanceof SpotifyTrack) - row.addComponents([ - new ButtonBuilder() - .setEmoji('🟢') - .setLabel(' Open in Spotify') - .setURL(encodeURI(`https://open.spotify.com/track/${instance.queue.track[0].id}`)) - .setStyle(ButtonStyle.Link) - ]); - if (instance.queue.track[0] instanceof YouTubeVideo || instance.queue.track[0] instanceof SpotifyTrack) { - const actualPlaybackURL = instance.getActualPlaybackURL(); - if (instance.queue.track[0] instanceof SpotifyTrack && !actualPlaybackURL) return; - row.addComponents([ - new ButtonBuilder() - .setEmoji('🔴') - .setLabel(' Open in YouTube') - .setURL( - instance.queue.track[0] instanceof YouTubeVideo - ? encodeURI(`https://www.youtube.com/watch?v=${instance.queue.track[0].id}`) - : encodeURI(instance.getActualPlaybackURL()!) - ) - .setStyle(ButtonStyle.Link) - ]); - } + // if (instance.queue.track[0] instanceof SpotifyTrack) + // row.addComponents([ + // new ButtonBuilder() + // .setEmoji('🟢') + // .setLabel(' Open in Spotify') + // .setURL(encodeURI(`https://open.spotify.com/track/${instance.queue.track[0].id}`)) + // .setStyle(ButtonStyle.Link) + // ]); + + row.addComponents([ + new ButtonBuilder() + .setEmoji('🔴') + .setLabel(' Open in YouTube') + .setURL(current.metadata.url) + .setStyle(ButtonStyle.Link) + ]); + return await sendHybridInteractionMessageResponse(data, { - embeds: [await EMBEDS.NOW_PLAYING(data, locale, instance.queue.track[0])], + embeds: [await EMBEDS.NOW_PLAYING(data, locale, current)], components: [row] }); } diff --git a/src/discord/MusicPlayer/Pause.ts b/src/discord/MusicPlayer/Pause.ts index fcb8ccf..ebf400b 100644 --- a/src/discord/MusicPlayer/Pause.ts +++ b/src/discord/MusicPlayer/Pause.ts @@ -1,7 +1,7 @@ import { Message, CommandInteraction, Interaction } from 'discord.js'; import { I18n } from 'i18n'; -import DiscordMusicPlayer from '../../providers/DiscordMusicPlayerTempFix'; +import DiscordMusicPlayer from '../../providers/DiscordMusicPlayer'; import Locale from '../../services/Locale'; import DiscordModule, { HybridInteractionMessage } from '../../utils/DiscordModule'; @@ -87,7 +87,7 @@ export default class Pause extends DiscordModule { true ); - if (instance.queue.track.length === 0) + if (!instance.nekoPlayer.getCurrentAudioInformation()) return await sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.NO_MUSIC_PLAYING(data, locale)] }); diff --git a/src/discord/MusicPlayer/Play.ts b/src/discord/MusicPlayer/Play.ts index a3719ac..8f634c0 100644 --- a/src/discord/MusicPlayer/Play.ts +++ b/src/discord/MusicPlayer/Play.ts @@ -15,7 +15,7 @@ import { I18n } from 'i18n'; import { joinVoiceChannelProcedure } from './Join'; import DiscordProvider from '../../providers/Discord'; -import DiscordMusicPlayer, { TrackUtils, ValidTracks } from '../../providers/DiscordMusicPlayerTempFix'; +import DiscordMusicPlayer, { TrackUtils, ValidTracks } from '../../providers/DiscordMusicPlayer'; import Locale from '../../services/Locale'; import DiscordModule, { HybridInteractionMessage } from '../../utils/DiscordModule'; @@ -26,6 +26,8 @@ import { makeInfoEmbed } from '../../utils/DiscordMessage'; import { checkBotPermissionsInChannel } from '../../utils/DiscordPermission'; +import { AudioInformation } from '../../../NekoMelody/src/providers/base'; +import { COMMON_EMBEDS } from '../Settings'; const EMBEDS = { PLAY_INFO: (data: HybridInteractionMessage, locale: I18n) => { @@ -41,18 +43,14 @@ const EMBEDS = { user: data.getUser() }); }, - ADDED_QUEUE: async (data: HybridInteractionMessage, locale: I18n, track: ValidTracks) => { - const title = TrackUtils.getTitle(track); - const thumbnails = await TrackUtils.getThumbnails(track); - + ADDED_QUEUE: async (data: HybridInteractionMessage, locale: I18n, track: AudioInformation) => { let embed = makeSuccessEmbed({ title: locale.__('musicplayer_play.queue_added_song'), - description: title, + description: track.metadata.title ?? 'No title', user: data.getUser() }); - if (TrackUtils.getHighestResolutionThumbnail(thumbnails)) - embed.setImage(TrackUtils.getHighestResolutionThumbnail(thumbnails).url); + if (track.metadata.thumbnail) embed.setImage(track.metadata.thumbnail); return embed; }, @@ -265,9 +263,7 @@ export default class Play extends DiscordModule { if (!instance) return; - let result = await DiscordMusicPlayer.searchYouTubeByYouTubeLink( - DiscordMusicPlayer.parseYouTubeLink(interaction.values[0]) - ).catch((err) => { + let result = await instance.nekoPlayer.enqueue(interaction.values[0]).catch((err) => { sendHybridInteractionMessageResponse( hybridData, { embeds: [EMBEDS.LOOKUP_ERROR(hybridData, locale, err)] }, @@ -277,7 +273,6 @@ export default class Play extends DiscordModule { }); if (!result) return; - instance.addTrackToQueue(result); return await sendHybridInteractionMessageResponse( hybridData, { embeds: [await EMBEDS.ADDED_QUEUE(new HybridInteractionMessage(interaction), locale, result)] }, @@ -335,6 +330,14 @@ export default class Play extends DiscordModule { if (!instance) return; + let placeholder: HybridInteractionMessage | undefined; + + let _placeholder = await sendHybridInteractionMessageResponse(data, { + embeds: [COMMON_EMBEDS.PROCESSING(data, locale)] + }); + if (_placeholder) placeholder = new HybridInteractionMessage(_placeholder); + if (!placeholder) return; + if (DiscordMusicPlayer.isYouTubeLink(query)) { let linkData = DiscordMusicPlayer.parseYouTubeLink(query); @@ -345,17 +348,15 @@ export default class Play extends DiscordModule { for (let song of songs) { instance.addTrackToQueue(song); } - return await sendHybridInteractionMessageResponse( - data, - { embeds: [EMBEDS.ADDED_SONGS_QUEUE(data, locale, songs)] }, - true - ); + return placeholder.getMessage().edit({ embeds: [EMBEDS.ADDED_SONGS_QUEUE(data, locale, songs)] }); } - let result = await DiscordMusicPlayer.searchYouTubeByYouTubeLink(linkData).catch((err) => { - sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.LOOKUP_ERROR(data, locale, err)] }, true); - return null; - }); + let result = await instance.nekoPlayer + .enqueue(`https://www.youtube.com/watch?v=${linkData.videoId}`) + .catch((err) => { + placeholder.getMessage().edit({ embeds: [EMBEDS.LOOKUP_ERROR(data, locale, err)] }); + return null; + }); if (!result) return; @@ -371,8 +372,6 @@ export default class Play extends DiscordModule { data.getMessage().suppressEmbeds(true); } - instance.addTrackToQueue(result); - if (linkData.list) { const row = new ActionRowBuilder().addComponents([ new ButtonBuilder() @@ -388,24 +387,16 @@ export default class Play extends DiscordModule { .setStyle(ButtonStyle.Primary) ]); - return await sendHybridInteractionMessageResponse(data, { - embeds: [await EMBEDS.ADDED_QUEUE(data, locale, result)], - components: [row] - }); - } else - return await sendHybridInteractionMessageResponse(data, { - embeds: [await EMBEDS.ADDED_QUEUE(data, locale, result)] - }); + return placeholder + .getMessage() + .edit({ embeds: [await EMBEDS.ADDED_QUEUE(data, locale, result)], components: [row] }); + } else return placeholder.getMessage().edit({ embeds: [await EMBEDS.ADDED_QUEUE(data, locale, result)] }); } else if (DiscordMusicPlayer.isSpotifyLink(query)) { let linkData = DiscordMusicPlayer.parseSpotifyLink(query); if (linkData.type === 'playlist' || linkData.type === 'album') { let playlist = await DiscordMusicPlayer.getSpotifySongsInPlayList(query).catch((err) => { - sendHybridInteractionMessageResponse( - data, - { embeds: [EMBEDS.LOOKUP_ERROR(data, locale, err)] }, - true - ); + placeholder.getMessage().edit({ embeds: [EMBEDS.LOOKUP_ERROR(data, locale, err)] }); return null; }); @@ -416,15 +407,11 @@ export default class Play extends DiscordModule { instance.addTrackToQueue(song); } - return await sendHybridInteractionMessageResponse( - data, - { embeds: [EMBEDS.ADDED_SONGS_QUEUE(data, locale, songs)] }, - true - ); + return placeholder.getMessage().edit({ embeds: [EMBEDS.ADDED_SONGS_QUEUE(data, locale, songs)] }); } let result = await DiscordMusicPlayer.searchSpotifyBySpotifyLink(linkData).catch((err) => { - sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.LOOKUP_ERROR(data, locale, err)] }, true); + placeholder.getMessage().edit({ embeds: [EMBEDS.LOOKUP_ERROR(data, locale, err)] }); return null; }); @@ -442,30 +429,29 @@ export default class Play extends DiscordModule { data.getMessage().suppressEmbeds(true); } - instance.addTrackToQueue(result); + const youTubeQuery = `${result.name} ${result.artists.map((artist) => artist.name).join(' ')}`; - return await sendHybridInteractionMessageResponse(data, { - embeds: [await EMBEDS.ADDED_QUEUE(data, locale, result)] - }); + const youTubeResult = await DiscordMusicPlayer.searchYouTubeByQuery(youTubeQuery); + + if (!youTubeResult) { + placeholder + .getMessage() + .edit({ embeds: [EMBEDS.LOOKUP_ERROR(data, locale, new Error('Cannot find that song'))] }); + return; + } + + const finalResult = await instance.addTrackToQueue(youTubeResult[0]); + + return placeholder.getMessage().edit({ embeds: [await EMBEDS.ADDED_QUEUE(data, locale, finalResult)] }); } else { let result = await DiscordMusicPlayer.searchYouTubeByQuery(query); if (!result) { - // TODO: Send not found embed - await sendHybridInteractionMessageResponse( - data, - { embeds: [EMBEDS.LOOKUP_ERROR(data, locale, new Error('Cannot find that song'))] }, - true - ); + placeholder + .getMessage() + .edit({ embeds: [EMBEDS.LOOKUP_ERROR(data, locale, new Error('Cannot find that song'))] }); return; } - instance.addTrackToQueue(result[0]); - - // Max 1 hour - if (result[0].durationInSec > 3600) - return await sendHybridInteractionMessageResponse(data, { - embeds: [EMBEDS.TOO_LONG(data, locale)] - }); if (result.length > 1) { // TODO: Find a better logic than this @@ -492,15 +478,15 @@ export default class Play extends DiscordModule { .setStyle(ButtonStyle.Primary) ]); - return await sendHybridInteractionMessageResponse(data, { - embeds: [await EMBEDS.ADDED_QUEUE(data, locale, result[0])], - components: [row] - }); + const finalResult = await instance.nekoPlayer.enqueue(result[0].url); + return placeholder + .getMessage() + .edit({ embeds: [await EMBEDS.ADDED_QUEUE(data, locale, finalResult)], components: [row] }); } - return await sendHybridInteractionMessageResponse(data, { - embeds: [await EMBEDS.ADDED_QUEUE(data, locale, result[0])] - }); + const finalResult = await instance.nekoPlayer.enqueue(result[0].url); + + return placeholder.getMessage().edit({ embeds: [await EMBEDS.ADDED_QUEUE(data, locale, finalResult)] }); } } diff --git a/src/discord/MusicPlayer/PlayMy.ts b/src/discord/MusicPlayer/PlayMy.ts index 5c54083..9bd177e 100644 --- a/src/discord/MusicPlayer/PlayMy.ts +++ b/src/discord/MusicPlayer/PlayMy.ts @@ -1,12 +1,14 @@ import { I18n } from 'i18n'; import { Message, CommandInteraction, ActivityType, ActionRowBuilder, ButtonBuilder, ButtonStyle } from 'discord.js'; -import DiscordMusicPlayer, { TrackUtils, ValidTracks } from '../../providers/DiscordMusicPlayerTempFix'; +import DiscordMusicPlayer, { TrackUtils, ValidTracks } from '../../providers/DiscordMusicPlayer'; import Locale from '../../services/Locale'; import { makeSuccessEmbed, makeErrorEmbed, sendHybridInteractionMessageResponse } from '../../utils/DiscordMessage'; import DiscordModule, { HybridInteractionMessage } from '../../utils/DiscordModule'; import { joinVoiceChannelProcedure } from './Join'; +import { AudioInformation } from '../../../NekoMelody/src/providers/base'; +import { COMMON_EMBEDS } from '../Settings'; const EMBEDS = { NOT_DETECTED: (data: HybridInteractionMessage, locale: I18n) => { @@ -27,9 +29,9 @@ const EMBEDS = { user: data.getUser() }); }, - ADDED_QUEUE: async (data: HybridInteractionMessage, locale: I18n, track: ValidTracks) => { - const title = TrackUtils.getTitle(track); - const thumbnails = await TrackUtils.getThumbnails(track); + ADDED_QUEUE: async (data: HybridInteractionMessage, locale: I18n, track: AudioInformation) => { + const title = track.metadata.title; + const thumbnail = track.metadata.thumbnail; let embed = makeSuccessEmbed({ title: locale.__('musicplayer_play.queue_added_song'), @@ -37,8 +39,7 @@ const EMBEDS = { user: data.getUser() }); - if (TrackUtils.getHighestResolutionThumbnail(thumbnails)) - embed.setImage(TrackUtils.getHighestResolutionThumbnail(thumbnails).url); + if (thumbnail) embed.setImage(thumbnail); return embed; }, @@ -101,6 +102,14 @@ export default class PlayMy extends DiscordModule { if (!member.presence) return; if (!member.presence.activities) return; + let placeholder: HybridInteractionMessage | undefined; + + let _placeholder = await sendHybridInteractionMessageResponse(data, { + embeds: [COMMON_EMBEDS.PROCESSING(data, locale)] + }); + if (_placeholder) placeholder = new HybridInteractionMessage(_placeholder); + if (!placeholder) return; + let query; let found = false; for (const activity of member.presence.activities) { @@ -113,13 +122,9 @@ export default class PlayMy extends DiscordModule { const result = await DiscordMusicPlayer.searchYouTubeByQuery(query); if (!result) continue; - instance.addTrackToQueue(result[0]); - // Max 1 hour - if (result[0].durationInSec > 3600) - return await sendHybridInteractionMessageResponse(data, { - embeds: [EMBEDS.TOO_LONG(data, locale)] - }); + const finalResult = await instance.nekoPlayer.enqueue(result[0].url); + if (!finalResult) continue; let row; if (result.length > 1) { @@ -149,19 +154,19 @@ export default class PlayMy extends DiscordModule { } if (!row) - await sendHybridInteractionMessageResponse(data, { - embeds: [await EMBEDS.ADDED_QUEUE(data, locale, result[0])] - }); + return placeholder + .getMessage() + .edit({ embeds: [await EMBEDS.ADDED_QUEUE(data, locale, finalResult)] }); else - await sendHybridInteractionMessageResponse(data, { - embeds: [await EMBEDS.ADDED_QUEUE(data, locale, result[0])], + return placeholder.getMessage().edit({ + embeds: [await EMBEDS.ADDED_QUEUE(data, locale, finalResult)], components: [row] }); } } - if (!found) await sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.NOT_DETECTED(data, locale)] }); - + if (!found) + return await sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.NOT_DETECTED(data, locale)] }); return; } } diff --git a/src/discord/MusicPlayer/Queue.ts b/src/discord/MusicPlayer/Queue.ts index abcfc84..b8e31a1 100644 --- a/src/discord/MusicPlayer/Queue.ts +++ b/src/discord/MusicPlayer/Queue.ts @@ -5,7 +5,7 @@ import DiscordMusicPlayer, { DiscordMusicPlayerInstance, DiscordMusicPlayerLoopMode, TrackUtils -} from '../../providers/DiscordMusicPlayerTempFix'; +} from '../../providers/DiscordMusicPlayer'; import Locale from '../../services/Locale'; import DiscordModule, { HybridInteractionMessage } from '../../utils/DiscordModule'; @@ -18,59 +18,59 @@ import { const EMBEDS = { QUEUE: (data: HybridInteractionMessage, locale: I18n, instance: DiscordMusicPlayerInstance) => { - const queue = instance.queue; + const queue = instance.nekoPlayer.getQueue(); + const current = instance.nekoPlayer.getCurrentAudioInformation(); - if (!queue.track[0]) + if (!current) return makeInfoEmbed({ title: locale.__('musicplayer_queue.title'), description: locale.__('musicplayer_queue.empty'), user: data.getUser() }); - else { - const nowPlayingText = `${ - instance.getLoopMode() === DiscordMusicPlayerLoopMode.Current - ? ` ${locale.__('musicplayer_queue.looping_current')}` - : '' - }: [${TrackUtils.getTitle(queue.track[0])}](${queue.track[0].url})`; - let description; - if (queue.track.length == 1) { - let queueString = `1. [${TrackUtils.getTitle(queue.track[0])}](${queue.track[0].url})`; - description = `${locale.__('musicplayer_queue.now_playing')}${nowPlayingText}\n - There are ${queue.track.length} song in the queue!\n${queueString}`; - } else if (queue.track.length >= 10) { - const upcomingText = `[${TrackUtils.getTitle(queue.track[1])}](${queue.track[1].url})`; - const first10 = queue.track.slice(0, 10); - let queueString = first10 - .map((track, index) => `${index + 1}. [${TrackUtils.getTitle(track)}](${track.url})`) - .join('\n'); - description = `${locale.__('musicplayer_queue.now_playing')}${nowPlayingText} + const nowPlayingText = `${ + instance.getLoopMode() === DiscordMusicPlayerLoopMode.Current + ? ` ${locale.__('musicplayer_queue.looping_current')}` + : '' + }: [${current.metadata.title}](${current.metadata.url})`; + + let description; + if (queue.length == 0) { + let queueString = `1. [${current.metadata.title}](${current.metadata.url})`; + description = `${locale.__('musicplayer_queue.now_playing')}${nowPlayingText}\n + ${locale.__('musicplayer_queue.empty')}`; + } else if (queue.length >= 10) { + const upcomingText = `[${queue[0].metadata.title}](${queue[0].metadata.url})`; + const first10 = queue.slice(0, 10); + let queueString = first10 + .map((track, index) => `${index + 1}. [${track.metadata.title}](${track.metadata.url})`) + .join('\n'); + description = `${locale.__('musicplayer_queue.now_playing')}${nowPlayingText} ${locale.__('musicplayer_queue.upcoming_song')} ${upcomingText}\n - ${locale.__('musicplayer_queue.song_x_in_queue', { COUNT: queue.track.length.toString() })} - ${queueString}\n${queue.track.length > 10 ? `...${queue.track.length - 10} more songs` : ''}`; - } else { - const upcomingText = `[${TrackUtils.getTitle(queue.track[1])}](${queue.track[1].url})`; - const queueString = queue.track - .map((track, index) => `${index + 1}. [${TrackUtils.getTitle(track)}](${track.url})`) - .join('\n'); - description = `${locale.__('musicplayer_queue.now_playing')}${nowPlayingText} + ${locale.__('musicplayer_queue.song_x_in_queue', { COUNT: queue.length.toString() })} + ${queueString}\n${queue.length > 10 ? `...${queue.length - 10} more songs` : ''}`; + } else { + const upcomingText = `[${queue[0].metadata.title}](${queue[0].metadata.url})`; + const queueString = queue + .map((track, index) => `${index + 1}. [${track.metadata.title}](${track.metadata.url})`) + .join('\n'); + description = `${locale.__('musicplayer_queue.now_playing')}${nowPlayingText} ${locale.__('musicplayer_queue.upcoming_song')} ${upcomingText}\n - ${locale.__('musicplayer_queue.song_x_in_queue', { COUNT: queue.track.length.toString() })} + ${locale.__('musicplayer_queue.song_x_in_queue', { COUNT: queue.length.toString() })} ${queueString}`; - } - - return makeInfoEmbed({ - title: locale.__('musicplayer_queue.title'), - description: description, - fields: [ - { - name: locale.__('common.available_args'), - value: locale.__('musicplayer_queue.valid_args') - } - ], - user: data.getUser() - }); } + + return makeInfoEmbed({ + title: locale.__('musicplayer_queue.title'), + description: description, + fields: [ + { + name: locale.__('common.available_args'), + value: locale.__('musicplayer_queue.valid_args') + } + ], + user: data.getUser() + }); }, QUEUE_CLEARED: (data: HybridInteractionMessage, locale: I18n) => { return makeSuccessEmbed({ diff --git a/src/discord/MusicPlayer/Resume.ts b/src/discord/MusicPlayer/Resume.ts index 7e52bea..4803a77 100644 --- a/src/discord/MusicPlayer/Resume.ts +++ b/src/discord/MusicPlayer/Resume.ts @@ -1,7 +1,7 @@ import { Message, CommandInteraction, Interaction } from 'discord.js'; import { I18n } from 'i18n'; -import DiscordMusicPlayer from '../../providers/DiscordMusicPlayerTempFix'; +import DiscordMusicPlayer from '../../providers/DiscordMusicPlayer'; import DiscordModule, { HybridInteractionMessage } from '../../utils/DiscordModule'; import { @@ -87,7 +87,7 @@ export default class Resume extends DiscordModule { true ); - if (instance.queue.track.length === 0) + if (!instance.nekoPlayer.getCurrentAudioInformation()) return await sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.NO_MUSIC_PLAYING(data, locale)] }); diff --git a/src/discord/MusicPlayer/Search.ts b/src/discord/MusicPlayer/Search.ts index f8588f0..c1a8848 100644 --- a/src/discord/MusicPlayer/Search.ts +++ b/src/discord/MusicPlayer/Search.ts @@ -10,7 +10,7 @@ import { I18n } from 'i18n'; import { joinVoiceChannelProcedure } from './Join'; -import DiscordMusicPlayer, { TrackUtils, ValidTracks } from '../../providers/DiscordMusicPlayerTempFix'; +import DiscordMusicPlayer, { TrackUtils, ValidTracks } from '../../providers/DiscordMusicPlayer'; import Locale from '../../services/Locale'; import DiscordModule, { HybridInteractionMessage } from '../../utils/DiscordModule'; diff --git a/src/discord/MusicPlayer/Skip.ts b/src/discord/MusicPlayer/Skip.ts index 538b32c..d1c2089 100644 --- a/src/discord/MusicPlayer/Skip.ts +++ b/src/discord/MusicPlayer/Skip.ts @@ -3,7 +3,7 @@ import DiscordModule, { HybridInteractionMessage } from '../../utils/DiscordModu import { Message, CommandInteraction } from 'discord.js'; import { makeSuccessEmbed, makeErrorEmbed, sendHybridInteractionMessageResponse } from '../../utils/DiscordMessage'; -import DiscordMusicPlayer from '../../providers/DiscordMusicPlayerTempFix'; +import DiscordMusicPlayer from '../../providers/DiscordMusicPlayer'; import { I18n } from 'i18n'; import Locale from '../../services/Locale'; @@ -81,14 +81,14 @@ export default class Skip extends DiscordModule { true ); - if (instance.queue.track.length === 0) + if (!instance.nekoPlayer.getCurrentAudioInformation()) return await sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.NO_MUSIC_PLAYING(data, locale)] }); instance.skipTrack(); - if (instance.queue.track.length === 0) + if (!instance.nekoPlayer.getCurrentAudioInformation()) return await sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.SKIPPED_LASTSONG(data, locale)] }); diff --git a/src/providers/DiscordMusicPlayer.ts b/src/providers/DiscordMusicPlayer.ts index 5f9eac4..7e6ffc9 100644 --- a/src/providers/DiscordMusicPlayer.ts +++ b/src/providers/DiscordMusicPlayer.ts @@ -21,11 +21,13 @@ import { DiscordGatewayAdapterCreator } from '@discordjs/voice'; import playdl, { Spotify, SpotifyPlaylist, SpotifyTrack, YouTubeVideo } from 'play-dl'; -import { EventEmitter } from 'stream'; - +import NekoMelody, { Player } from '../../NekoMelody/src/index'; +import { YtDlpProvider } from '../../NekoMelody/src/providers'; import DiscordProvider from './Discord'; import Environment from './Environment'; import Logger from '../libs/Logger'; +import EventEmitter from 'events'; +import { AudioInformation } from '../../NekoMelody/src/providers/base'; const LOGGING_TAG = '[DiscordMusicPlayer]'; @@ -187,7 +189,8 @@ export enum DiscordMusicPlayerLoopMode { export class DiscordMusicPlayerInstance { public queue: Queue; - public player: AudioPlayer; + public discordPlayer: AudioPlayer; + public nekoPlayer: Player; public textChannel?: BaseGuildTextChannel | BaseGuildVoiceChannel; public voiceChannel: VoiceChannel | StageChannel; public voiceConnection?: VoiceConnection; @@ -196,51 +199,71 @@ export class DiscordMusicPlayerInstance { public paused: boolean = false; public loopMode: DiscordMusicPlayerLoopMode = DiscordMusicPlayerLoopMode.None; - public actualPlaybackURL?: string; - public readonly events: EventEmitter; + private providers = [new YtDlpProvider()]; + constructor({ voiceChannel }: { voiceChannel: VoiceChannel | StageChannel }) { this.queue = new Queue(); - this.player = createAudioPlayer({ + this.discordPlayer = createAudioPlayer({ behaviors: { noSubscriber: NoSubscriberBehavior.Pause, maxMissedFrames: 1000 } }); + this.nekoPlayer = NekoMelody.createPlayer(this.providers); this.voiceChannel = voiceChannel; this.events = new EventEmitter(); - this.player.on(AudioPlayerStatus.Idle, async (oldStage, newStage) => { - //The player stopped - if (newStage.status === AudioPlayerStatus.Idle && oldStage.status !== AudioPlayerStatus.Idle) { - // Loop mode is set to current song - if (this.loopMode === DiscordMusicPlayerLoopMode.Current) { - if (this.queue.track.length !== 0) { - this.previousTrack = this.queue.track[0]; - this.playTrack(this.queue.track[0]); - } - return; - } + // this.player.on(AudioPlayerStatus.Idle, async (oldStage, newStage) => { + // //The player stopped + // if (newStage.status === AudioPlayerStatus.Idle && oldStage.status !== AudioPlayerStatus.Idle) { + // // Loop mode is set to current song + // if (this.loopMode === DiscordMusicPlayerLoopMode.Current) { + // if (this.queue.track.length !== 0) { + // this.previousTrack = this.queue.track[0]; + // this.playTrack(this.queue.track[0]); + // } + // return; + // } - // There are more songs in the queue, remove finished song and play the next one - if (this.queue.track.length !== 0) { - let previousTrack = this.queue.track.shift(); - if (previousTrack) this.previousTrack = previousTrack; + // // There are more songs in the queue, remove finished song and play the next one + // if (this.queue.track.length !== 0) { + // let previousTrack = this.queue.track.shift(); + // if (previousTrack) this.previousTrack = previousTrack; - if (this.queue.track.length > 0) { - this.playTrack(this.queue.track[0]); - } - } - } - }); + // if (this.queue.track.length > 0) { + // this.playTrack(this.queue.track[0]); + // } + // } + // } + // }); - this.player.on(AudioPlayerStatus.Playing, (oldState: any, newState: any) => { + // this.player.on(AudioPlayerStatus.Playing, (oldState: any, newState: any) => { + // this.events.emit('playing', new PlayerPlayingEvent(this)); + // }); + + // this.player.on('error', (error: Error) => { + // this.events.emit('error', new PlayerErrorEvent(this, error)); + // }); + + this.nekoPlayer.on('play', (information: AudioInformation) => { + if (!this.nekoPlayer.stream) throw new Error('No input stream'); + + const resource = createAudioResource(this.nekoPlayer.stream, { + //inlineVolume: true, + }); + + this.discordPlayer.play(resource); + this.nekoPlayer.startCurrentStream(); this.events.emit('playing', new PlayerPlayingEvent(this)); - }); - this.player.on('error', (error: Error) => { - this.events.emit('error', new PlayerErrorEvent(this, error)); + this.discordPlayer.on('stateChange', (oldState, newState) => { + console.log('State change', oldState.status, newState.status); + if (oldState.status === 'playing' && newState.status === 'idle') { + this.nekoPlayer.endCurrentStream(); + } + }); }); } @@ -261,6 +284,8 @@ export class DiscordMusicPlayerInstance { adapterCreator: this.voiceChannel.guild.voiceAdapterCreator as DiscordGatewayAdapterCreator }); + this.voiceConnection.subscribe(this.discordPlayer); + this.voiceConnection.on( VoiceConnectionStatus.Ready, async (oldState: VoiceConnectionState, newState: VoiceConnectionState) => { @@ -290,7 +315,7 @@ export class DiscordMusicPlayerInstance { } public async leaveVoiceChannel() { - if (this.player) this.player.pause(); + if (this.discordPlayer) this.discordPlayer.pause(); const guild = DiscordProvider.client.guilds.cache.get(this.voiceChannel.guild.id); if (!guild) return; @@ -299,81 +324,28 @@ export class DiscordMusicPlayerInstance { } public async pausePlayer() { - if (this.paused || !this.player) return; - if (!this.player.pause(true)) throw new Error('Unable to pause player'); + if (this.paused || !this.discordPlayer) return; + if (!this.discordPlayer.pause(true)) throw new Error('Unable to pause player'); this.paused = true; } public async resumePlayer() { - if (!this.paused || !this.player) return; - if (!this.player.unpause()) throw new Error('Unable to resume player'); + if (!this.paused || !this.discordPlayer) return; + if (!this.discordPlayer.unpause()) throw new Error('Unable to resume player'); this.paused = false; } - public addTrackToQueue(track: ValidTracks) { - if (this.queue.track.length === 0) { - this.queue.track.push(track); - this.playTrack(this.queue.track[0]); - return; - } - - this.queue.track.push(track); - } - - public async playTrack(track: ValidTracks) { - if (!this.voiceConnection) throw new Error('No voice connection'); - - try { - let resource; - if (track instanceof YouTubeVideo) { - const stream = await playdl.stream(track.url); - - Logger.verbose( - LOGGING_TAG, - `New stream created, type: ${stream.type}, url: ${track.url}, Guild: ${this.voiceChannel.guild.id}, VoiceChannel: ${this.voiceChannel.id}` - ); - - resource = createAudioResource(stream.stream, { - inputType: stream.type - }); - this.actualPlaybackURL = track.url; - } else { - const search = await DiscordMusicPlayer_Instance.searchYouTubeBySpotifyLink(track); - if (!search) throw new Error('Unable to find Spotify track on YouTube'); - - const stream = await playdl.stream(search.url); - - Logger.verbose( - LOGGING_TAG, - `New stream created, type: ${stream.type}, url: ${track.url}, Guild: ${this.voiceChannel.guild.id}, VoiceChannel: ${this.voiceChannel.id}` - ); - - resource = createAudioResource(stream.stream, { - inputType: stream.type - }); - this.actualPlaybackURL = search.url; - } - - this.player.play(resource); - this.voiceConnection.subscribe(this.player); - } catch (error: any) { - this.events.emit('error', new PlayerErrorEvent(this, error)); - this.skipTrack(); - } + public async addTrackToQueue(track: ValidTracks) { + return await this.nekoPlayer.enqueue(track.url); } public async skipTrack() { if (!this.voiceConnection) throw new Error('No voice connection'); - if (this.queue.track.length > 1) { - this.previousTrack = this.queue.track[0]; - this.queue.track.shift(); - this.playTrack(this.queue.track[0]); - } else { - this.previousTrack = this.queue.track[0]; - this.queue.track.shift(); - this.player.stop(); - } + if (this.nekoPlayer.getQueue().length === 0) return; + + await this.nekoPlayer.skip(); + if (this.paused) this.paused = false; } public clearQueue() { @@ -413,8 +385,8 @@ export class DiscordMusicPlayerInstance { return this.previousTrack; } - public getActualPlaybackURL() { - return this.actualPlaybackURL; + public getQueue() { + return this.nekoPlayer.getQueue(); } public isReady() { @@ -439,16 +411,13 @@ export class DiscordMusicPlayerInstance { await this.leaveVoiceChannel(); if (this.voiceConnection) { - this.voiceConnection.removeAllListeners(); if (this.voiceConnection.state.status !== 'destroyed') this.voiceConnection.destroy(); } - if (this.player) { - this.player.removeAllListeners(); - this.player.stop(true); + if (this.discordPlayer) { + this.discordPlayer.stop(true); } - this.queue.track = []; this.textChannel = undefined; this.voiceConnection = undefined; } @@ -456,8 +425,8 @@ export class DiscordMusicPlayerInstance { public async _fake_error_on_player() { const stream = 'https://fakestream:42069/fake/stream/fake/audio/fake.mp3'; const resource = createAudioResource(stream); - this.player.play(resource); - this.player.emit('error', new AudioPlayerError(new Error('Music player was manually crashed'), null!)); + this.discordPlayer.play(resource); + //this.player.emit('error', new AudioPlayerError(new Error('Music player was manually crashed'), null!)); } } @@ -500,19 +469,6 @@ class DiscordMusicPlayer { return searched; } - public async searchYouTubeBySpotifyLink(spotifyLink: SpotifyLink) { - const track = await this.searchSpotifyBySpotifyLink(spotifyLink); - if (!track) return; - - let artistNames = ''; - for (let artist of track.artists) artistNames += artist.name + ' '; - - const ytSearchResult = await this.searchYouTubeByQuery(`${artistNames} ${track.name}`); - if (!ytSearchResult) return null; - - return ytSearchResult[0]; - } - public async searchSpotifyBySpotifyLink(spotifyLink: SpotifyLink) { if (playdl.is_expired()) { Logger.debug(LOGGING_TAG, 'Spotify token expired, refreshing...'); @@ -538,87 +494,6 @@ class DiscordMusicPlayer { return track; } - public async searchYouTubeByYouTubeLink(youtubeLink: YouTubeLink) { - // Search the url - const searched: YouTubeVideo[] = await playdl.search('https://www.youtube.com/watch?v=' + youtubeLink.videoId, { - source: { youtube: 'video' } - }); - - Logger.verbose( - LOGGING_TAG, - `Search YouTube by link (Pass 1): ${youtubeLink.videoId}, Total result: ${ - searched.length - }, ${JSON.stringify(searched)}` - ); - - for (let video of searched) { - if (video.id === youtubeLink.videoId) return video; - } - - // Serch the video Id - const searched2: YouTubeVideo[] = await playdl.search(youtubeLink.videoId, { - source: { youtube: 'video' } - }); - - Logger.verbose( - LOGGING_TAG, - `Seach YouTube by video ID (Pass 2): ${youtubeLink.videoId}, Total result: ${ - searched2.length - }, ${JSON.stringify(searched2)}` - ); - - for (let video of searched2) { - if (video.id === youtubeLink.videoId) return video; - } - - // Last resort, search the title - const videoInfo = await playdl.video_basic_info('https://www.youtube.com/watch?v=' + youtubeLink.videoId); - if (videoInfo?.video_details?.title) { - const searched: YouTubeVideo[] = await playdl.search(videoInfo.video_details.title, { - source: { youtube: 'video' } - }); - - Logger.verbose( - LOGGING_TAG, - `Search YouTube by title (Pass 3): ${videoInfo.video_details.title}, Total result: ${ - searched.length - }, ${JSON.stringify(searched)}` - ); - - for (let video of searched) { - if (video.id === youtubeLink.videoId) return video; - } - } - - let yt_info = await playdl.video_info('https://www.youtube.com/watch?v=' + youtubeLink.videoId); - - if (yt_info) { - return new YouTubeVideo({ - id: yt_info.video_details.id, - url: yt_info.video_details.url, - type: yt_info.video_details.type, - title: yt_info.video_details.title, - description: yt_info.video_details.description, - durationRaw: yt_info.video_details.durationRaw, - durationInSec: yt_info.video_details.durationInSec, - uploadedAt: yt_info.video_details.uploadedAt, - upcoming: yt_info.video_details.upcoming, - views: yt_info.video_details.views, - thumbnails: yt_info.video_details.thumbnails, - channel: yt_info.video_details.channel, - likes: yt_info.video_details.likes, - live: yt_info.video_details.live, - liveAt: yt_info.video_details.liveAt, - private: yt_info.video_details.private, - tags: yt_info.video_details.tags, - discretionAdvised: yt_info.video_details.discretionAdvised, - music: yt_info.video_details.music - }); - } - - return null; - } - public async getYouTubeSongsInPlayList(youtubeLink: string) { const result = await playdl.playlist_info(youtubeLink, { incomplete: true diff --git a/src/providers/DiscordMusicPlayerTempFix.ts b/src/providers/DiscordMusicPlayerTempFix.ts deleted file mode 100644 index c0aec7d..0000000 --- a/src/providers/DiscordMusicPlayerTempFix.ts +++ /dev/null @@ -1,792 +0,0 @@ -import { - VoiceChannel, - Snowflake, - StageChannel, - Guild, - PermissionsBitField, - BaseGuildVoiceChannel, - BaseGuildTextChannel -} from 'discord.js'; -import { - AudioPlayer, - VoiceConnection, - createAudioPlayer, - joinVoiceChannel, - createAudioResource, - VoiceConnectionStatus, - AudioPlayerStatus, - NoSubscriberBehavior, - VoiceConnectionState, - AudioPlayerError, - DiscordGatewayAdapterCreator -} from '@discordjs/voice'; -import playdl, { Spotify, SpotifyPlaylist, SpotifyTrack, YouTubeVideo } from 'play-dl'; -import { EventEmitter } from 'stream'; -import YTDlpWrap from 'yt-dlp-wrap'; -const ytDlpWrap = new YTDlpWrap(); -import fs from 'fs'; -import DiscordProvider from './Discord'; -import Environment from './Environment'; -import Logger from '../libs/Logger'; - -const LOGGING_TAG = '[DiscordMusicPlayer]'; - -export type ValidTracks = YouTubeVideo | SpotifyTrack; -declare class YouTubeThumbnail { - url: string; - width: number; - height: number; - constructor(data: any); - toJSON(): { - url: string; - width: number; - height: number; - }; -} - -interface SpotifyThumbnail { - height: number; - width: number; - url: string; -} - -interface TokenOptions { - spotify?: { - client_id: string; - client_secret: string; - refresh_token: string; - market: string; - }; - soundcloud?: { - client_id: string; - }; - youtube?: { - cookie: string; - }; - useragent?: string[]; -} - -let tokenObject: TokenOptions = {}; - -if (Environment.get().YOUTUBE_COOKIE_BASE64) { - Logger.debug(LOGGING_TAG, 'Setting YouTube cookie'); - tokenObject.youtube = { - cookie: Buffer.from(Environment.get().YOUTUBE_COOKIE_BASE64, 'base64').toString() - }; -} - -if ( - Environment.get().SPOTIFY_CLIENT_ID && - Environment.get().SPOTIFY_CLIENT_SECRET && - Environment.get().SPOTIFY_REFRESH_TOKEN && - Environment.get().SPOTIFY_CLIENT_MARKET -) { - Logger.debug(LOGGING_TAG, 'Setting Spotify token'); - tokenObject.spotify = { - client_id: Environment.get().SPOTIFY_CLIENT_ID, - client_secret: Environment.get().SPOTIFY_CLIENT_SECRET, - refresh_token: Environment.get().SPOTIFY_REFRESH_TOKEN, - market: Environment.get().SPOTIFY_CLIENT_MARKET - }; -} - -playdl.setToken(tokenObject); - -export class TrackUtils { - public static getTitle(track: ValidTracks) { - if (track instanceof YouTubeVideo) { - return track.title; - } else if (track instanceof SpotifyTrack) { - let artistNames = ''; - for (let artist of track.artists) artistNames += artist.name + ' '; - - return `${artistNames} - ${track.name}`; - } else { - throw new Error('Invalid track type'); - } - } - public static async getThumbnails(track: ValidTracks) { - if (track instanceof YouTubeVideo) { - return track.thumbnails; - } else if (track instanceof SpotifyTrack) { - if (track.thumbnail) return [track.thumbnail]; - else { - // Try to find the thumbnail again - const result = await DiscordMusicPlayer_Instance.searchSpotifyBySpotifyLink(track); - if (!result) return null; - if (result.thumbnail) return [result.thumbnail]; - return null; - } - } else { - throw new Error('Invalid track type'); - } - } - public static getHighestResolutionThumbnail(thumbnails: YouTubeThumbnail[] | SpotifyThumbnail[] | null) { - if (!thumbnails) return null; - - return (thumbnails as any[]).reduce((prev: any, current: any) => - prev.height * prev.width > current.height * current.width ? prev : current - ); - } -} - -export class Queue { - public track: ValidTracks[] = []; -} - -export class YouTubeLink { - public videoId: string; - public list?: string; - - constructor(videoId: string, list: string) { - this.videoId = videoId; - this.list = list; - } -} - -export class SpotifyLink { - public id: string; - public type: 'track' | 'playlist' | 'album'; - public url: string; - - constructor(id: string, type: 'track' | 'playlist' | 'album', url: string) { - this.id = id; - this.type = type; - this.url = url; - } -} - -export class PlayerPlayingEvent { - public instance: DiscordMusicPlayerInstance; - - constructor(instance: DiscordMusicPlayerInstance) { - this.instance = instance; - } -} - -export class PlayerErrorEvent { - public instance: DiscordMusicPlayerInstance; - public error: Error; - - constructor(instance: DiscordMusicPlayerInstance, error: Error) { - this.instance = instance; - this.error = error; - } -} - -export class VoiceDisconnectedEvent { - public instance: DiscordMusicPlayerInstance; - - constructor(instance: DiscordMusicPlayerInstance) { - this.instance = instance; - } -} - -export enum DiscordMusicPlayerLoopMode { - None = 'none', - Current = 'current' -} - -export class DiscordMusicPlayerInstance { - public queue: Queue; - public player: AudioPlayer; - public textChannel?: BaseGuildTextChannel | BaseGuildVoiceChannel; - public voiceChannel: VoiceChannel | StageChannel; - public voiceConnection?: VoiceConnection; - public previousTrack?: ValidTracks; - - public paused: boolean = false; - public loopMode: DiscordMusicPlayerLoopMode = DiscordMusicPlayerLoopMode.None; - - public actualPlaybackURL?: string; - - public readonly events: EventEmitter; - - constructor({ voiceChannel }: { voiceChannel: VoiceChannel | StageChannel }) { - this.queue = new Queue(); - this.player = createAudioPlayer({ - behaviors: { - noSubscriber: NoSubscriberBehavior.Pause, - maxMissedFrames: 1000 - } - }); - this.voiceChannel = voiceChannel; - this.events = new EventEmitter(); - - this.player.on(AudioPlayerStatus.Idle, async (oldStage, newStage) => { - //The player stopped - if (newStage.status === AudioPlayerStatus.Idle && oldStage.status !== AudioPlayerStatus.Idle) { - // Loop mode is set to current song - if (this.loopMode === DiscordMusicPlayerLoopMode.Current) { - if (this.queue.track.length !== 0) { - this.previousTrack = this.queue.track[0]; - this.playTrack(this.queue.track[0]); - } - return; - } - - // There are more songs in the queue, remove finished song and play the next one - if (this.queue.track.length !== 0) { - let previousTrack = this.queue.track.shift(); - if (previousTrack) this.previousTrack = previousTrack; - - if (this.queue.track.length > 0) { - await this.playTrack(this.queue.track[0]); - } - } - } - }); - - this.player.on(AudioPlayerStatus.Playing, (oldState: any, newState: any) => { - this.events.emit('playing', new PlayerPlayingEvent(this)); - }); - - this.player.on('error', (error: Error) => { - this.events.emit('error', new PlayerErrorEvent(this, error)); - }); - } - - public joinVoiceChannel( - voiceChannel: VoiceChannel | StageChannel, - textChannel?: BaseGuildTextChannel | BaseGuildVoiceChannel - ) { - const permissions = voiceChannel.permissionsFor(DiscordProvider.client.user!); - - if (!permissions || !voiceChannel.joinable || !permissions.has(PermissionsBitField.Flags.Connect)) - throw new Error('No permissions'); - - if (textChannel) this.textChannel = textChannel; - - this.voiceConnection = joinVoiceChannel({ - channelId: this.voiceChannel.id, - guildId: this.voiceChannel.guild.id, - adapterCreator: this.voiceChannel.guild.voiceAdapterCreator as DiscordGatewayAdapterCreator - }); - - this.voiceConnection.on( - VoiceConnectionStatus.Ready, - async (oldState: VoiceConnectionState, newState: VoiceConnectionState) => { - let guild = DiscordProvider.client.guilds.cache.get(voiceChannel.guild.id); - if (guild) { - let currentVC = guild?.members.me?.voice.channel; - if (currentVC && currentVC.id !== this.voiceChannel.id) { - this.voiceChannel = currentVC; - } - } - } - ); - - this.voiceConnection.on( - VoiceConnectionStatus.Disconnected, - (oldState: VoiceConnectionState, newState: VoiceConnectionState) => { - setTimeout(async () => { - let guild = DiscordProvider.client.guilds.cache.get(voiceChannel.guildId); - if (guild) { - if (!guild?.members.me?.voice.channelId) { - this.events.emit('disconnect', new VoiceDisconnectedEvent(this)); - } - } - }, 2000); - } - ); - } - - public async leaveVoiceChannel() { - if (this.player) this.player.pause(); - - const guild = DiscordProvider.client.guilds.cache.get(this.voiceChannel.guild.id); - if (!guild) return; - - if (guild.members.me?.voice) this.voiceConnection?.disconnect(); - } - - public async pausePlayer() { - if (this.paused || !this.player) return; - if (!this.player.pause(true)) throw new Error('Unable to pause player'); - this.paused = true; - } - - public async resumePlayer() { - if (!this.paused || !this.player) return; - if (!this.player.unpause()) throw new Error('Unable to resume player'); - this.paused = false; - } - - public addTrackToQueue(track: ValidTracks) { - if (this.queue.track.length === 0) { - this.queue.track.push(track); - this.playTrack(this.queue.track[0]); - return; - } - - this.queue.track.push(track); - } - - public async playTrack(track: ValidTracks) { - if (!this.voiceConnection) throw new Error('No voice connection'); - - try { - let resource; - if (track instanceof YouTubeVideo) { - await ytDlpWrap.execPromise([ - track.url, - '--extractor-args', - 'youtube:player_client=ios', - '-f', - '140', - '-o', - `./temp/${track.id}.mp3` - ]); - const streamFile = fs.createReadStream(`./temp/${track.id}.mp3`); - - //const stream = await playdl.stream(track.url); - const stream = streamFile; - - // Logger.verbose( - // LOGGING_TAG, - // `New stream created, type: ${stream.type}, url: ${track.url}, Guild: ${this.voiceChannel.guild.id}, VoiceChannel: ${this.voiceChannel.id}` - // ); - - resource = createAudioResource(stream, { - //inputType: stream.type - }); - this.actualPlaybackURL = track.url; - } else { - const search = await DiscordMusicPlayer_Instance.searchYouTubeBySpotifyLink(track); - if (!search) throw new Error('Unable to find Spotify track on YouTube'); - - await ytDlpWrap.execPromise([ - search.url, - '--extractor-args', - 'youtube:player_client=ios', - '-f', - '140', - '-o', - `./temp/${search.id}.mp3` - ]); - const streamFile = fs.createReadStream(`./temp/${search.id}.mp3`); - - //const stream = await playdl.stream(search.url); - const stream = streamFile; - - // Logger.verbose( - // LOGGING_TAG, - // `New stream created, type: ${stream.type}, url: ${track.url}, Guild: ${this.voiceChannel.guild.id}, VoiceChannel: ${this.voiceChannel.id}` - // ); - - resource = createAudioResource(stream, { - //inputType: stream.type - }); - this.actualPlaybackURL = search.url; - } - - this.player.play(resource); - this.voiceConnection.subscribe(this.player); - - let timeout = 0; - while (!resource.started && timeout < 10000) { - await new Promise((resolve) => setTimeout(resolve, 100)); - timeout += 100; - - if (timeout >= 10000) - this.events.emit('error', new PlayerErrorEvent(this, new Error('Resource took too long to start'))); - } - } catch (error: any) { - this.events.emit('error', new PlayerErrorEvent(this, error)); - this.skipTrack(); - } - } - - public async skipTrack() { - if (!this.voiceConnection) throw new Error('No voice connection'); - - if (this.queue.track.length > 1) { - this.previousTrack = this.queue.track[0]; - this.queue.track.shift(); - this.playTrack(this.queue.track[0]); - } else { - this.previousTrack = this.queue.track[0]; - this.queue.track.shift(); - this.player.stop(); - } - } - - public clearQueue() { - if (!this.voiceConnection) throw new Error('No voice connection'); - - if (!this.queue.track || this.queue.track.length === 0) return; - this.queue.track = [this.queue.track[0]]; - } - - public shuffleQueue() { - if (!this.voiceConnection) throw new Error('No voice connection'); - - const shuffleFixedFirst = (queue: ValidTracks[]) => { - if (queue.length <= 2) return queue; - - const fixedFirst = queue.shift(); - if (!fixedFirst) return queue; - - queue.sort(() => Math.random() - 0.5); - queue.unshift(fixedFirst); - return queue; - }; - - if (!this.queue.track || this.queue.track.length === 0) return; - this.queue.track = shuffleFixedFirst(this.queue.track); - } - - public setLoopMode(mode: DiscordMusicPlayerLoopMode) { - this.loopMode = mode; - } - - public getLoopMode() { - return this.loopMode; - } - - public getPreviousTrack(): ValidTracks | undefined { - return this.previousTrack; - } - - public getActualPlaybackURL() { - return this.actualPlaybackURL; - } - - public isReady() { - if (!this.voiceConnection) return false; - return this.voiceConnection.state.status === VoiceConnectionStatus.Ready; - } - - public isConnected() { - if (!this.voiceConnection) return false; - - if (this.voiceConnection.state.status === VoiceConnectionStatus.Destroyed) return false; - if (this.voiceConnection.state.status === VoiceConnectionStatus.Disconnected) return false; - - return true; - } - - public isPaused() { - return this.paused; - } - - public async destroy() { - await this.leaveVoiceChannel(); - - if (this.voiceConnection) { - this.voiceConnection.removeAllListeners(); - if (this.voiceConnection.state.status !== 'destroyed') this.voiceConnection.destroy(); - } - - if (this.player) { - this.player.removeAllListeners(); - this.player.stop(true); - } - - this.queue.track = []; - this.textChannel = undefined; - this.voiceConnection = undefined; - } - - public async _fake_error_on_player() { - const stream = 'https://fakestream:42069/fake/stream/fake/audio/fake.mp3'; - const resource = createAudioResource(stream); - this.player.play(resource); - this.player.emit('error', new AudioPlayerError(new Error('Music player was manually crashed'), null!)); - } -} - -class DiscordMusicPlayer { - public GuildQueue = new Map(); - - public getGuildInstance(guildId: Snowflake): DiscordMusicPlayerInstance | null { - if (!this.isGuildInstanceExists(guildId)) return null; - return this.GuildQueue.get(guildId); - } - - public isGuildInstanceExists(guildId: Snowflake) { - return this.GuildQueue.has(guildId); - } - - public createGuildInstance(guildId: Snowflake, voiceChannel: VoiceChannel | StageChannel) { - this.GuildQueue.set(guildId, new DiscordMusicPlayerInstance({ voiceChannel })); - } - - public async destoryGuildInstance(guild: Guild | Snowflake) { - let guildId: Snowflake = guild instanceof Guild ? guild.id : guild; - - if (this.isGuildInstanceExists(guildId)) { - await this.GuildQueue.get(guildId).destroy(); - this.GuildQueue.delete(guildId); - } - } - - public async searchYouTubeByQuery(query: string) { - const searched: YouTubeVideo[] = await playdl.search(query, { - source: { youtube: 'video' } - }); - - Logger.verbose( - LOGGING_TAG, - `Search YouTube by query: ${query}, Total result: ${searched.length}, ${JSON.stringify(searched)}` - ); - - if (searched.length == 0) return null; - return searched; - } - - public async searchYouTubeBySpotifyLink(spotifyLink: SpotifyLink) { - const track = await this.searchSpotifyBySpotifyLink(spotifyLink); - if (!track) return; - - let artistNames = ''; - for (let artist of track.artists) artistNames += artist.name + ' '; - - const ytSearchResult = await this.searchYouTubeByQuery(`${artistNames} ${track.name}`); - if (!ytSearchResult) return null; - - return ytSearchResult[0]; - } - - public async searchSpotifyBySpotifyLink(spotifyLink: SpotifyLink) { - if (playdl.is_expired()) { - Logger.debug(LOGGING_TAG, 'Spotify token expired, refreshing...'); - await playdl.refreshToken(); - } - - if (spotifyLink.type != 'track') return; - - // Fetch data from spotify - const searched: Spotify = await playdl - .spotify('https://open.spotify.com/track/' + spotifyLink.id) - .catch((err) => { - Logger.error(err.message); - throw new Error('Error while searching on Spotify'); - }); - - Logger.verbose(LOGGING_TAG, `Search Spotify by link: ${spotifyLink.id}, ${JSON.stringify(searched)}`); - - if (!(searched instanceof SpotifyTrack)) return; - - if (!searched) return null; - const track = searched as unknown as SpotifyTrack; - return track; - } - - public async searchYouTubeByYouTubeLink(youtubeLink: YouTubeLink) { - // Search the url - const searched: YouTubeVideo[] = await playdl.search('https://www.youtube.com/watch?v=' + youtubeLink.videoId, { - source: { youtube: 'video' } - }); - - Logger.verbose( - LOGGING_TAG, - `Search YouTube by link (Pass 1): ${youtubeLink.videoId}, Total result: ${ - searched.length - }, ${JSON.stringify(searched)}` - ); - - for (let video of searched) { - if (video.id === youtubeLink.videoId) return video; - } - - // Serch the video Id - const searched2: YouTubeVideo[] = await playdl.search(youtubeLink.videoId, { - source: { youtube: 'video' } - }); - - Logger.verbose( - LOGGING_TAG, - `Seach YouTube by video ID (Pass 2): ${youtubeLink.videoId}, Total result: ${ - searched2.length - }, ${JSON.stringify(searched2)}` - ); - - for (let video of searched2) { - if (video.id === youtubeLink.videoId) return video; - } - - // Last resort, search the title - const videoInfo = await playdl.video_basic_info('https://www.youtube.com/watch?v=' + youtubeLink.videoId); - if (videoInfo?.video_details?.title) { - const searched: YouTubeVideo[] = await playdl.search(videoInfo.video_details.title, { - source: { youtube: 'video' } - }); - - Logger.verbose( - LOGGING_TAG, - `Search YouTube by title (Pass 3): ${videoInfo.video_details.title}, Total result: ${ - searched.length - }, ${JSON.stringify(searched)}` - ); - - for (let video of searched) { - if (video.id === youtubeLink.videoId) return video; - } - } - - let yt_info = await playdl.video_info('https://www.youtube.com/watch?v=' + youtubeLink.videoId); - - if (yt_info) { - return new YouTubeVideo({ - id: yt_info.video_details.id, - url: yt_info.video_details.url, - type: yt_info.video_details.type, - title: yt_info.video_details.title, - description: yt_info.video_details.description, - durationRaw: yt_info.video_details.durationRaw, - durationInSec: yt_info.video_details.durationInSec, - uploadedAt: yt_info.video_details.uploadedAt, - upcoming: yt_info.video_details.upcoming, - views: yt_info.video_details.views, - thumbnails: yt_info.video_details.thumbnails, - channel: yt_info.video_details.channel, - likes: yt_info.video_details.likes, - live: yt_info.video_details.live, - liveAt: yt_info.video_details.liveAt, - private: yt_info.video_details.private, - tags: yt_info.video_details.tags, - discretionAdvised: yt_info.video_details.discretionAdvised, - music: yt_info.video_details.music - }); - } - - return null; - } - - public async getYouTubeSongsInPlayList(youtubeLink: string) { - const result = await playdl.playlist_info(youtubeLink, { - incomplete: true - }); - Logger.verbose(LOGGING_TAG, `Get YouTube songs in playlist: ${youtubeLink}, ${JSON.stringify(result)}`); - return result; - } - - public async getSpotifySongsInPlayList(spotifyLink: string) { - if (playdl.is_expired()) { - Logger.debug(LOGGING_TAG, 'Spotify token expired, refreshing...'); - await playdl.refreshToken(); - } - - const result = await playdl.spotify(spotifyLink).catch((err) => { - Logger.error(err.message); - throw new Error('Error while searching on Spotify'); - }); - - Logger.verbose(LOGGING_TAG, `Get Spotify songs in playlist: ${spotifyLink}, ${JSON.stringify(result)}`); - - if (!(result.type == 'playlist' || result.type == 'album')) throw new Error('Not a spotify playlist'); - - return result as unknown as SpotifyPlaylist; - } - - public isYouTubeLink(link: string): boolean { - try { - this.parseYouTubeLink(link); - return true; - } catch (err) { - return false; - } - } - - public isSpotifyLink(link: string): boolean { - try { - this.parseSpotifyLink(link); - return true; - } catch (err) { - return false; - } - } - - public parseYouTubeLink(query: string): YouTubeLink { - if ( - query.startsWith('https://www.youtube.com/watch?v=') || - query.startsWith('http://www.youtube.com/watch?v=') || - query.startsWith('https://music.youtube.com/watch?v=') || - query.startsWith('https://music.youtube.com/watch?v=') - ) { - let data = this.parseURLQuery(query); - if (!data.v) throw new Error('YouTube link is invalid'); - return { - videoId: data.v, - list: data.list ? (data.list !== 'RDMM' ? data.list : undefined) : undefined - }; - } else if (query.startsWith('https://youtu.be/') || query.startsWith('http://youtu.be/')) { - //Get youtube video id after the url - let videoId = query.split('/')[3]; - - if (!videoId) throw new Error('YouTube link is invalid'); - if (query.split('/')[4]) throw new Error('YouTube link is invalid'); - - return { - videoId: videoId - }; - } else if ( - query.startsWith('https://www.youtube.com/shorts/') || - query.startsWith('http://www.youtube.com/shorts/') - ) { - let videoId = query.split('/')[4]; - - if (!videoId) throw new Error('YouTube link is invalid'); - if (query.split('/')[5]) throw new Error('YouTube link is invalid'); - - return { - videoId: videoId - }; - } else if ( - query.startsWith('https://www.youtube.com/playlist?list=') || - query.startsWith('http://www.youtube.com/playlist?list=') - ) { - let listId = query.split('?list=')[1]; - return { - videoId: '', - list: listId - }; - } else { - throw new Error('YouTube link is invalid'); - } - } - - public parseSpotifyLink(query: string): SpotifyLink { - if (query.startsWith('https://open.spotify.com/track/')) { - let id = query.split('/')[4].split(/[?#]/)[0]; - return { - id: id, - type: 'track', - url: query.split(/[?#]/)[0] - }; - } else if (query.startsWith('https://open.spotify.com/album/')) { - let id = query.split('/')[4].split(/[?#]/)[0]; - return { - id: id, - type: 'album', - url: query.split(/[?#]/)[0] - }; - } else if (query.startsWith('https://open.spotify.com/playlist/')) { - let id = query.split('/')[4].split(/[?#]/)[0]; - return { - id: id, - type: 'playlist', - url: query.split(/[?#]/)[0] - }; - } else { - throw new Error('Spotify link is invalid'); - } - } - - private parseURLQuery(query: string) { - let queryObject: any = {}; - if (query.indexOf('?') >= 0) { - let queryString = query.split('?')[1]; - let queryArray = queryString.split('&'); - for (let i = 0; i < queryArray.length; i++) { - let queryPair = queryArray[i].split('='); - queryObject[queryPair[0]] = queryPair[1]; - } - } - return queryObject; - } -} - -const DiscordMusicPlayer_Instance = new DiscordMusicPlayer(); -export default DiscordMusicPlayer_Instance;