mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 18:57:03 +02:00
Compare commits
332
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f355cb9f76 | ||
|
|
e42576b005 | ||
|
|
f68198475e | ||
|
|
896ae20dce | ||
|
|
b8fdc5424d | ||
|
|
204c3eacc1 | ||
|
|
4d0f21e10b | ||
|
|
d3202e8607 | ||
|
|
a438eb704f | ||
|
|
1569de4475 | ||
|
|
0f022f8295 | ||
|
|
75c21a5129 | ||
|
|
5092d43e8e | ||
|
|
56d5d5e956 | ||
|
|
70eca3293b | ||
|
|
4f7ee54ef7 | ||
|
|
269df9586d | ||
|
|
3152c18840 | ||
|
|
52630596b8 | ||
|
|
7e184b8be0 | ||
|
|
877ba9408d | ||
|
|
8dc9a6b46d | ||
|
|
b3e439669b | ||
|
|
08c909fbe2 | ||
|
|
a44e2e9866 | ||
|
|
bae2f253bc | ||
|
|
d485a463dd | ||
|
|
3da1ed4d6c | ||
|
|
051e9ec74a | ||
|
|
486171f4db | ||
|
|
72de42a9ab | ||
|
|
404e6625c0 | ||
|
|
32e4bf3fd2 | ||
|
|
0d1088fefb | ||
|
|
1a17d607fb | ||
|
|
dcda627518 | ||
|
|
c130da7f0e | ||
|
|
e2df4d35b8 | ||
|
|
7739dbd0a3 | ||
|
|
9b7aa13d61 | ||
|
|
84ecaec5d3 | ||
|
|
01a5f1bd47 | ||
|
|
de0433ca02 | ||
|
|
cf76ae7136 | ||
|
|
ea21636c4e | ||
|
|
dafa834d28 | ||
|
|
f1a1c78588 | ||
|
|
14d16e5daf | ||
|
|
b52c1fc2d9 | ||
|
|
f45b24f7ab | ||
|
|
6ae175e5e0 | ||
|
|
0df27c38a1 | ||
|
|
e27cc3f6ed | ||
|
|
968c3957d0 | ||
|
|
577d2323a8 | ||
|
|
625c6cc649 | ||
|
|
9bc753b512 | ||
|
|
fb34e6ce2f | ||
|
|
f882ea29e2 | ||
|
|
62f68f1f10 | ||
|
|
8c9a41d72b | ||
|
|
5bda754b6e | ||
|
|
c5bb537bf2 | ||
|
|
c59779bedb | ||
|
|
5059e382b3 | ||
|
|
953570461c | ||
|
|
6d527a7170 | ||
|
|
ffd74de79f | ||
|
|
7c9ef9e5e0 | ||
|
|
cd10d9ab4a | ||
|
|
578d4a3ff2 | ||
|
|
0cd01fa258 | ||
|
|
21b37ced8d | ||
|
|
81856276b0 | ||
|
|
389052c692 | ||
|
|
09edd39a06 | ||
|
|
5c3077033e | ||
|
|
ef84d5b3b5 | ||
|
|
d29f91afbc | ||
|
|
ab87282103 | ||
|
|
408417ca68 | ||
|
|
b171ce2011 | ||
|
|
58d0d92d4f | ||
|
|
754f39f623 | ||
|
|
10c8ac95a4 | ||
|
|
b367866a22 | ||
|
|
b26c5137f3 | ||
|
|
13cda7aec0 | ||
|
|
d1b8bfe244 | ||
|
|
734db0957e | ||
|
|
050cb7a834 | ||
|
|
6dbcbc2afc | ||
|
|
484cb8fcb5 | ||
|
|
e09b407e61 | ||
|
|
b8742bae66 | ||
|
|
af58b4614d | ||
|
|
db6c4679b7 | ||
|
|
8169dfd85d | ||
|
|
e6d7f78ea4 | ||
|
|
f1f29b85b7 | ||
|
|
f587bc0983 | ||
|
|
7ef4e0b9af | ||
|
|
b52919ebfe | ||
|
|
84290b1c0e | ||
|
|
24297dcae8 | ||
|
|
c7ee3dbf7e | ||
|
|
dd769a9aa5 | ||
|
|
645cfacecb | ||
|
|
d2041d0ee6 | ||
|
|
ed7dd76ee5 | ||
|
|
bc2b9f1267 | ||
|
|
851a1108d2 | ||
|
|
f09663e1c0 | ||
|
|
6a05f11001 | ||
|
|
36e8a20cd5 | ||
|
|
7630cc52d3 | ||
|
|
23d2ca9a42 | ||
|
|
6e759e52c9 | ||
|
|
85883cd2c5 | ||
|
|
9e4d9c7968 | ||
|
|
9968b2c83d | ||
|
|
be0804ae59 | ||
|
|
129a2c52f9 | ||
|
|
996c9c05df | ||
|
|
36dbb24572 | ||
|
|
aaae8fb8ff | ||
|
|
e5e747f7a0 | ||
|
|
487d149587 | ||
|
|
48c4a4c76d | ||
|
|
33ebbbeb65 | ||
|
|
1a7a1223d5 | ||
|
|
9813459310 | ||
|
|
94c3608ca7 | ||
|
|
7e9be14a9a | ||
|
|
5f773931bc | ||
|
|
b2fd85a5b0 | ||
|
|
b060e65af5 | ||
|
|
8a3e57637d | ||
|
|
90ad923672 | ||
|
|
59108d7637 | ||
|
|
f85d097c16 | ||
|
|
ed92440b94 | ||
|
|
d41d45abae | ||
|
|
32a7db238b | ||
|
|
2dc23ba09d | ||
|
|
30522bfda0 | ||
|
|
ed31f40876 | ||
|
|
6ad64c9bd9 | ||
|
|
bd7c952478 | ||
|
|
f7180f0e1a | ||
|
|
b0611d7d72 | ||
|
|
244968bbbf | ||
|
|
fd8448b0a6 | ||
|
|
17c54be1c8 | ||
|
|
39745dd475 | ||
|
|
d81d885767 | ||
|
|
901cb0fcc8 | ||
|
|
7ee49c4026 | ||
|
|
4cff06110a | ||
|
|
251d40b0f4 | ||
|
|
ad15f83abb | ||
|
|
c2a5b742a7 | ||
|
|
514999e588 | ||
|
|
50d21918b4 | ||
|
|
43b59e4f02 | ||
|
|
d0834ed572 | ||
|
|
caf238dd32 | ||
|
|
0a7a220af3 | ||
|
|
434d1ede3c | ||
|
|
0f47208f5e | ||
|
|
cb2d795461 | ||
|
|
6e934e0ff1 | ||
|
|
375adadbe5 | ||
|
|
082a756f1b | ||
|
|
9fc8a8e2a2 | ||
|
|
1413475679 | ||
|
|
86504e685e | ||
|
|
9df81044d1 | ||
|
|
c5fd7591ea | ||
|
|
cd8e43f945 | ||
|
|
8df112aab4 | ||
|
|
94c04ce102 | ||
|
|
3a170202ca | ||
|
|
46937693a0 | ||
|
|
b391d0b036 | ||
|
|
1061e003f7 | ||
|
|
a2b573abca | ||
|
|
4571d141e6 | ||
|
|
d70225b03c | ||
|
|
dc6c528167 | ||
|
|
b4d5d4c16e | ||
|
|
f2f6d4ff49 | ||
|
|
cdbb7647f0 | ||
|
|
41e40de791 | ||
|
|
c85cd36818 | ||
|
|
5d2c63fed9 | ||
|
|
cead140855 | ||
|
|
63a0143d4f | ||
|
|
19f22993f1 | ||
|
|
b2eb74914f | ||
|
|
05572918b1 | ||
|
|
1cc8b26b16 | ||
|
|
a8e8d20cf1 | ||
|
|
55deb30607 | ||
|
|
03b8b89a17 | ||
|
|
3e421c7eb7 | ||
|
|
fc27caabdc | ||
|
|
3d35fae5ce | ||
|
|
f6dfc4f176 | ||
|
|
fdbbe2f356 | ||
|
|
cdf2aee43f | ||
|
|
56933ddfac | ||
|
|
1df2e818be | ||
|
|
1e4d00ea34 | ||
|
|
1bde50e0a3 | ||
|
|
88290ec1ab | ||
|
|
e8325df832 | ||
|
|
394f28e6ed | ||
|
|
f5f170bcca | ||
|
|
2ffe3fc006 | ||
|
|
406d70b5b7 | ||
|
|
f801e81c8b | ||
|
|
a0e1d8cee0 | ||
|
|
a9a870c3e6 | ||
|
|
3d061a78de | ||
|
|
a188a01244 | ||
|
|
0828722876 | ||
|
|
0ccd9e45d8 | ||
|
|
2f745a16d1 | ||
|
|
100c7391fb | ||
|
|
4f42a31f53 | ||
|
|
0b2e322112 | ||
|
|
042a1afa74 | ||
|
|
3edf4a25be | ||
|
|
43237c2aee | ||
|
|
2fffdc3ef5 | ||
|
|
76e748f0ed | ||
|
|
c353119962 | ||
|
|
5fa4d3b242 | ||
|
|
068e0e26b0 | ||
|
|
f6ca77f8c8 | ||
|
|
4c7eda81ca | ||
|
|
3948af9e39 | ||
|
|
aec30e1944 | ||
|
|
4205b16769 | ||
|
|
4d13803b0c | ||
|
|
b950ac1318 | ||
|
|
1920be28d8 | ||
|
|
8b00772958 | ||
|
|
e2e38dc4b3 | ||
|
|
455f1be041 | ||
|
|
3e37368038 | ||
|
|
4b86e20a13 | ||
|
|
d9a14924eb | ||
|
|
7d9d322405 | ||
|
|
5365044017 | ||
|
|
069edf0847 | ||
|
|
2cdcf95822 | ||
|
|
e43231aa97 | ||
|
|
0df2acd5e6 | ||
|
|
3f0b3f190a | ||
|
|
504f143ff7 | ||
|
|
7cfc30c7a1 | ||
|
|
f3ed687f00 | ||
|
|
e37575148c | ||
|
|
2df9979f08 | ||
|
|
c8ce26d6a7 | ||
|
|
898fd4bbf6 | ||
|
|
744f7195dd | ||
|
|
bc4f51846d | ||
|
|
ab8dc131b8 | ||
|
|
684d33071e | ||
|
|
146e68fc53 | ||
|
|
655b87d876 | ||
|
|
71caa2f703 | ||
|
|
99c95a4c15 | ||
|
|
93632a7073 | ||
|
|
297265822b | ||
|
|
a7f799b5b6 | ||
|
|
b176ec6c96 | ||
|
|
1a008a4852 | ||
|
|
145de2bbbc | ||
|
|
77c516a6eb | ||
|
|
6835004945 | ||
|
|
e36823c159 | ||
|
|
ec6ac128f2 | ||
|
|
d80f47a6c8 | ||
|
|
3a9af7505f | ||
|
|
34ee954502 | ||
|
|
b9878a05a1 | ||
|
|
e9412bc404 | ||
|
|
6755115c8a | ||
|
|
e8ed4615fe | ||
|
|
c55f4c311f | ||
|
|
e063970c58 | ||
|
|
fdf8580f5f | ||
|
|
cffd37c6f1 | ||
|
|
7419b3f29e | ||
|
|
e2f50871ec | ||
|
|
bdea9fdab3 | ||
|
|
ae793c1c28 | ||
|
|
3d912036a7 | ||
|
|
1866077a82 | ||
|
|
8345f99603 | ||
|
|
2ab576a37c | ||
|
|
5b9ff7acb3 | ||
|
|
4cdb712013 | ||
|
|
e6fcfdb514 | ||
|
|
9df1800e10 | ||
|
|
95ba925d27 | ||
|
|
41882ddf23 | ||
|
|
fe9b543a75 | ||
|
|
191843f972 | ||
|
|
c1fde44809 | ||
|
|
1a3517e035 | ||
|
|
afec6d9851 | ||
|
|
e3f2fd70ad | ||
|
|
5adbec25c4 | ||
|
|
4ff8d77460 | ||
|
|
22faa6d294 | ||
|
|
a2abfa7f85 | ||
|
|
7b93b12fcb | ||
|
|
ed252d5dfe | ||
|
|
c365993541 | ||
|
|
30f9475208 | ||
|
|
454c526666 | ||
|
|
e67970d2b9 | ||
|
|
0f1c03d1e5 | ||
|
|
8394f2ec1e | ||
|
|
f14e73d811 | ||
|
|
23e00b4199 | ||
|
|
427b189a34 |
No files matched your search
@@ -1,82 +0,0 @@
|
|||||||
name: Assets
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: main
|
|
||||||
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
asset_repo:
|
|
||||||
type: choice
|
|
||||||
required: false
|
|
||||||
description: What asset repo to write to
|
|
||||||
options:
|
|
||||||
- blitzkit/assets
|
|
||||||
- blitzkit/assets-preview
|
|
||||||
- blitzkit/assets-dev
|
|
||||||
default: blitzkit/assets
|
|
||||||
|
|
||||||
asset_source:
|
|
||||||
type: string
|
|
||||||
required: false
|
|
||||||
description: "Archive URL or Steam to download (example: steam:APP_ID/DEPOT_ID or zip:URL_TO_ZIP)"
|
|
||||||
default: "steam:444200/444202"
|
|
||||||
|
|
||||||
schedule:
|
|
||||||
- cron: "0 2 * * *"
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event.inputs.asset_repo }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
env:
|
|
||||||
DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
|
|
||||||
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
|
|
||||||
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
|
||||||
VIDEOS_SHEET: ${{ secrets.VIDEOS_SHEET }}
|
|
||||||
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
|
|
||||||
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
|
|
||||||
WOTB_DLC_CDN: ${{ secrets.WOTB_DLC_CDN }}
|
|
||||||
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
|
||||||
PUBLIC_ASSET_REPO: ${{ github.event.inputs.asset_repo != '' && github.event.inputs.asset_repo || secrets.PUBLIC_ASSET_REPO }}
|
|
||||||
PUBLIC_ASSET_BRANCH: ${{ secrets.PUBLIC_ASSET_BRANCH }}
|
|
||||||
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
|
|
||||||
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
|
|
||||||
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
|
|
||||||
ALLOW_ROBOTS: true
|
|
||||||
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
|
|
||||||
PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ${{ secrets.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID }}
|
|
||||||
PUBLIC_PATREON_CLIENT_ID: ${{ secrets.PUBLIC_PATREON_CLIENT_ID }}
|
|
||||||
PUBLIC_PATREON_REDIRECT_URI: ${{ secrets.PUBLIC_PATREON_REDIRECT_URI }}
|
|
||||||
PATREON_CLIENT_SECRET: ${{ secrets.PATREON_CLIENT_SECRET }}
|
|
||||||
PUBLIC_NITROPAY_ID: ${{ secrets.PUBLIC_NITROPAY_ID }}
|
|
||||||
PUBLIC_DEBUG_MISSING_I18N: false
|
|
||||||
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
|
|
||||||
PUBLIC_ASSET_FAST_USER: blitzkit
|
|
||||||
PUBLIC_ASSET_FAST_REPO: assets
|
|
||||||
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
|
|
||||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
|
||||||
STEAM_USERNAME: ${{ secrets.STEAM_USERNAME }}
|
|
||||||
STEAM_PASSWORD: ${{ secrets.STEAM_PASSWORD }}
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build_assets:
|
|
||||||
name: Build assets
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
token: ${{ secrets.GH_TOKEN }}
|
|
||||||
- uses: arduino/setup-protoc@v3
|
|
||||||
with:
|
|
||||||
repo-token: ${{ secrets.GH_TOKEN }}
|
|
||||||
- uses: oven-sh/setup-bun@v2
|
|
||||||
- run: bun run setup
|
|
||||||
|
|
||||||
- name: AppArmor hack
|
|
||||||
run: echo 0 | sudo tee /proc/sys/kernel/apparmor_restrict_unprivileged_userns
|
|
||||||
|
|
||||||
- name: Build assets
|
|
||||||
run: bun run build:assets --all-targets --source=${{ github.event.inputs.asset_source || 'steam:444200/444202' }}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
name: Averages
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
schedule:
|
|
||||||
- cron: "0 8 * * *"
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
env:
|
|
||||||
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
|
|
||||||
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
|
||||||
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
|
|
||||||
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
|
|
||||||
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
|
|
||||||
ALLOW_ROBOTS: "true"
|
|
||||||
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
|
|
||||||
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
|
|
||||||
PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ${{ secrets.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID }}
|
|
||||||
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
|
|
||||||
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
|
|
||||||
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
|
|
||||||
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
|
|
||||||
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
|
|
||||||
PUBLIC_BRANCH: ${{ secrets.PUBLIC_BRANCH }}
|
|
||||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
token: ${{ secrets.GH_TOKEN }}
|
|
||||||
- uses: oven-sh/setup-bun@v2
|
|
||||||
- uses: arduino/setup-protoc@v3
|
|
||||||
with:
|
|
||||||
repo-token: ${{ secrets.GH_TOKEN }}
|
|
||||||
- run: bun run setup
|
|
||||||
|
|
||||||
- name: Build averages
|
|
||||||
env:
|
|
||||||
PUBLIC_ASSET_BRANCH: main
|
|
||||||
DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
|
|
||||||
|
|
||||||
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
|
|
||||||
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
|
||||||
VIDEOS_SHEET: ${{ secrets.VIDEOS_SHEET }}
|
|
||||||
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
|
|
||||||
run: bun run build:averages --production
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
name: Bot
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
name: Build bot
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
token: ${{ secrets.GH_TOKEN }}
|
|
||||||
- uses: oven-sh/setup-bun@v2
|
|
||||||
- uses: arduino/setup-protoc@v3
|
|
||||||
with:
|
|
||||||
repo-token: ${{ secrets.GH_TOKEN }}
|
|
||||||
- run: bun run setup
|
|
||||||
|
|
||||||
- name: Build bot
|
|
||||||
run: bun run build:bot
|
|
||||||
|
|
||||||
- name: Archive build
|
|
||||||
uses: actions/upload-artifact@v5
|
|
||||||
with:
|
|
||||||
name: bot
|
|
||||||
path: dist/bot
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
name: IDs
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
schedule:
|
|
||||||
- cron: "0 0 * * 1"
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
env:
|
|
||||||
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
|
|
||||||
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
|
||||||
PUBLIC_ASSET_BRANCH: ${{ secrets.PUBLIC_ASSET_BRANCH }}
|
|
||||||
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
|
|
||||||
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
|
||||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
token: ${{ secrets.GH_TOKEN }}
|
|
||||||
- uses: oven-sh/setup-bun@v2
|
|
||||||
- uses: arduino/setup-protoc@v3
|
|
||||||
with:
|
|
||||||
repo-token: ${{ secrets.GH_TOKEN }}
|
|
||||||
- run: bun run setup
|
|
||||||
|
|
||||||
- name: Discover IDs
|
|
||||||
run: bun build:ids --production
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
name: Host
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: main
|
|
||||||
schedule:
|
|
||||||
- cron: "0 */5 * * *"
|
|
||||||
workflow_dispatch:
|
|
||||||
release:
|
|
||||||
types: [created, published, released, edited]
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
env:
|
|
||||||
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
|
|
||||||
DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
|
|
||||||
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
|
||||||
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
|
|
||||||
PUBLIC_ASSET_BRANCH: ${{ secrets.PUBLIC_ASSET_BRANCH }}
|
|
||||||
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
|
||||||
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
|
|
||||||
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
|
|
||||||
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
|
|
||||||
ALLOW_ROBOTS: ${{ secrets.ALLOW_ROBOTS }}
|
|
||||||
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
|
|
||||||
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
|
|
||||||
PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ${{ secrets.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID }}
|
|
||||||
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
|
|
||||||
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
|
|
||||||
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
|
|
||||||
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
|
|
||||||
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
|
|
||||||
PUBLIC_BRANCH: ${{ secrets.PUBLIC_BRANCH }}
|
|
||||||
PUBLIC_GUIDE_WEBSITE: ${{ secrets.PUBLIC_GUIDE_WEBSITE }}
|
|
||||||
SERVICING: ${{ secrets.SERVICING }}
|
|
||||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
host:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: oven-sh/setup-bun@v2
|
|
||||||
- uses: arduino/setup-protoc@v3
|
|
||||||
with:
|
|
||||||
repo-token: ${{ secrets.GH_TOKEN }}
|
|
||||||
|
|
||||||
- name: Download release assets
|
|
||||||
run: |
|
|
||||||
DOWNLOAD_URL=$(curl -s https://api.github.com/repos/blitzkit/blitzkit/releases/latest \
|
|
||||||
| grep "browser_download_url.*bot.zip" \
|
|
||||||
| cut -d : -f 2,3 \
|
|
||||||
| tr -d \")
|
|
||||||
curl -L -o bot.zip $DOWNLOAD_URL
|
|
||||||
mkdir -p dist/bot
|
|
||||||
unzip bot.zip -d dist/bot
|
|
||||||
|
|
||||||
- name: Install sharp
|
|
||||||
run: bun init -y && bun add sharp
|
|
||||||
|
|
||||||
- name: Move directories
|
|
||||||
run: mv dist/bot/prisma .
|
|
||||||
|
|
||||||
- name: Run bot
|
|
||||||
run: bun run dist/bot/main.js
|
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
name: Discover IDs
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: production
|
||||||
|
|
||||||
|
schedule:
|
||||||
|
- cron: 0 */6 * * *
|
||||||
|
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
discover:
|
||||||
|
name: Discover IDs
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
ref: production
|
||||||
|
submodules: recursive
|
||||||
|
token: ${{ secrets.GH_TOKEN }}
|
||||||
|
|
||||||
|
- name: Setup bun
|
||||||
|
uses: oven-sh/setup-bun@v2
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: bun install
|
||||||
|
|
||||||
|
- name: Setup Git
|
||||||
|
run: |
|
||||||
|
git config --global user.name "github-actions[bot]"
|
||||||
|
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||||
|
|
||||||
|
- name: Discover IDs
|
||||||
|
run: bun run discover-ids
|
||||||
|
env:
|
||||||
|
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
||||||
|
GH_TOKEN: ${{ secrets.IDS_TOKEN }}
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
name: Rating Asia
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
schedule:
|
|
||||||
- cron: "0 17 * * *"
|
|
||||||
|
|
||||||
env:
|
|
||||||
PUBLIC_ASSET_BRANCH: main
|
|
||||||
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
|
|
||||||
DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
|
|
||||||
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
|
|
||||||
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
|
||||||
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
|
||||||
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
|
|
||||||
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
|
|
||||||
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
|
|
||||||
ALLOW_ROBOTS: "true"
|
|
||||||
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
|
|
||||||
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
|
|
||||||
PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ${{ secrets.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID }}
|
|
||||||
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
|
|
||||||
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
|
|
||||||
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
|
|
||||||
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
|
|
||||||
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
|
|
||||||
PUBLIC_BRANCH: ${{ secrets.PUBLIC_BRANCH }}
|
|
||||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
host:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
token: ${{ secrets.GH_TOKEN }}
|
|
||||||
- uses: oven-sh/setup-bun@v2
|
|
||||||
- uses: arduino/setup-protoc@v3
|
|
||||||
with:
|
|
||||||
repo-token: ${{ secrets.GH_TOKEN }}
|
|
||||||
- run: bun run setup
|
|
||||||
|
|
||||||
- name: Generate leaderboard
|
|
||||||
run: bun build:ratingleaderboard --region=asia
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
name: Rating Europe
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
schedule:
|
|
||||||
- cron: "0 23 * * *"
|
|
||||||
|
|
||||||
env:
|
|
||||||
PUBLIC_ASSET_BRANCH: main
|
|
||||||
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
|
|
||||||
DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
|
|
||||||
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
|
|
||||||
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
|
||||||
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
|
||||||
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
|
|
||||||
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
|
|
||||||
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
|
|
||||||
ALLOW_ROBOTS: "true"
|
|
||||||
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
|
|
||||||
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
|
|
||||||
PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ${{ secrets.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID }}
|
|
||||||
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
|
|
||||||
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
|
|
||||||
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
|
|
||||||
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
|
|
||||||
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
|
|
||||||
PUBLIC_BRANCH: ${{ secrets.PUBLIC_BRANCH }}
|
|
||||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
host:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
token: ${{ secrets.GH_TOKEN }}
|
|
||||||
- uses: oven-sh/setup-bun@v2
|
|
||||||
- uses: arduino/setup-protoc@v3
|
|
||||||
with:
|
|
||||||
repo-token: ${{ secrets.GH_TOKEN }}
|
|
||||||
- run: bun run setup
|
|
||||||
|
|
||||||
- name: Generate leaderboard
|
|
||||||
run: bun build:ratingleaderboard --region=eu
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
name: Rating North America
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
schedule:
|
|
||||||
- cron: "0 5 * * *"
|
|
||||||
|
|
||||||
env:
|
|
||||||
PUBLIC_ASSET_BRANCH: main
|
|
||||||
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
|
|
||||||
DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
|
|
||||||
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
|
|
||||||
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
|
||||||
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
|
||||||
PUBLIC_ASSET_FAST_USER: ${{ secrets.PUBLIC_ASSET_FAST_USER }}
|
|
||||||
PUBLIC_ASSET_FAST_REPO: ${{ secrets.PUBLIC_ASSET_FAST_REPO }}
|
|
||||||
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
|
|
||||||
ALLOW_ROBOTS: "true"
|
|
||||||
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
|
|
||||||
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
|
|
||||||
PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ${{ secrets.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID }}
|
|
||||||
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
|
|
||||||
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
|
|
||||||
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
|
|
||||||
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
|
|
||||||
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
|
|
||||||
PUBLIC_BRANCH: ${{ secrets.PUBLIC_BRANCH }}
|
|
||||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
host:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
token: ${{ secrets.GH_TOKEN }}
|
|
||||||
- uses: oven-sh/setup-bun@v2
|
|
||||||
- uses: arduino/setup-protoc@v3
|
|
||||||
with:
|
|
||||||
repo-token: ${{ secrets.GH_TOKEN }}
|
|
||||||
- run: bun run setup
|
|
||||||
|
|
||||||
- name: Generate leaderboard
|
|
||||||
run: bun build:ratingleaderboard --region=com
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
name: Reviews
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
schedule:
|
|
||||||
- cron: 0 0 * * 2
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
env:
|
|
||||||
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
|
|
||||||
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
|
||||||
PUBLIC_ASSET_BRANCH: ${{ secrets.PUBLIC_ASSET_BRANCH }}
|
|
||||||
PUBLIC_ASSET_REPO: ${{ secrets.PUBLIC_ASSET_REPO }}
|
|
||||||
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
|
|
||||||
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
|
||||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
|
||||||
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
token: ${{ secrets.GH_TOKEN }}
|
|
||||||
- uses: oven-sh/setup-bun@v2
|
|
||||||
- uses: arduino/setup-protoc@v3
|
|
||||||
with:
|
|
||||||
repo-token: ${{ secrets.GH_TOKEN }}
|
|
||||||
- run: bun run setup
|
|
||||||
|
|
||||||
- name: Find reviews
|
|
||||||
run: bun run build:reviews
|
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
name: Website
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
|
||||||
|
schedule:
|
||||||
|
- cron: "0 4 * * *"
|
||||||
|
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
branch:
|
||||||
|
description: Branch
|
||||||
|
|
||||||
|
type: choice
|
||||||
|
required: true
|
||||||
|
default: production
|
||||||
|
|
||||||
|
options:
|
||||||
|
- production
|
||||||
|
- main
|
||||||
|
|
||||||
|
environment:
|
||||||
|
description: Environment
|
||||||
|
|
||||||
|
type: choice
|
||||||
|
required: true
|
||||||
|
default: production
|
||||||
|
|
||||||
|
options:
|
||||||
|
- development
|
||||||
|
- beta
|
||||||
|
- production
|
||||||
|
- preview
|
||||||
|
- opentest
|
||||||
|
|
||||||
|
client_provider:
|
||||||
|
description: Client provider
|
||||||
|
|
||||||
|
type: choice
|
||||||
|
required: true
|
||||||
|
default: steam
|
||||||
|
|
||||||
|
options:
|
||||||
|
- steam
|
||||||
|
- zip
|
||||||
|
- wgpkg
|
||||||
|
|
||||||
|
client_source:
|
||||||
|
description: Client source
|
||||||
|
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
default: 444200/windows
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ inputs.environment || github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
env:
|
||||||
|
# client
|
||||||
|
STEAM_USERNAME: ${{ secrets.STEAM_USERNAME }}
|
||||||
|
STEAM_PASSWORD: ${{ secrets.STEAM_PASSWORD }}
|
||||||
|
CLIENT_PROVIDER: ${{ inputs.client_provider || 'steam' }}
|
||||||
|
CLIENT_SOURCE: ${{ inputs.client_source || '444200/windows' }}
|
||||||
|
CLIENT_DIR: ../../temp/game
|
||||||
|
|
||||||
|
# blitzkit
|
||||||
|
PUBLIC_ENVIRONMENT: ${{ inputs.environment || 'production' }}
|
||||||
|
PUBLIC_PROMOTE_OPENTEST: false
|
||||||
|
PUBLIC_STATIC_ASSET_BASE: https://assets.blitzkit.app
|
||||||
|
PUBLIC_GUIDE_WEBSITE: https://guidesblitz.com
|
||||||
|
|
||||||
|
# blitz
|
||||||
|
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
|
||||||
|
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
|
||||||
|
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
|
||||||
|
|
||||||
|
# google
|
||||||
|
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
|
||||||
|
|
||||||
|
# wargaming
|
||||||
|
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build website
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: true
|
||||||
|
matrix:
|
||||||
|
chunk: [default, api]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Free disk space
|
||||||
|
uses: jlumbroso/free-disk-space@main
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
ref: ${{ inputs.branch || 'production' }}
|
||||||
|
submodules: recursive
|
||||||
|
token: ${{ secrets.GH_TOKEN }}
|
||||||
|
|
||||||
|
- name: Setup bun
|
||||||
|
uses: oven-sh/setup-bun@v2
|
||||||
|
|
||||||
|
- name: Setup protoc
|
||||||
|
uses: arduino/setup-protoc@v3
|
||||||
|
with:
|
||||||
|
repo-token: ${{ secrets.GH_TOKEN }}
|
||||||
|
|
||||||
|
- name: Setup CLIs
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y aria2 libarchive-tools
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: bun install
|
||||||
|
|
||||||
|
- name: Download Client
|
||||||
|
run: bun run download-client
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: bun run --bun build
|
||||||
|
env:
|
||||||
|
CHUNK: ${{ matrix.chunk }}
|
||||||
|
|
||||||
|
- name: Upload artifact
|
||||||
|
id: upload
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: chunk-${{ matrix.chunk }}
|
||||||
|
path: dist/website
|
||||||
|
|
||||||
|
- name: Trigger deployment
|
||||||
|
|
||||||
|
if: ${{ github.ref == 'refs/heads/production' }}
|
||||||
|
|
||||||
|
env:
|
||||||
|
TOKEN: ${{ secrets.GH_NODE_DEPLOY_TOKEN }}
|
||||||
|
CHUNK: ${{ matrix.chunk }}
|
||||||
|
|
||||||
|
run: |
|
||||||
|
ENV_FILE="environments/${PUBLIC_ENVIRONMENT}.json"
|
||||||
|
TARGET_REPO=$(jq -r ".nodes.\"$CHUNK\"" "$ENV_FILE")
|
||||||
|
|
||||||
|
if [ "$TARGET_REPO" == "null" ] || [ -z "$TARGET_REPO" ]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
curl \
|
||||||
|
-X POST \
|
||||||
|
-H "Accept: application/vnd.github+json" \
|
||||||
|
-H "Authorization: Bearer $TOKEN" \
|
||||||
|
"https://api.github.com/repos/$TARGET_REPO/dispatches" \
|
||||||
|
-d "{
|
||||||
|
\"event_type\": \"deploy-pages\",
|
||||||
|
\"client_payload\": {
|
||||||
|
\"source_repo\": \"${{ github.repository }}\",
|
||||||
|
\"run_id\": \"${{ github.run_id }}\",
|
||||||
|
\"artifact_id\": \"${{ steps.upload.outputs.artifact-id }}\",
|
||||||
|
\"chunk\": \"$CHUNK\"
|
||||||
|
}
|
||||||
|
}"
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
name: Website
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
schedule:
|
|
||||||
- cron: "0 4 * * *"
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
pages: write
|
|
||||||
id-token: write
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: ${{ github.ref == 'refs/heads/main' }}
|
|
||||||
|
|
||||||
env:
|
|
||||||
PUBLIC_WARGAMING_APPLICATION_ID: ${{ secrets.PUBLIC_WARGAMING_APPLICATION_ID }}
|
|
||||||
PUBLIC_PROMOTE_OPENTEST: ${{ secrets.PUBLIC_PROMOTE_OPENTEST }}
|
|
||||||
ALLOW_ROBOTS: ${{ secrets.ALLOW_ROBOTS }}
|
|
||||||
WOTB_GLOSSARY: ${{ secrets.WOTB_GLOSSARY }}
|
|
||||||
PUBLIC_GOOGLE_TAG_MANAGER_ID: ${{ secrets.PUBLIC_GOOGLE_TAG_MANAGER_ID }}
|
|
||||||
PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID: ${{ secrets.PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID }}
|
|
||||||
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
|
|
||||||
WOTB_GLOSSARY_DOMAIN: ${{ secrets.WOTB_GLOSSARY_DOMAIN }}
|
|
||||||
WOTB_GLOSSARY_PATH: ${{ secrets.WOTB_GLOSSARY_PATH }}
|
|
||||||
PUBLIC_DISCORD_SERVER_ID: ${{ secrets.PUBLIC_DISCORD_SERVER_ID }}
|
|
||||||
PUBLIC_ASSET_BASE: ${{ secrets.PUBLIC_ASSET_BASE }}
|
|
||||||
PUBLIC_BRANCH: ${{ secrets.PUBLIC_BRANCH }}
|
|
||||||
PUBLIC_GUIDE_WEBSITE: ${{ secrets.PUBLIC_GUIDE_WEBSITE }}
|
|
||||||
SERVICING: ${{ secrets.SERVICING }}
|
|
||||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
name: Build website
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v6
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
token: ${{ secrets.GH_TOKEN }}
|
|
||||||
- uses: oven-sh/setup-bun@v2
|
|
||||||
- uses: arduino/setup-protoc@v3
|
|
||||||
with:
|
|
||||||
repo-token: ${{ secrets.GH_TOKEN }}
|
|
||||||
- uses: actions/configure-pages@v5
|
|
||||||
- run: bun run setup
|
|
||||||
|
|
||||||
- name: Build website
|
|
||||||
run: bun run build:website
|
|
||||||
|
|
||||||
- name: Upload artifact
|
|
||||||
uses: actions/upload-pages-artifact@v4
|
|
||||||
with:
|
|
||||||
path: dist/website
|
|
||||||
|
|
||||||
deploy-github-pages:
|
|
||||||
if: ${{ github.ref == 'refs/heads/main' }}
|
|
||||||
name: Deploy to GitHub Pages
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: build
|
|
||||||
environment:
|
|
||||||
name: Production
|
|
||||||
url: ${{ steps.deployment.outputs.page_url }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Deploy to GitHub Pages
|
|
||||||
id: deployment
|
|
||||||
uses: actions/deploy-pages@v4
|
|
||||||
+1
-2
@@ -1,7 +1,7 @@
|
|||||||
node_modules
|
node_modules
|
||||||
_node_modules
|
_node_modules
|
||||||
package-lock.json
|
package-lock.json
|
||||||
*.env
|
.env
|
||||||
/test-results/
|
/test-results/
|
||||||
/playwright-report/
|
/playwright-report/
|
||||||
/playwright/.cache/
|
/playwright/.cache/
|
||||||
@@ -27,7 +27,6 @@ target
|
|||||||
.astro
|
.astro
|
||||||
.vercel
|
.vercel
|
||||||
/src
|
/src
|
||||||
/packages/bot/src/prisma
|
|
||||||
dev-dist
|
dev-dist
|
||||||
# Logs
|
# Logs
|
||||||
logs
|
logs
|
||||||
|
|||||||
Vendored
+1
@@ -192,6 +192,7 @@
|
|||||||
"searchtanks",
|
"searchtanks",
|
||||||
"SHAREDEXP",
|
"SHAREDEXP",
|
||||||
"SKLLD",
|
"SKLLD",
|
||||||
|
"sluggify",
|
||||||
"smoothstep",
|
"smoothstep",
|
||||||
"Smri",
|
"Smri",
|
||||||
"Specularity",
|
"Specularity",
|
||||||
|
|||||||
@@ -8,15 +8,13 @@ If you intend to contribute to the code, note that you may need to check out sen
|
|||||||
|
|
||||||
## Packages
|
## Packages
|
||||||
|
|
||||||
| Package | Title | Source | Memo |
|
| Package | Title | Source | Memo |
|
||||||
| ------------------------------------ | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ |
|
| ------------------------------------ | -------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
||||||
| [packages/app](packages/app) | BlitzKit | [Play Store](https://play.google.com/store/apps/details?id=com.tresabhi.blitzkit), [App Store](https://apps.apple.com/app/4321), [Microsoft Store](https://apps.microsoft.com/detail/zyxw) | The native app of BlitzKit for all platforms. Unavailable from stores at this time. |
|
| [packages/core](packages/core) | | | Mutual internal code shared between all other packages. |
|
||||||
| [packages/bot](packages/bot) | BlitzKit Discord Bot | [Discord Application Directory](https://discord.com/discovery/applications/1097673957865443370) | The one-in-all Discord bot for statistics. |
|
| [packages/i18n](packages/i18n) | | [Crowdin](https://crowdin.com/project/blitzkrieg) | Translations served as JSON shared across all other packages, including some utility code. |
|
||||||
| [packages/core](packages/core) | | | Mutual internal code shared between all other packages. |
|
| [packages/scripts](packages/scripts) | | | CLI utilities for the development and deployment of BlitzKit services. |
|
||||||
| [packages/i18n](packages/i18n) | | [Crowdin](https://crowdin.com/project/blitzkrieg) | Translations served as JSON shared across all other packages, including some utility code. |
|
| [packages/varuna](packages/varuna) | Varuna | [NPM](https://www.npmjs.com/package/varuna) | React and Astro-oriented state management library, awaiting separation from BlitzKit. Unavailable from NPM at this time. |
|
||||||
| [packages/scripts](packages/scripts) | | | CLI utilities for the development and deployment of BlitzKit services. |
|
| [packages/website](packages/website) | BlitzKit | https://blitzkit.app | The BlitzKit website provides a wide range of tools, APIs, and interconnects all other services. |
|
||||||
| [packages/varuna](packages/varuna) | Varuna | [NPM](https://www.npmjs.com/package/varuna) | React and Astro-oriented state management library, awaiting separation from BlitzKit. Unavailable from NPM at this time. |
|
|
||||||
| [packages/website](packages/website) | BlitzKit | https://blitzkit.app | The BlitzKit website provides a wide range of tools, APIs, and interconnects all other services. |
|
|
||||||
|
|
||||||
## Submodules
|
## Submodules
|
||||||
|
|
||||||
@@ -26,22 +24,18 @@ If you intend to contribute to the code, note that you may need to check out sen
|
|||||||
|
|
||||||
## Environment Variables
|
## Environment Variables
|
||||||
|
|
||||||
| Name | Source | BlitzKit Default | Memo |
|
| Name | Source | BlitzKit Default | Memo |
|
||||||
| ------------------------------------------------------------- | -------------------------------------------------------------------------------- | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
|
| ------------------------------------------------------------- | -------------------------------------------------------------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `PUBLIC_WARGAMING_APPLICATION_ID` | [Wargaming Developer's Room](https://developers.wargaming.net/) | | Application ID needed to communicate with Wargaming APIs. |
|
| `PUBLIC_WARGAMING_APPLICATION_ID` | [Wargaming Developer's Room](https://developers.wargaming.net/) | | Application ID needed to communicate with Wargaming APIs. |
|
||||||
| `PUBLIC_PROMOTE_OPENTEST` | | `false` | Optional boolean dictating whether the website advertises [the opentest subdomain of BlitzKit](https://opentest.blitzkit.app/). |
|
| `PUBLIC_PROMOTE_OPENTEST` | | `false` | Optional boolean dictating whether the website advertises [the opentest subdomain of BlitzKit](https://opentest.blitzkit.app/). |
|
||||||
| `ALLOW_ROBOTS` | | `true` | Toggles between `Allow: /` and `Disallow: /` in the website's `/robots.txt`. This is usually `false` for all BlitzKit's subdomains. |
|
| `WOTB_GLOSSARY`, `WOTB_GLOSSARY_DOMAIN`, `WOTB_GLOSSARY_PATH` | | | |
|
||||||
| `WOTB_GLOSSARY`, `WOTB_GLOSSARY_DOMAIN`, `WOTB_GLOSSARY_PATH` | | | |
|
| `PUBLIC_GOOGLE_TAG_MANAGER_ID` | [Google Tag Manager](https://tagmanager.google.com/) | `G-GL2JVHCGPQ` | Google Tag Manager's unique identifier for analytical purposes. |
|
||||||
| `PUBLIC_GOOGLE_TAG_MANAGER_ID` | [Google Tag Manager](https://tagmanager.google.com/) | `G-GL2JVHCGPQ` | Google Tag Manager's unique identifier for analytical purposes. |
|
| `PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID` | [Google Analytics](https://analytics.google.com/) | `430711767` | Google Analytics' unique property ID for [BlitzKit's apex domain](https://blitzkit.app/) and subdomains. |
|
||||||
| `PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID` | [Google Analytics](https://analytics.google.com/) | `430711767` | Google Analytics' unique property ID for [BlitzKit's apex domain](https://blitzkit.app/) and subdomains. |
|
| `GOOGLE_APPLICATION_CREDENTIALS` | [Google Cloud](https://cloud.google.com/) | | Google Cloud's API key, primarily used for ranking popular tanks and finding relevant tank review videos in Tankopedia. |
|
||||||
| `GOOGLE_APPLICATION_CREDENTIALS` | [Google Cloud](https://cloud.google.com/) | | Google Cloud's API key, primarily used for ranking popular tanks and finding relevant tank review videos in Tankopedia. |
|
| `PUBLIC_DISCORD_SERVER_ID` | [BlitzKit Discord Server](https://discord.gg/nDt7AjGJQH) | `734786591205359697` | BlitzKit Discord Server's id. |
|
||||||
| `PUBLIC_DISCORD_SERVER_ID` | [BlitzKit Discord Server](https://discord.gg/nDt7AjGJQH) | `734786591205359697` | BlitzKit Discord Server's id. |
|
| `PUBLIC_ASSET_BASE` | [blitzkit/assets](https://github.com/blitzkit/assets) | `https://blitzkit.github.io/assets` | The root domain and path that serves the external assets like tank models and icons. |
|
||||||
| `PUBLIC_ASSET_BASE` | [blitzkit/assets](https://github.com/blitzkit/assets) | `https://blitzkit.github.io/assets` | The root domain and path that serves the external assets like tank models and icons. |
|
| `PUBLIC_GUIDE_WEBSITE` | [GuidesBlitz](https://guidesblitz.com/) | `https://guidesblitz.com` | The website that serves the encyclopedia-like content in BlitzKit. |
|
||||||
| `PUBLIC_BRANCH` | | `main` | The branch that the website is operating on. This is completely nominal. |
|
| `SERVICING` | | `false` | Wether the website is down for servicing. |
|
||||||
| `PUBLIC_GUIDE_WEBSITE` | [GuidesBlitz](https://guidesblitz.com/) | `https://guidesblitz.com` | The website that serves the encyclopedia-like content in BlitzKit. |
|
| `GH_TOKEN` | [GitHub Fine-Grained Tokens](https://github.com/settings/personal-access-tokens) | | The GitHub API key used for checking out private submodules and pushing content to the asset repository. |
|
||||||
| `SERVICING` | | `false` | Wether the website is down for servicing. |
|
| `DATABASE_URL` | [CockroachDB](https://www.cockroachlabs.com/) | | The CockroachDB-SQL database URL used to link Wargaming and Discord users. |
|
||||||
| `DISCORD_CLIENT_ID` | [Discord Developer Portal](https://discord.com/developers/applications) | `1097673957865443370` | The BlitzKit Discord Bot's user ID. |
|
| `WOTB_DLC_CDN` | | | |
|
||||||
| `GH_TOKEN` | [GitHub Fine-Grained Tokens](https://github.com/settings/personal-access-tokens) | | The GitHub API key used for checking out private submodules and pushing content to the asset repository. |
|
|
||||||
| `DISCORD_TOKEN` | [Discord Developer Portal](https://discord.com/developers/applications) | | The Discord API Key for the BlitzKit Discord Bot. |
|
|
||||||
| `DATABASE_URL` | [CockroachDB](https://www.cockroachlabs.com/) | | The CockroachDB-SQL database URL used to link Wargaming and Discord users. |
|
|
||||||
| `WOTB_DLC_CDN` | | | |
|
|
||||||
@@ -5,50 +5,12 @@
|
|||||||
"": {
|
"": {
|
||||||
"name": "blitzkit",
|
"name": "blitzkit",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@prisma/client": "^6.18.0",
|
"@gltf-transform/extensions": "^4.4.2",
|
||||||
"prisma": "^6.18.0",
|
"lz4js": "^0.2.0",
|
||||||
"sharp": "^0.34.5",
|
"sharp": "^0.34.5",
|
||||||
"typescript": "^5.9.3",
|
"typescript": "^5.9.3",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"packages/app": {
|
|
||||||
"name": "@blitzkit/app",
|
|
||||||
"dependencies": {
|
|
||||||
"@tauri-apps/api": "^2",
|
|
||||||
"@tauri-apps/cli": "^2",
|
|
||||||
"@tauri-apps/plugin-opener": "^2",
|
|
||||||
"typescript": "~5.6.2",
|
|
||||||
"vite": "^6.0.3",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"packages/bot": {
|
|
||||||
"name": "@blitzkit/bot",
|
|
||||||
"dependencies": {
|
|
||||||
"@blitzkit/core": "workspace:*",
|
|
||||||
"@blitzkit/i18n": "workspace:*",
|
|
||||||
"@radix-ui/colors": "^3.0.0",
|
|
||||||
"@radix-ui/themes": "^3.3.0",
|
|
||||||
"@resvg/resvg-js": "^2.6.2",
|
|
||||||
"@types/adm-zip": "^0.5.7",
|
|
||||||
"@types/bun": "^1.3.9",
|
|
||||||
"@types/lodash-es": "^4.17.12",
|
|
||||||
"@types/markdown-escape": "^1.1.3",
|
|
||||||
"@types/react": "^19.2.14",
|
|
||||||
"adm-zip": "^0.5.16",
|
|
||||||
"bepaint": "^0.1.0-beta.3",
|
|
||||||
"discord.js": "^14.25.1",
|
|
||||||
"dotenv": "^17.3.1",
|
|
||||||
"fuzzysort": "^3.1.0",
|
|
||||||
"lodash-es": "^4.17.23",
|
|
||||||
"markdown-escape": "^2.0.0",
|
|
||||||
"pickleparser": "^0.2.1",
|
|
||||||
"prisma": "^6.19.2",
|
|
||||||
"protobufjs": "^7.5.4",
|
|
||||||
"react": "^19.2.4",
|
|
||||||
"satori": "^0.18.4",
|
|
||||||
"sharp": "^0.34.5",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"packages/closed": {
|
"packages/closed": {
|
||||||
"name": "@blitzkit/closed",
|
"name": "@blitzkit/closed",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -67,9 +29,8 @@
|
|||||||
"@bufbuild/protobuf": "^2.9.0",
|
"@bufbuild/protobuf": "^2.9.0",
|
||||||
"@octokit/plugin-throttling": "^11.0.1",
|
"@octokit/plugin-throttling": "^11.0.1",
|
||||||
"@octokit/rest": "^22.0.0",
|
"@octokit/rest": "^22.0.0",
|
||||||
"@prisma/client": "^6.16.2",
|
|
||||||
"@types/adm-zip": "^0.5.7",
|
"@types/adm-zip": "^0.5.7",
|
||||||
"@types/bun": "^1.3.1",
|
"@types/bun": "^1.3.14",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/lz4js": "^0.2.1",
|
"@types/lz4js": "^0.2.1",
|
||||||
"@types/three": "^0.180.0",
|
"@types/three": "^0.180.0",
|
||||||
@@ -78,7 +39,6 @@
|
|||||||
"dotenv": "^17.2.2",
|
"dotenv": "^17.2.2",
|
||||||
"fast-xml-parser": "^5.3.2",
|
"fast-xml-parser": "^5.3.2",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"lz4js": "^0.2.0",
|
|
||||||
"pickleparser": "^0.2.1",
|
"pickleparser": "^0.2.1",
|
||||||
"protobufjs": "^7.5.4",
|
"protobufjs": "^7.5.4",
|
||||||
"three": "^0.180.0",
|
"three": "^0.180.0",
|
||||||
@@ -103,7 +63,7 @@
|
|||||||
"@gltf-transform/functions": "^4.2.1",
|
"@gltf-transform/functions": "^4.2.1",
|
||||||
"@octokit/plugin-throttling": "^11.0.2",
|
"@octokit/plugin-throttling": "^11.0.2",
|
||||||
"@octokit/rest": "^22.0.0",
|
"@octokit/rest": "^22.0.0",
|
||||||
"@types/bun": "^1.3.0",
|
"@types/bun": "^1.3.14",
|
||||||
"@types/decompress": "^4.2.7",
|
"@types/decompress": "^4.2.7",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/lz4js": "^0.2.1",
|
"@types/lz4js": "^0.2.1",
|
||||||
@@ -118,7 +78,7 @@
|
|||||||
"fast-xml-parser": "^5.2.5",
|
"fast-xml-parser": "^5.2.5",
|
||||||
"googleapis": "^162.0.0",
|
"googleapis": "^162.0.0",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"lz4js": "^0.2.0",
|
"lz4-napi": "^2.9.1",
|
||||||
"progress": "^2.0.3",
|
"progress": "^2.0.3",
|
||||||
"puppeteer": "^24.22.3",
|
"puppeteer": "^24.22.3",
|
||||||
"sharp": "^0.34.4",
|
"sharp": "^0.34.4",
|
||||||
@@ -148,6 +108,8 @@
|
|||||||
"@blitzkit/core": "workspace:*",
|
"@blitzkit/core": "workspace:*",
|
||||||
"@blitzkit/i18n": "workspace:*",
|
"@blitzkit/i18n": "workspace:*",
|
||||||
"@fontsource/inter": "^5.2.8",
|
"@fontsource/inter": "^5.2.8",
|
||||||
|
"@gltf-transform/core": "^4.4.2",
|
||||||
|
"@gltf-transform/functions": "^4.4.2",
|
||||||
"@radix-ui/colors": "^3.0.0",
|
"@radix-ui/colors": "^3.0.0",
|
||||||
"@radix-ui/react-icons": "^1.3.2",
|
"@radix-ui/react-icons": "^1.3.2",
|
||||||
"@radix-ui/themes": "^3.2.1",
|
"@radix-ui/themes": "^3.2.1",
|
||||||
@@ -174,6 +136,7 @@
|
|||||||
"react-promise-suspense": "^0.3.4",
|
"react-promise-suspense": "^0.3.4",
|
||||||
"three": "^0.180.0",
|
"three": "^0.180.0",
|
||||||
"three-stdlib": "^2.36.0",
|
"three-stdlib": "^2.36.0",
|
||||||
|
"transliteration": "^2.6.1",
|
||||||
"typescript": "^5.9.3",
|
"typescript": "^5.9.3",
|
||||||
"urlon": "^3.1.0",
|
"urlon": "^3.1.0",
|
||||||
"varuna": "workspace:*",
|
"varuna": "workspace:*",
|
||||||
@@ -182,6 +145,40 @@
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"packages": {
|
"packages": {
|
||||||
|
"@antoniomuso/lz4-napi-android-arm-eabi": ["@antoniomuso/[email protected]", "", { "os": "android", "cpu": "arm" }, "sha512-KcRvkSOymDvxFDT9AGFBc7g+J/Xv4qExMMHhtxjZ45qE2sEIVCXoSFmyLDiVVKztkVzoV24VXPPRLOa4WQOi2Q=="],
|
||||||
|
|
||||||
|
"@antoniomuso/lz4-napi-android-arm64": ["@antoniomuso/[email protected]", "", { "os": "android", "cpu": "arm64" }, "sha512-BNiddtI+5Z83w1jIufTFhTPrtxMVKb0UPezTq47XIE/7vkB6y5mHSWSlcHqEIFFIg2/PVdqyqec1CXv0bkpCPA=="],
|
||||||
|
|
||||||
|
"@antoniomuso/lz4-napi-darwin-arm64": ["@antoniomuso/[email protected]", "", { "os": "darwin", "cpu": "arm64" }, "sha512-nhLu+8g8Q6Yqd0rxRn4JkCMJBUs6mByiyT3Mhha2EgorsA2txx18JKm9qLhnXpDgFGWc94tLEVHqzDk0tLD9yA=="],
|
||||||
|
|
||||||
|
"@antoniomuso/lz4-napi-darwin-x64": ["@antoniomuso/[email protected]", "", { "os": "darwin", "cpu": "x64" }, "sha512-DqkN1D/IrqOaUBppCP7BrF9j5Usb6RqFyz16kf3SHPDxLG7pmemgwXmGWpcNrKQfp4Shx1VkbFWA61gMyE1+uw=="],
|
||||||
|
|
||||||
|
"@antoniomuso/lz4-napi-freebsd-x64": ["@antoniomuso/[email protected]", "", { "os": "freebsd", "cpu": "x64" }, "sha512-ORtZ27l+j0yDgPMgt9q/j10LCchtKS44gFohEWl8fokgr5rzDAYAtMyQZzHV8sqE2LUWHAU3Gk6Wh9s1GRl9ow=="],
|
||||||
|
|
||||||
|
"@antoniomuso/lz4-napi-linux-arm-gnueabihf": ["@antoniomuso/[email protected]", "", { "os": "linux", "cpu": "arm" }, "sha512-GBZgQ/rY0AzjZA4jOKFXmLQKVPGXglVZ3U7SLcCu2nmuHTO73vsqiPeAHnYu7/org1km7yw3ii6XFlBRzyNKIA=="],
|
||||||
|
|
||||||
|
"@antoniomuso/lz4-napi-linux-arm64-gnu": ["@antoniomuso/[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-9lvGts14KHNT4pc9lKYUPI1PRdBkfbyT4HCjyDk8fJJzEG9ryvLvyhTeFr/IVpJOFmkSodZw1nxJMQDT5+zvlQ=="],
|
||||||
|
|
||||||
|
"@antoniomuso/lz4-napi-linux-arm64-musl": ["@antoniomuso/[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-SsidKyLRHGB/rrgic+N7ZxFjjl+Cbav2sbuSj4AJsc37oVhyjzbiI5EEL9Rl+zL4ajL0d3utG3UbIUooThhykQ=="],
|
||||||
|
|
||||||
|
"@antoniomuso/lz4-napi-linux-ppc64-gnu": ["@antoniomuso/[email protected]", "", { "os": "linux", "cpu": "ppc64" }, "sha512-1Joz9RmBLiLIfI5Gk/wmJI/WwQy74prKDhLcCPFoa/FcTOJavJAopAzs1MQdnM7nGklEPOpKZWmKHZz1yQ4LMQ=="],
|
||||||
|
|
||||||
|
"@antoniomuso/lz4-napi-linux-riscv64-gnu": ["@antoniomuso/[email protected]", "", { "os": "linux", "cpu": "none" }, "sha512-3z6jSvhEpnSMlubcHwSn6W8Xziq5LYSuIcSpSo7wTEOopnr6GNnKcH2uTPFsRiqC/aC2TLpm17ktXbYTrYL7jg=="],
|
||||||
|
|
||||||
|
"@antoniomuso/lz4-napi-linux-s390x-gnu": ["@antoniomuso/[email protected]", "", { "os": "linux", "cpu": "s390x" }, "sha512-wtQg/ikF1JutKdWfUdGXvR0LG+eG49mS01luwJXG6sg40DX737T3BAsbjM9Fccvif5jQwC+KmzP8+tvxy2eMtQ=="],
|
||||||
|
|
||||||
|
"@antoniomuso/lz4-napi-linux-x64-gnu": ["@antoniomuso/[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-Vw7vb3i1Q6QU2sI5GdgZdi4cVwN2xZ44Gw/WawIxCno1gX39VIF/j8T1pYwS7Dc67NeoA37LsYIPb3h49CiRRA=="],
|
||||||
|
|
||||||
|
"@antoniomuso/lz4-napi-linux-x64-musl": ["@antoniomuso/[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-oZVrvOPjnI7c07v1lx6HMLFi8xlW9WS0pHmkaisldybNUWmNI6vR44KoqBctGCFplvF5YVMK2xPs3W04UGzF8w=="],
|
||||||
|
|
||||||
|
"@antoniomuso/lz4-napi-openharmony-arm64": ["@antoniomuso/[email protected]", "", { "os": "none", "cpu": "arm64" }, "sha512-mkDQv6C0JbMbCDn070Dv67SWfkDy8uD6DkqUT373LHjdaEXj/0eK2gAVykKyPdnC1RBhONgUCaV4HQOp63oH8Q=="],
|
||||||
|
|
||||||
|
"@antoniomuso/lz4-napi-win32-arm64-msvc": ["@antoniomuso/[email protected]", "", { "os": "win32", "cpu": "arm64" }, "sha512-EBsN9YzV3xpSPr6h/t6ntBetpdtO0nZw9o4sZ1vNOfLJ8FMdHxHiY7FonzhEyTnc4N3x3yMqPudD6zLVy/oNXg=="],
|
||||||
|
|
||||||
|
"@antoniomuso/lz4-napi-win32-ia32-msvc": ["@antoniomuso/[email protected]", "", { "os": "win32", "cpu": "ia32" }, "sha512-Fqe2JmcfjvVrC+BHjHPzoiIzNgjHpQvDO7duMbJh5fW9VvF7pKkjRAPDwhtFhkU/fBLVQywq5WbsFqtJ3pYG/w=="],
|
||||||
|
|
||||||
|
"@antoniomuso/lz4-napi-win32-x64-msvc": ["@antoniomuso/[email protected]", "", { "os": "win32", "cpu": "x64" }, "sha512-N6bAJ4pcYfbiuysHNyEl6uVnYxl0CBboPeA6Iz1GQWJb6mp8J/z4+E8bTvasMuRhIhEW5F6X+oJIwmOwSzHoIQ=="],
|
||||||
|
|
||||||
"@apideck/better-ajv-errors": ["@apideck/[email protected]", "", { "dependencies": { "json-schema": "^0.4.0", "jsonpointer": "^5.0.0", "leven": "^3.1.0" }, "peerDependencies": { "ajv": ">=8" } }, "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA=="],
|
"@apideck/better-ajv-errors": ["@apideck/[email protected]", "", { "dependencies": { "json-schema": "^0.4.0", "jsonpointer": "^5.0.0", "leven": "^3.1.0" }, "peerDependencies": { "ajv": ">=8" } }, "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA=="],
|
||||||
|
|
||||||
"@astrojs/check": ["@astrojs/[email protected]", "", { "dependencies": { "@astrojs/language-server": "^2.15.0", "chokidar": "^4.0.1", "kleur": "^4.1.5", "yargs": "^17.7.2" }, "peerDependencies": { "typescript": "^5.0.0" }, "bin": { "astro-check": "dist/bin.js" } }, "sha512-IOheHwCtpUfvogHHsvu0AbeRZEnjJg3MopdLddkJE70mULItS/Vh37BHcI00mcOJcH1vhD3odbpvWokpxam7xA=="],
|
"@astrojs/check": ["@astrojs/[email protected]", "", { "dependencies": { "@astrojs/language-server": "^2.15.0", "chokidar": "^4.0.1", "kleur": "^4.1.5", "yargs": "^17.7.2" }, "peerDependencies": { "typescript": "^5.0.0" }, "bin": { "astro-check": "dist/bin.js" } }, "sha512-IOheHwCtpUfvogHHsvu0AbeRZEnjJg3MopdLddkJE70mULItS/Vh37BHcI00mcOJcH1vhD3odbpvWokpxam7xA=="],
|
||||||
@@ -394,10 +391,6 @@
|
|||||||
|
|
||||||
"@bbob/plugin-helper": ["@bbob/[email protected]", "", {}, "sha512-idpUcNQ2co6T1oU/7/DG/ZRfipSSkTn9Ozw9f5vaXH7nzV3qhqZnhFVlHTzGGnRlzKlBwWOBzOdWi4Zeqg1c5A=="],
|
"@bbob/plugin-helper": ["@bbob/[email protected]", "", {}, "sha512-idpUcNQ2co6T1oU/7/DG/ZRfipSSkTn9Ozw9f5vaXH7nzV3qhqZnhFVlHTzGGnRlzKlBwWOBzOdWi4Zeqg1c5A=="],
|
||||||
|
|
||||||
"@blitzkit/app": ["@blitzkit/app@workspace:packages/app"],
|
|
||||||
|
|
||||||
"@blitzkit/bot": ["@blitzkit/bot@workspace:packages/bot"],
|
|
||||||
|
|
||||||
"@blitzkit/closed": ["@blitzkit/closed@workspace:packages/closed"],
|
"@blitzkit/closed": ["@blitzkit/closed@workspace:packages/closed"],
|
||||||
|
|
||||||
"@blitzkit/core": ["@blitzkit/core@workspace:packages/core"],
|
"@blitzkit/core": ["@blitzkit/core@workspace:packages/core"],
|
||||||
@@ -414,18 +407,6 @@
|
|||||||
|
|
||||||
"@dimforge/rapier3d-compat": ["@dimforge/[email protected]", "", {}, "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow=="],
|
"@dimforge/rapier3d-compat": ["@dimforge/[email protected]", "", {}, "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow=="],
|
||||||
|
|
||||||
"@discordjs/builders": ["@discordjs/[email protected]", "", { "dependencies": { "@discordjs/formatters": "^0.6.2", "@discordjs/util": "^1.2.0", "@sapphire/shapeshift": "^4.0.0", "discord-api-types": "^0.38.33", "fast-deep-equal": "^3.1.3", "ts-mixer": "^6.0.4", "tslib": "^2.6.3" } }, "sha512-cOU0UDHc3lp/5nKByDxkmRiNZBpdp0kx55aarbiAfakfKJHlxv/yFW1zmIqCAmwH5CRlrH9iMFKJMpvW4DPB+w=="],
|
|
||||||
|
|
||||||
"@discordjs/collection": ["@discordjs/[email protected]", "", {}, "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ=="],
|
|
||||||
|
|
||||||
"@discordjs/formatters": ["@discordjs/[email protected]", "", { "dependencies": { "discord-api-types": "^0.38.33" } }, "sha512-y4UPwWhH6vChKRkGdMB4odasUbHOUwy7KL+OVwF86PvT6QVOwElx+TiI1/6kcmcEe+g5YRXJFiXSXUdabqZOvQ=="],
|
|
||||||
|
|
||||||
"@discordjs/rest": ["@discordjs/[email protected]", "", { "dependencies": { "@discordjs/collection": "^2.1.1", "@discordjs/util": "^1.1.1", "@sapphire/async-queue": "^1.5.3", "@sapphire/snowflake": "^3.5.3", "@vladfrangu/async_event_emitter": "^2.4.6", "discord-api-types": "^0.38.16", "magic-bytes.js": "^1.10.0", "tslib": "^2.6.3", "undici": "6.21.3" } }, "sha512-RDYrhmpB7mTvmCKcpj+pc5k7POKszS4E2O9TYc+U+Y4iaCP+r910QdO43qmpOja8LRr1RJ0b3U+CqVsnPqzf4w=="],
|
|
||||||
|
|
||||||
"@discordjs/util": ["@discordjs/[email protected]", "", { "dependencies": { "discord-api-types": "^0.38.33" } }, "sha512-3LKP7F2+atl9vJFhaBjn4nOaSWahZ/yWjOvA4e5pnXkt2qyXRCHLxoBQy81GFtLGCq7K9lPm9R517M1U+/90Qg=="],
|
|
||||||
|
|
||||||
"@discordjs/ws": ["@discordjs/[email protected]", "", { "dependencies": { "@discordjs/collection": "^2.1.0", "@discordjs/rest": "^2.5.1", "@discordjs/util": "^1.1.0", "@sapphire/async-queue": "^1.5.2", "@types/ws": "^8.5.10", "@vladfrangu/async_event_emitter": "^2.2.4", "discord-api-types": "^0.38.1", "tslib": "^2.6.2", "ws": "^8.17.0" } }, "sha512-wPlQDxEmlDg5IxhJPuxXr3Vy9AjYq5xCvFWGJyD7w7Np8ZGu+Mc+97LCoEc/+AYCo2IDpKioiH0/c/mj5ZR9Uw=="],
|
|
||||||
|
|
||||||
"@doctormckay/stdlib": ["@doctormckay/[email protected]", "", { "dependencies": { "psl": "^1.9.0" } }, "sha512-bwy+gPn6oa2KTpfxJKX3leZoV/wHDVtO0/gq3usPvqPswG//dcf3jVB8LcbRRsKO3BXCt5DqctOQ+Xb07ivxnw=="],
|
"@doctormckay/stdlib": ["@doctormckay/[email protected]", "", { "dependencies": { "psl": "^1.9.0" } }, "sha512-bwy+gPn6oa2KTpfxJKX3leZoV/wHDVtO0/gq3usPvqPswG//dcf3jVB8LcbRRsKO3BXCt5DqctOQ+Xb07ivxnw=="],
|
||||||
|
|
||||||
"@doctormckay/steam-crypto": ["@doctormckay/[email protected]", "", {}, "sha512-lsxgLw640gEdZBOXpVIcYWcYD+V+QbtEsMPzRvjmjz2XXKc7QeEMyHL07yOFRmay+cUwO4ObKTJO0dSInEuq5g=="],
|
"@doctormckay/steam-crypto": ["@doctormckay/[email protected]", "", {}, "sha512-lsxgLw640gEdZBOXpVIcYWcYD+V+QbtEsMPzRvjmjz2XXKc7QeEMyHL07yOFRmay+cUwO4ObKTJO0dSInEuq5g=="],
|
||||||
@@ -510,11 +491,11 @@
|
|||||||
|
|
||||||
"@fontsource/inter": ["@fontsource/[email protected]", "", {}, "sha512-P6r5WnJoKiNVV+zvW2xM13gNdFhAEpQ9dQJHt3naLvfg+LkF2ldgSLiF4T41lf1SQCM9QmkqPTn4TH568IRagg=="],
|
"@fontsource/inter": ["@fontsource/[email protected]", "", {}, "sha512-P6r5WnJoKiNVV+zvW2xM13gNdFhAEpQ9dQJHt3naLvfg+LkF2ldgSLiF4T41lf1SQCM9QmkqPTn4TH568IRagg=="],
|
||||||
|
|
||||||
"@gltf-transform/core": ["@gltf-transform/core@4.2.1", "", { "dependencies": { "property-graph": "^3.0.0" } }, "sha512-qKhrQ29KJ9K6sz7xGoGRllqPBlROjPJMQPvCLBOfgMPH3S/Ph5E0e6fD5WmwTY5QPyBsDMRqKd1Vl0ncThTXGw=="],
|
"@gltf-transform/core": ["@gltf-transform/core@4.4.2", "", { "dependencies": { "property-graph": "^4.1.0" } }, "sha512-qsWKwNSwK+2s834Mt4xbYcyHqCrgNFP7hIv5s487JxebngRfDgelpghNF+kSswGb2/NuapasfK3UViFoSJJoMg=="],
|
||||||
|
|
||||||
"@gltf-transform/extensions": ["@gltf-transform/extensions@4.2.1", "", { "dependencies": { "@gltf-transform/core": "^4.2.1", "ktx-parse": "^1.0.1" } }, "sha512-ieHSJU9qvb3ucWDxgHFcff+C7fLtFPa6G0Wtc/ki7GsN6Rh7o9eoyqi7Ggj2LO4i3ynCwLLPb/onbJKw2fBtsA=="],
|
"@gltf-transform/extensions": ["@gltf-transform/extensions@4.4.2", "", { "dependencies": { "@gltf-transform/core": "^4.4.2", "ktx-parse": "^1.1.0" } }, "sha512-HJH1FM+edC5eNvl6xO0SOXJ/j/3oDoIpSu150OTdJaLBoM3TgCCGIfh4wyhgWAqZrkvgHKVGiZKxcKV5LkgPCQ=="],
|
||||||
|
|
||||||
"@gltf-transform/functions": ["@gltf-transform/functions@4.2.1", "", { "dependencies": { "@gltf-transform/core": "^4.2.1", "@gltf-transform/extensions": "^4.2.1", "ktx-parse": "^1.0.1", "ndarray": "^1.0.19", "ndarray-lanczos": "^0.3.0", "ndarray-pixels": "^5.0.1" } }, "sha512-hFCI80N6zt7yHlqXbzlYEYQbFwK+2OOZNvacrRtrWiCWKI0k1Ad5+nZFsmuIZZV03aXb5XG6UF7JINT3wETS1Q=="],
|
"@gltf-transform/functions": ["@gltf-transform/functions@4.4.2", "", { "dependencies": { "@gltf-transform/core": "^4.4.2", "@gltf-transform/extensions": "^4.4.2", "ktx-parse": "^1.1.0", "ndarray": "^1.0.19", "ndarray-lanczos": "^0.3.0", "ndarray-pixels": "^5.0.1" } }, "sha512-dclXgv9TshMaWBqPDUYd4xTwBQ2PpuR8p0Y9pokrRzGQDUPXRP6lTDzbqT0UmEmxFSvRyPJjvOWUmzeiRafpvw=="],
|
||||||
|
|
||||||
"@img/colour": ["@img/[email protected]", "", {}, "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw=="],
|
"@img/colour": ["@img/[email protected]", "", {}, "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw=="],
|
||||||
|
|
||||||
@@ -672,20 +653,6 @@
|
|||||||
|
|
||||||
"@oslojs/encoding": ["@oslojs/[email protected]", "", {}, "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ=="],
|
"@oslojs/encoding": ["@oslojs/[email protected]", "", {}, "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ=="],
|
||||||
|
|
||||||
"@prisma/client": ["@prisma/[email protected]", "", { "peerDependencies": { "prisma": "*", "typescript": ">=5.1.0" }, "optionalPeers": ["prisma", "typescript"] }, "sha512-jnL2I9gDnPnw4A+4h5SuNn8Gc+1mL1Z79U/3I9eE2gbxJG1oSA+62ByPW4xkeDgwE0fqMzzpAZ7IHxYnLZ4iQA=="],
|
|
||||||
|
|
||||||
"@prisma/config": ["@prisma/[email protected]", "", { "dependencies": { "c12": "3.1.0", "deepmerge-ts": "7.1.5", "effect": "3.18.4", "empathic": "2.0.0" } }, "sha512-rgFzspCpwsE+q3OF/xkp0fI2SJ3PfNe9LLMmuSVbAZ4nN66WfBiKqJKo/hLz3ysxiPQZf8h1SMf2ilqPMeWATQ=="],
|
|
||||||
|
|
||||||
"@prisma/debug": ["@prisma/[email protected]", "", {}, "sha512-PMVPMmxPj0ps1VY75DIrT430MoOyQx9hmm174k6cmLZpcI95rAPXOQ+pp8ANQkJtNyLVDxnxVJ0QLbrm/ViBcg=="],
|
|
||||||
|
|
||||||
"@prisma/engines": ["@prisma/[email protected]", "", { "dependencies": { "@prisma/debug": "6.18.0", "@prisma/engines-version": "6.18.0-8.34b5a692b7bd79939a9a2c3ef97d816e749cda2f", "@prisma/fetch-engine": "6.18.0", "@prisma/get-platform": "6.18.0" } }, "sha512-i5RzjGF/ex6AFgqEe2o1IW8iIxJGYVQJVRau13kHPYEL1Ck8Zvwuzamqed/1iIljs5C7L+Opiz5TzSsUebkriA=="],
|
|
||||||
|
|
||||||
"@prisma/engines-version": ["@prisma/engines-version@6.18.0-8.34b5a692b7bd79939a9a2c3ef97d816e749cda2f", "", {}, "sha512-T7Af4QsJQnSgWN1zBbX+Cha5t4qjHRxoeoWpK4JugJzG/ipmmDMY5S+O0N1ET6sCBNVkf6lz+Y+ZNO9+wFU8pQ=="],
|
|
||||||
|
|
||||||
"@prisma/fetch-engine": ["@prisma/[email protected]", "", { "dependencies": { "@prisma/debug": "6.18.0", "@prisma/engines-version": "6.18.0-8.34b5a692b7bd79939a9a2c3ef97d816e749cda2f", "@prisma/get-platform": "6.18.0" } }, "sha512-TdaBvTtBwP3IoqVYoGIYpD4mWlk0pJpjTJjir/xLeNWlwog7Sl3bD2J0jJ8+5+q/6RBg+acb9drsv5W6lqae7A=="],
|
|
||||||
|
|
||||||
"@prisma/get-platform": ["@prisma/[email protected]", "", { "dependencies": { "@prisma/debug": "6.18.0" } }, "sha512-uXNJCJGhxTCXo2B25Ta91Rk1/Nmlqg9p7G9GKh8TPhxvAyXCvMNQoogj4JLEUy+3ku8g59cpyQIKFhqY2xO2bg=="],
|
|
||||||
|
|
||||||
"@protobufjs/aspromise": ["@protobufjs/[email protected]", "", {}, "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="],
|
"@protobufjs/aspromise": ["@protobufjs/[email protected]", "", {}, "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="],
|
||||||
|
|
||||||
"@protobufjs/base64": ["@protobufjs/[email protected]", "", {}, "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="],
|
"@protobufjs/base64": ["@protobufjs/[email protected]", "", {}, "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="],
|
||||||
@@ -838,32 +805,6 @@
|
|||||||
|
|
||||||
"@react-three/fiber": ["@react-three/[email protected]", "", { "dependencies": { "@babel/runtime": "^7.17.8", "@types/react-reconciler": "^0.32.0", "@types/webxr": "*", "base64-js": "^1.5.1", "buffer": "^6.0.3", "its-fine": "^2.0.0", "react-reconciler": "^0.31.0", "react-use-measure": "^2.1.7", "scheduler": "^0.25.0", "suspend-react": "^0.1.3", "use-sync-external-store": "^1.4.0", "zustand": "^5.0.3" }, "peerDependencies": { "expo": ">=43.0", "expo-asset": ">=8.4", "expo-file-system": ">=11.0", "expo-gl": ">=11.0", "react": "^19.0.0", "react-dom": "^19.0.0", "react-native": ">=0.78", "three": ">=0.156" }, "optionalPeers": ["expo", "expo-asset", "expo-file-system", "expo-gl", "react-dom", "react-native"] }, "sha512-k4iu1R6e5D54918V4sqmISUkI5OgTw3v7/sDRKEC632Wd5g2WBtUS5gyG63X0GJO/HZUj1tsjSXfyzwrUHZl1g=="],
|
"@react-three/fiber": ["@react-three/[email protected]", "", { "dependencies": { "@babel/runtime": "^7.17.8", "@types/react-reconciler": "^0.32.0", "@types/webxr": "*", "base64-js": "^1.5.1", "buffer": "^6.0.3", "its-fine": "^2.0.0", "react-reconciler": "^0.31.0", "react-use-measure": "^2.1.7", "scheduler": "^0.25.0", "suspend-react": "^0.1.3", "use-sync-external-store": "^1.4.0", "zustand": "^5.0.3" }, "peerDependencies": { "expo": ">=43.0", "expo-asset": ">=8.4", "expo-file-system": ">=11.0", "expo-gl": ">=11.0", "react": "^19.0.0", "react-dom": "^19.0.0", "react-native": ">=0.78", "three": ">=0.156" }, "optionalPeers": ["expo", "expo-asset", "expo-file-system", "expo-gl", "react-dom", "react-native"] }, "sha512-k4iu1R6e5D54918V4sqmISUkI5OgTw3v7/sDRKEC632Wd5g2WBtUS5gyG63X0GJO/HZUj1tsjSXfyzwrUHZl1g=="],
|
||||||
|
|
||||||
"@resvg/resvg-js": ["@resvg/[email protected]", "", { "optionalDependencies": { "@resvg/resvg-js-android-arm-eabi": "2.6.2", "@resvg/resvg-js-android-arm64": "2.6.2", "@resvg/resvg-js-darwin-arm64": "2.6.2", "@resvg/resvg-js-darwin-x64": "2.6.2", "@resvg/resvg-js-linux-arm-gnueabihf": "2.6.2", "@resvg/resvg-js-linux-arm64-gnu": "2.6.2", "@resvg/resvg-js-linux-arm64-musl": "2.6.2", "@resvg/resvg-js-linux-x64-gnu": "2.6.2", "@resvg/resvg-js-linux-x64-musl": "2.6.2", "@resvg/resvg-js-win32-arm64-msvc": "2.6.2", "@resvg/resvg-js-win32-ia32-msvc": "2.6.2", "@resvg/resvg-js-win32-x64-msvc": "2.6.2" } }, "sha512-xBaJish5OeGmniDj9cW5PRa/PtmuVU3ziqrbr5xJj901ZDN4TosrVaNZpEiLZAxdfnhAe7uQ7QFWfjPe9d9K2Q=="],
|
|
||||||
|
|
||||||
"@resvg/resvg-js-android-arm-eabi": ["@resvg/[email protected]", "", { "os": "android", "cpu": "arm" }, "sha512-FrJibrAk6v29eabIPgcTUMPXiEz8ssrAk7TXxsiZzww9UTQ1Z5KAbFJs+Z0Ez+VZTYgnE5IQJqBcoSiMebtPHA=="],
|
|
||||||
|
|
||||||
"@resvg/resvg-js-android-arm64": ["@resvg/[email protected]", "", { "os": "android", "cpu": "arm64" }, "sha512-VcOKezEhm2VqzXpcIJoITuvUS/fcjIw5NA/w3tjzWyzmvoCdd+QXIqy3FBGulWdClvp4g+IfUemigrkLThSjAQ=="],
|
|
||||||
|
|
||||||
"@resvg/resvg-js-darwin-arm64": ["@resvg/[email protected]", "", { "os": "darwin", "cpu": "arm64" }, "sha512-nmok2LnAd6nLUKI16aEB9ydMC6Lidiiq2m1nEBDR1LaaP7FGs4AJ90qDraxX+CWlVuRlvNjyYJTNv8qFjtL9+A=="],
|
|
||||||
|
|
||||||
"@resvg/resvg-js-darwin-x64": ["@resvg/[email protected]", "", { "os": "darwin", "cpu": "x64" }, "sha512-GInyZLjgWDfsVT6+SHxQVRwNzV0AuA1uqGsOAW+0th56J7Nh6bHHKXHBWzUrihxMetcFDmQMAX1tZ1fZDYSRsw=="],
|
|
||||||
|
|
||||||
"@resvg/resvg-js-linux-arm-gnueabihf": ["@resvg/[email protected]", "", { "os": "linux", "cpu": "arm" }, "sha512-YIV3u/R9zJbpqTTNwTZM5/ocWetDKGsro0SWp70eGEM9eV2MerWyBRZnQIgzU3YBnSBQ1RcxRZvY/UxwESfZIw=="],
|
|
||||||
|
|
||||||
"@resvg/resvg-js-linux-arm64-gnu": ["@resvg/[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-zc2BlJSim7YR4FZDQ8OUoJg5holYzdiYMeobb9pJuGDidGL9KZUv7SbiD4E8oZogtYY42UZEap7dqkkYuA91pg=="],
|
|
||||||
|
|
||||||
"@resvg/resvg-js-linux-arm64-musl": ["@resvg/[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-3h3dLPWNgSsD4lQBJPb4f+kvdOSJHa5PjTYVsWHxLUzH4IFTJUAnmuWpw4KqyQ3NA5QCyhw4TWgxk3jRkQxEKg=="],
|
|
||||||
|
|
||||||
"@resvg/resvg-js-linux-x64-gnu": ["@resvg/[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-IVUe+ckIerA7xMZ50duAZzwf1U7khQe2E0QpUxu5MBJNao5RqC0zwV/Zm965vw6D3gGFUl7j4m+oJjubBVoftw=="],
|
|
||||||
|
|
||||||
"@resvg/resvg-js-linux-x64-musl": ["@resvg/[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-UOf83vqTzoYQO9SZ0fPl2ZIFtNIz/Rr/y+7X8XRX1ZnBYsQ/tTb+cj9TE+KHOdmlTFBxhYzVkP2lRByCzqi4jQ=="],
|
|
||||||
|
|
||||||
"@resvg/resvg-js-win32-arm64-msvc": ["@resvg/[email protected]", "", { "os": "win32", "cpu": "arm64" }, "sha512-7C/RSgCa+7vqZ7qAbItfiaAWhyRSoD4l4BQAbVDqRRsRgY+S+hgS3in0Rxr7IorKUpGE69X48q6/nOAuTJQxeQ=="],
|
|
||||||
|
|
||||||
"@resvg/resvg-js-win32-ia32-msvc": ["@resvg/[email protected]", "", { "os": "win32", "cpu": "ia32" }, "sha512-har4aPAlvjnLcil40AC77YDIk6loMawuJwFINEM7n0pZviwMkMvjb2W5ZirsNOZY4aDbo5tLx0wNMREp5Brk+w=="],
|
|
||||||
|
|
||||||
"@resvg/resvg-js-win32-x64-msvc": ["@resvg/[email protected]", "", { "os": "win32", "cpu": "x64" }, "sha512-ZXtYhtUr5SSaBrUDq7DiyjOFJqBVL/dOBN7N/qmi/pO0IgiWW/f/ue3nbvu9joWE5aAKDoIzy/CxsY0suwGosQ=="],
|
|
||||||
|
|
||||||
"@rolldown/pluginutils": ["@rolldown/[email protected]", "", {}, "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA=="],
|
"@rolldown/pluginutils": ["@rolldown/[email protected]", "", {}, "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA=="],
|
||||||
|
|
||||||
"@rollup/plugin-babel": ["@rollup/[email protected]", "", { "dependencies": { "@babel/helper-module-imports": "^7.10.4", "@rollup/pluginutils": "^3.1.0" }, "peerDependencies": { "@babel/core": "^7.0.0", "@types/babel__core": "^7.1.9", "rollup": "^1.20.0||^2.0.0" }, "optionalPeers": ["@types/babel__core"] }, "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q=="],
|
"@rollup/plugin-babel": ["@rollup/[email protected]", "", { "dependencies": { "@babel/helper-module-imports": "^7.10.4", "@rollup/pluginutils": "^3.1.0" }, "peerDependencies": { "@babel/core": "^7.0.0", "@types/babel__core": "^7.1.9", "rollup": "^1.20.0||^2.0.0" }, "optionalPeers": ["@types/babel__core"] }, "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q=="],
|
||||||
@@ -920,12 +861,6 @@
|
|||||||
|
|
||||||
"@rollup/rollup-win32-x64-msvc": ["@rollup/[email protected]", "", { "os": "win32", "cpu": "x64" }, "sha512-zGIbEVVXVtauFgl3MRwGWEN36P5ZGenHRMgNw88X5wEhEBpq0XrMEZwOn07+ICrwM17XO5xfMZqh0OldCH5VTA=="],
|
"@rollup/rollup-win32-x64-msvc": ["@rollup/[email protected]", "", { "os": "win32", "cpu": "x64" }, "sha512-zGIbEVVXVtauFgl3MRwGWEN36P5ZGenHRMgNw88X5wEhEBpq0XrMEZwOn07+ICrwM17XO5xfMZqh0OldCH5VTA=="],
|
||||||
|
|
||||||
"@sapphire/async-queue": ["@sapphire/[email protected]", "", {}, "sha512-cvGzxbba6sav2zZkH8GPf2oGk9yYoD5qrNWdu9fRehifgnFZJMV+nuy2nON2roRO4yQQ+v7MK/Pktl/HgfsUXg=="],
|
|
||||||
|
|
||||||
"@sapphire/shapeshift": ["@sapphire/[email protected]", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "lodash": "^4.17.21" } }, "sha512-d9dUmWVA7MMiKobL3VpLF8P2aeanRTu6ypG2OIaEv/ZHH/SUQ2iHOVyi5wAPjQ+HmnMuL0whK9ez8I/raWbtIg=="],
|
|
||||||
|
|
||||||
"@sapphire/snowflake": ["@sapphire/[email protected]", "", {}, "sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ=="],
|
|
||||||
|
|
||||||
"@shikijs/core": ["@shikijs/[email protected]", "", { "dependencies": { "@shikijs/types": "3.13.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-3P8rGsg2Eh2qIHekwuQjzWhKI4jV97PhvYjYUzGqjvJfqdQPz+nMlfWahU24GZAyW1FxFI1sYjyhfh5CoLmIUA=="],
|
"@shikijs/core": ["@shikijs/[email protected]", "", { "dependencies": { "@shikijs/types": "3.13.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-3P8rGsg2Eh2qIHekwuQjzWhKI4jV97PhvYjYUzGqjvJfqdQPz+nMlfWahU24GZAyW1FxFI1sYjyhfh5CoLmIUA=="],
|
||||||
|
|
||||||
"@shikijs/engine-javascript": ["@shikijs/[email protected]", "", { "dependencies": { "@shikijs/types": "3.13.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.3" } }, "sha512-Ty7xv32XCp8u0eQt8rItpMs6rU9Ki6LJ1dQOW3V/56PKDcpvfHPnYFbsx5FFUP2Yim34m/UkazidamMNVR4vKg=="],
|
"@shikijs/engine-javascript": ["@shikijs/[email protected]", "", { "dependencies": { "@shikijs/types": "3.13.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.3" } }, "sha512-Ty7xv32XCp8u0eQt8rItpMs6rU9Ki6LJ1dQOW3V/56PKDcpvfHPnYFbsx5FFUP2Yim34m/UkazidamMNVR4vKg=="],
|
||||||
@@ -940,42 +875,10 @@
|
|||||||
|
|
||||||
"@shikijs/vscode-textmate": ["@shikijs/[email protected]", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="],
|
"@shikijs/vscode-textmate": ["@shikijs/[email protected]", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="],
|
||||||
|
|
||||||
"@shuding/opentype.js": ["@shuding/[email protected]", "", { "dependencies": { "fflate": "^0.7.3", "string.prototype.codepointat": "^0.2.1" }, "bin": { "ot": "bin/ot" } }, "sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA=="],
|
|
||||||
|
|
||||||
"@standard-schema/spec": ["@standard-schema/[email protected]", "", {}, "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA=="],
|
|
||||||
|
|
||||||
"@surma/rollup-plugin-off-main-thread": ["@surma/[email protected]", "", { "dependencies": { "ejs": "^3.1.6", "json5": "^2.2.0", "magic-string": "^0.25.0", "string.prototype.matchall": "^4.0.6" } }, "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ=="],
|
"@surma/rollup-plugin-off-main-thread": ["@surma/[email protected]", "", { "dependencies": { "ejs": "^3.1.6", "json5": "^2.2.0", "magic-string": "^0.25.0", "string.prototype.matchall": "^4.0.6" } }, "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ=="],
|
||||||
|
|
||||||
"@swc/helpers": ["@swc/[email protected]", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A=="],
|
"@swc/helpers": ["@swc/[email protected]", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A=="],
|
||||||
|
|
||||||
"@tauri-apps/api": ["@tauri-apps/[email protected]", "", {}, "sha512-ga7zdhbS2GXOMTIZRT0mYjKJtR9fivsXzsyq5U3vjDL0s6DTMwYRm0UHNjzTY5dh4+LSC68Sm/7WEiimbQNYlw=="],
|
|
||||||
|
|
||||||
"@tauri-apps/cli": ["@tauri-apps/[email protected]", "", { "optionalDependencies": { "@tauri-apps/cli-darwin-arm64": "2.8.4", "@tauri-apps/cli-darwin-x64": "2.8.4", "@tauri-apps/cli-linux-arm-gnueabihf": "2.8.4", "@tauri-apps/cli-linux-arm64-gnu": "2.8.4", "@tauri-apps/cli-linux-arm64-musl": "2.8.4", "@tauri-apps/cli-linux-riscv64-gnu": "2.8.4", "@tauri-apps/cli-linux-x64-gnu": "2.8.4", "@tauri-apps/cli-linux-x64-musl": "2.8.4", "@tauri-apps/cli-win32-arm64-msvc": "2.8.4", "@tauri-apps/cli-win32-ia32-msvc": "2.8.4", "@tauri-apps/cli-win32-x64-msvc": "2.8.4" }, "bin": { "tauri": "tauri.js" } }, "sha512-ejUZBzuQRcjFV+v/gdj/DcbyX/6T4unZQjMSBZwLzP/CymEjKcc2+Fc8xTORThebHDUvqoXMdsCZt8r+hyN15g=="],
|
|
||||||
|
|
||||||
"@tauri-apps/cli-darwin-arm64": ["@tauri-apps/[email protected]", "", { "os": "darwin", "cpu": "arm64" }, "sha512-BKu8HRkYV01SMTa7r4fLx+wjgtRK8Vep7lmBdHDioP6b8XH3q2KgsAyPWfEZaZIkZ2LY4SqqGARaE9oilNe0oA=="],
|
|
||||||
|
|
||||||
"@tauri-apps/cli-darwin-x64": ["@tauri-apps/[email protected]", "", { "os": "darwin", "cpu": "x64" }, "sha512-imb9PfSd/7G6VAO7v1bQ2A3ZH4NOCbhGJFLchxzepGcXf9NKkfun157JH9mko29K6sqAwuJ88qtzbKCbWJTH9g=="],
|
|
||||||
|
|
||||||
"@tauri-apps/cli-linux-arm-gnueabihf": ["@tauri-apps/[email protected]", "", { "os": "linux", "cpu": "arm" }, "sha512-Ml215UnDdl7/fpOrF1CNovym/KjtUbCuPgrcZ4IhqUCnhZdXuphud/JT3E8X97Y03TZ40Sjz8raXYI2ET0exzw=="],
|
|
||||||
|
|
||||||
"@tauri-apps/cli-linux-arm64-gnu": ["@tauri-apps/[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-pbcgBpMyI90C83CxE5REZ9ODyIlmmAPkkJXtV398X3SgZEIYy5TACYqlyyv2z5yKgD8F8WH4/2fek7+jH+ZXAw=="],
|
|
||||||
|
|
||||||
"@tauri-apps/cli-linux-arm64-musl": ["@tauri-apps/[email protected]", "", { "os": "linux", "cpu": "arm64" }, "sha512-zumFeaU1Ws5Ay872FTyIm7z8kfzEHu8NcIn8M6TxbJs0a7GRV21KBdpW1zNj2qy7HynnpQCqjAYXTUUmm9JAOw=="],
|
|
||||||
|
|
||||||
"@tauri-apps/cli-linux-riscv64-gnu": ["@tauri-apps/[email protected]", "", { "os": "linux", "cpu": "none" }, "sha512-qiqbB3Zz6IyO201f+1ojxLj65WYj8mixL5cOMo63nlg8CIzsP23cPYUrx1YaDPsCLszKZo7tVs14pc7BWf+/aQ=="],
|
|
||||||
|
|
||||||
"@tauri-apps/cli-linux-x64-gnu": ["@tauri-apps/[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-TaqaDd9Oy6k45Hotx3pOf+pkbsxLaApv4rGd9mLuRM1k6YS/aw81YrsMryYPThrxrScEIUcmNIHaHsLiU4GMkw=="],
|
|
||||||
|
|
||||||
"@tauri-apps/cli-linux-x64-musl": ["@tauri-apps/[email protected]", "", { "os": "linux", "cpu": "x64" }, "sha512-ot9STAwyezN8w+bBHZ+bqSQIJ0qPZFlz/AyscpGqB/JnJQVDFQcRDmUPFEaAtt2UUHSWzN3GoTJ5ypqLBp2WQA=="],
|
|
||||||
|
|
||||||
"@tauri-apps/cli-win32-arm64-msvc": ["@tauri-apps/[email protected]", "", { "os": "win32", "cpu": "arm64" }, "sha512-+2aJ/g90dhLiOLFSD1PbElXX3SoMdpO7HFPAZB+xot3CWlAZD1tReUFy7xe0L5GAR16ZmrxpIDM9v9gn5xRy/w=="],
|
|
||||||
|
|
||||||
"@tauri-apps/cli-win32-ia32-msvc": ["@tauri-apps/[email protected]", "", { "os": "win32", "cpu": "ia32" }, "sha512-yj7WDxkL1t9Uzr2gufQ1Hl7hrHuFKTNEOyascbc109EoiAqCp0tgZ2IykQqOZmZOHU884UAWI1pVMqBhS/BfhA=="],
|
|
||||||
|
|
||||||
"@tauri-apps/cli-win32-x64-msvc": ["@tauri-apps/[email protected]", "", { "os": "win32", "cpu": "x64" }, "sha512-XuvGB4ehBdd7QhMZ9qbj/8icGEatDuBNxyYHbLKsTYh90ggUlPa/AtaqcC1Fo69lGkTmq9BOKrs1aWSi7xDonA=="],
|
|
||||||
|
|
||||||
"@tauri-apps/plugin-opener": ["@tauri-apps/[email protected]", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-B0LShOYae4CZjN8leiNDbnfjSrTwoZakqKaWpfoH6nXiJwt6Rgj6RnVIffG3DoJiKsffRhMkjmBV9VeilSb4TA=="],
|
|
||||||
|
|
||||||
"@tokenizer/token": ["@tokenizer/[email protected]", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
|
"@tokenizer/token": ["@tokenizer/[email protected]", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
|
||||||
|
|
||||||
"@tootallnate/quickjs-emscripten": ["@tootallnate/[email protected]", "", {}, "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA=="],
|
"@tootallnate/quickjs-emscripten": ["@tootallnate/[email protected]", "", {}, "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA=="],
|
||||||
@@ -992,7 +895,7 @@
|
|||||||
|
|
||||||
"@types/babel__traverse": ["@types/[email protected]", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="],
|
"@types/babel__traverse": ["@types/[email protected]", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="],
|
||||||
|
|
||||||
"@types/bun": ["@types/[email protected].9", "", { "dependencies": { "bun-types": "1.3.9" } }, "sha512-KQ571yULOdWJiMH+RIWIOZ7B2RXQGpL1YQrBtLIV3FqDcCu6FsbFUBwhdKUlCKUpS3PJDsHlJ1QKlpxoVR+xtw=="],
|
"@types/bun": ["@types/[email protected].14", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="],
|
||||||
|
|
||||||
"@types/bytebuffer": ["@types/[email protected]", "", { "dependencies": { "@types/long": "^3.0.0", "@types/node": "*" } }, "sha512-lV4YLiolMdD4upDmr4vnfiwV/FN9Jg33eNTSFMkHqyMKqTIAn5TmFTYsARwXwUXeFU7yzRpECmWV1SOhIvdkRQ=="],
|
"@types/bytebuffer": ["@types/[email protected]", "", { "dependencies": { "@types/long": "^3.0.0", "@types/node": "*" } }, "sha512-lV4YLiolMdD4upDmr4vnfiwV/FN9Jg33eNTSFMkHqyMKqTIAn5TmFTYsARwXwUXeFU7yzRpECmWV1SOhIvdkRQ=="],
|
||||||
|
|
||||||
@@ -1018,8 +921,6 @@
|
|||||||
|
|
||||||
"@types/lz4js": ["@types/[email protected]", "", {}, "sha512-aAnbA4uKPNqZqu0XK1QAwKP0Wskb4Oa7ZFqxW5CMIyGgqYQKFgBxTfK3m3KODXoOLv5t14VregzgrEak13uGQA=="],
|
"@types/lz4js": ["@types/[email protected]", "", {}, "sha512-aAnbA4uKPNqZqu0XK1QAwKP0Wskb4Oa7ZFqxW5CMIyGgqYQKFgBxTfK3m3KODXoOLv5t14VregzgrEak13uGQA=="],
|
||||||
|
|
||||||
"@types/markdown-escape": ["@types/[email protected]", "", {}, "sha512-JIc1+s3y5ujKnt/+N+wq6s/QdL2qZ11fP79MijrVXsAAnzSxCbT2j/3prHRouJdZ2yFLN3vkP0HytfnoCczjOw=="],
|
|
||||||
|
|
||||||
"@types/mdast": ["@types/[email protected]", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="],
|
"@types/mdast": ["@types/[email protected]", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="],
|
||||||
|
|
||||||
"@types/ms": ["@types/[email protected]", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="],
|
"@types/ms": ["@types/[email protected]", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="],
|
||||||
@@ -1058,8 +959,6 @@
|
|||||||
|
|
||||||
"@types/webxr": ["@types/[email protected]", "", {}, "sha512-GPe4AsfOSpqWd3xA/0gwoKod13ChcfV67trvxaW2krUbgb9gxQjnCx8zGshzMl8LSHZlNH5gQ8LNScsDuc7nGQ=="],
|
"@types/webxr": ["@types/[email protected]", "", {}, "sha512-GPe4AsfOSpqWd3xA/0gwoKod13ChcfV67trvxaW2krUbgb9gxQjnCx8zGshzMl8LSHZlNH5gQ8LNScsDuc7nGQ=="],
|
||||||
|
|
||||||
"@types/ws": ["@types/[email protected]", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="],
|
|
||||||
|
|
||||||
"@types/yauzl": ["@types/[email protected]", "", { "dependencies": { "@types/node": "*" } }, "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q=="],
|
"@types/yauzl": ["@types/[email protected]", "", { "dependencies": { "@types/node": "*" } }, "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q=="],
|
||||||
|
|
||||||
"@ungap/structured-clone": ["@ungap/[email protected]", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="],
|
"@ungap/structured-clone": ["@ungap/[email protected]", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="],
|
||||||
@@ -1072,8 +971,6 @@
|
|||||||
|
|
||||||
"@vitejs/plugin-react": ["@vitejs/[email protected]", "", { "dependencies": { "@babel/core": "^7.28.0", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-beta.27", "@types/babel__core": "^7.20.5", "react-refresh": "^0.17.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA=="],
|
"@vitejs/plugin-react": ["@vitejs/[email protected]", "", { "dependencies": { "@babel/core": "^7.28.0", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-beta.27", "@types/babel__core": "^7.20.5", "react-refresh": "^0.17.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA=="],
|
||||||
|
|
||||||
"@vladfrangu/async_event_emitter": ["@vladfrangu/[email protected]", "", {}, "sha512-RaI5qZo6D2CVS6sTHFKg1v5Ohq/+Bo2LZ5gzUEwZ/WkHhwtGTCB/sVLw8ijOkAUxasZ+WshN/Rzj4ywsABJ5ZA=="],
|
|
||||||
|
|
||||||
"@volar/kit": ["@volar/[email protected]", "", { "dependencies": { "@volar/language-service": "2.4.23", "@volar/typescript": "2.4.23", "typesafe-path": "^0.2.2", "vscode-languageserver-textdocument": "^1.0.11", "vscode-uri": "^3.0.8" }, "peerDependencies": { "typescript": "*" } }, "sha512-YuUIzo9zwC2IkN7FStIcVl1YS9w5vkSFEZfPvnu0IbIMaR9WHhc9ZxvlT+91vrcSoRY469H2jwbrGqpG7m1KaQ=="],
|
"@volar/kit": ["@volar/[email protected]", "", { "dependencies": { "@volar/language-service": "2.4.23", "@volar/typescript": "2.4.23", "typesafe-path": "^0.2.2", "vscode-languageserver-textdocument": "^1.0.11", "vscode-uri": "^3.0.8" }, "peerDependencies": { "typescript": "*" } }, "sha512-YuUIzo9zwC2IkN7FStIcVl1YS9w5vkSFEZfPvnu0IbIMaR9WHhc9ZxvlT+91vrcSoRY469H2jwbrGqpG7m1KaQ=="],
|
||||||
|
|
||||||
"@volar/language-core": ["@volar/[email protected]", "", { "dependencies": { "@volar/source-map": "2.4.23" } }, "sha512-hEEd5ET/oSmBC6pi1j6NaNYRWoAiDhINbT8rmwtINugR39loROSlufGdYMF9TaKGfz+ViGs1Idi3mAhnuPcoGQ=="],
|
"@volar/language-core": ["@volar/[email protected]", "", { "dependencies": { "@volar/source-map": "2.4.23" } }, "sha512-hEEd5ET/oSmBC6pi1j6NaNYRWoAiDhINbT8rmwtINugR39loROSlufGdYMF9TaKGfz+ViGs1Idi3mAhnuPcoGQ=="],
|
||||||
@@ -1176,8 +1073,6 @@
|
|||||||
|
|
||||||
"before-after-hook": ["[email protected]", "", {}, "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ=="],
|
"before-after-hook": ["[email protected]", "", {}, "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ=="],
|
||||||
|
|
||||||
"bepaint": ["[email protected]", "", { "peerDependencies": { "@radix-ui/colors": "^0.1.8" } }, "sha512-rybuEo674bEal5QUm/qO9jok3TptyRH2bdHDheFO25fw+HCBic5Oiy+ZWnOFnROCGZQy2Zcw7po4KrKSxz02Pg=="],
|
|
||||||
|
|
||||||
"bidi-js": ["[email protected]", "", { "dependencies": { "require-from-string": "^2.0.2" } }, "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw=="],
|
"bidi-js": ["[email protected]", "", { "dependencies": { "require-from-string": "^2.0.2" } }, "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw=="],
|
||||||
|
|
||||||
"bignumber.js": ["[email protected]", "", {}, "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ=="],
|
"bignumber.js": ["[email protected]", "", {}, "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ=="],
|
||||||
@@ -1216,12 +1111,10 @@
|
|||||||
|
|
||||||
"buffer-from": ["[email protected]", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="],
|
"buffer-from": ["[email protected]", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="],
|
||||||
|
|
||||||
"bun-types": ["[email protected].9", "", { "dependencies": { "@types/node": "*" } }, "sha512-+UBWWOakIP4Tswh0Bt0QD0alpTY8cb5hvgiYeWCMet9YukHbzuruIEeXC2D7nMJPB12kbh8C7XJykSexEqGKJg=="],
|
"bun-types": ["[email protected].14", "", { "dependencies": { "@types/node": "*" } }, "sha512-4N0ig0fEomHt5R0KCFWjovxow98rIoRwKolrYdCcknNwMekCXRnWEUvgu5soYV8QXtVsrUD8B95MBOZGPvr6KQ=="],
|
||||||
|
|
||||||
"bytebuffer": ["[email protected]", "", { "dependencies": { "long": "~3" } }, "sha512-IuzSdmADppkZ6DlpycMkm8l9zeEq16fWtLvunEwFiYciR/BHo4E8/xs5piFquG+Za8OWmMqHF8zuRviz2LHvRQ=="],
|
"bytebuffer": ["[email protected]", "", { "dependencies": { "long": "~3" } }, "sha512-IuzSdmADppkZ6DlpycMkm8l9zeEq16fWtLvunEwFiYciR/BHo4E8/xs5piFquG+Za8OWmMqHF8zuRviz2LHvRQ=="],
|
||||||
|
|
||||||
"c12": ["[email protected]", "", { "dependencies": { "chokidar": "^4.0.3", "confbox": "^0.2.2", "defu": "^6.1.4", "dotenv": "^16.6.1", "exsolve": "^1.0.7", "giget": "^2.0.0", "jiti": "^2.4.2", "ohash": "^2.0.11", "pathe": "^2.0.3", "perfect-debounce": "^1.0.0", "pkg-types": "^2.2.0", "rc9": "^2.1.2" }, "peerDependencies": { "magicast": "^0.3.5" }, "optionalPeers": ["magicast"] }, "sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw=="],
|
|
||||||
|
|
||||||
"call-bind": ["[email protected]", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.2" } }, "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww=="],
|
"call-bind": ["[email protected]", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.2" } }, "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww=="],
|
||||||
|
|
||||||
"call-bind-apply-helpers": ["[email protected]", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
|
"call-bind-apply-helpers": ["[email protected]", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
|
||||||
@@ -1232,8 +1125,6 @@
|
|||||||
|
|
||||||
"camelcase": ["[email protected]", "", {}, "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA=="],
|
"camelcase": ["[email protected]", "", {}, "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA=="],
|
||||||
|
|
||||||
"camelize": ["[email protected]", "", {}, "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ=="],
|
|
||||||
|
|
||||||
"camera-controls": ["[email protected]", "", { "peerDependencies": { "three": ">=0.126.1" } }, "sha512-w5oULNpijgTRH0ARFJJ0R5ct1nUM3R3WP7/b8A6j9uTGpRfnsypc/RBMPQV8JQDPayUe37p/TZZY1PcUr4czOQ=="],
|
"camera-controls": ["[email protected]", "", { "peerDependencies": { "three": ">=0.126.1" } }, "sha512-w5oULNpijgTRH0ARFJJ0R5ct1nUM3R3WP7/b8A6j9uTGpRfnsypc/RBMPQV8JQDPayUe37p/TZZY1PcUr4czOQ=="],
|
||||||
|
|
||||||
"caniuse-lite": ["[email protected]", "", {}, "sha512-ywt6i8FzvdgrrrGbr1jZVObnVv6adj+0if2/omv9cmR2oiZs30zL4DIyaptKcbOrBdOIc74QTMoJvSE2QHh5UQ=="],
|
"caniuse-lite": ["[email protected]", "", {}, "sha512-ywt6i8FzvdgrrrGbr1jZVObnVv6adj+0if2/omv9cmR2oiZs30zL4DIyaptKcbOrBdOIc74QTMoJvSE2QHh5UQ=="],
|
||||||
@@ -1260,8 +1151,6 @@
|
|||||||
|
|
||||||
"ci-info": ["[email protected]", "", {}, "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ=="],
|
"ci-info": ["[email protected]", "", {}, "sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ=="],
|
||||||
|
|
||||||
"citty": ["[email protected]", "", { "dependencies": { "consola": "^3.2.3" } }, "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ=="],
|
|
||||||
|
|
||||||
"classnames": ["[email protected]", "", {}, "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow=="],
|
"classnames": ["[email protected]", "", {}, "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow=="],
|
||||||
|
|
||||||
"cli-boxes": ["[email protected]", "", {}, "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g=="],
|
"cli-boxes": ["[email protected]", "", {}, "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g=="],
|
||||||
@@ -1292,10 +1181,6 @@
|
|||||||
|
|
||||||
"concat-map": ["[email protected]", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
|
"concat-map": ["[email protected]", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
|
||||||
|
|
||||||
"confbox": ["[email protected]", "", {}, "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ=="],
|
|
||||||
|
|
||||||
"consola": ["[email protected]", "", {}, "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA=="],
|
|
||||||
|
|
||||||
"convert-source-map": ["[email protected]", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="],
|
"convert-source-map": ["[email protected]", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="],
|
||||||
|
|
||||||
"cookie": ["[email protected]", "", {}, "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA=="],
|
"cookie": ["[email protected]", "", {}, "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA=="],
|
||||||
@@ -1318,18 +1203,8 @@
|
|||||||
|
|
||||||
"crypto-random-string": ["[email protected]", "", {}, "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA=="],
|
"crypto-random-string": ["[email protected]", "", {}, "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA=="],
|
||||||
|
|
||||||
"css-background-parser": ["[email protected]", "", {}, "sha512-2EZLisiZQ+7m4wwur/qiYJRniHX4K5Tc9w93MT3AS0WS1u5kaZ4FKXlOTBhOjc+CgEgPiGY+fX1yWD8UwpEqUA=="],
|
|
||||||
|
|
||||||
"css-box-shadow": ["[email protected]", "", {}, "sha512-9jaqR6e7Ohds+aWwmhe6wILJ99xYQbfmK9QQB9CcMjDbTxPZjwEmUQpU91OG05Xgm8BahT5fW+svbsQGjS/zPg=="],
|
|
||||||
|
|
||||||
"css-color-keywords": ["[email protected]", "", {}, "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg=="],
|
|
||||||
|
|
||||||
"css-gradient-parser": ["[email protected]", "", {}, "sha512-w2Xy9UMMwlKtou0vlRnXvWglPAceXCTtcmVSo8ZBUvqCV5aXEFP/PC6d+I464810I9FT++UACwTD5511bmGPUg=="],
|
|
||||||
|
|
||||||
"css-select": ["[email protected]", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="],
|
"css-select": ["[email protected]", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="],
|
||||||
|
|
||||||
"css-to-react-native": ["[email protected]", "", { "dependencies": { "camelize": "^1.0.0", "css-color-keywords": "^1.0.0", "postcss-value-parser": "^4.0.2" } }, "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ=="],
|
|
||||||
|
|
||||||
"css-tree": ["[email protected]", "", { "dependencies": { "mdn-data": "2.12.2", "source-map-js": "^1.0.1" } }, "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w=="],
|
"css-tree": ["[email protected]", "", { "dependencies": { "mdn-data": "2.12.2", "source-map-js": "^1.0.1" } }, "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w=="],
|
||||||
|
|
||||||
"css-what": ["[email protected]", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="],
|
"css-what": ["[email protected]", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="],
|
||||||
@@ -1368,8 +1243,6 @@
|
|||||||
|
|
||||||
"deepmerge": ["[email protected]", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="],
|
"deepmerge": ["[email protected]", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="],
|
||||||
|
|
||||||
"deepmerge-ts": ["[email protected]", "", {}, "sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw=="],
|
|
||||||
|
|
||||||
"define-data-property": ["[email protected]", "", { "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" } }, "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A=="],
|
"define-data-property": ["[email protected]", "", { "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" } }, "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A=="],
|
||||||
|
|
||||||
"define-properties": ["[email protected]", "", { "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg=="],
|
"define-properties": ["[email protected]", "", { "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg=="],
|
||||||
@@ -1402,10 +1275,6 @@
|
|||||||
|
|
||||||
"diff": ["[email protected]", "", {}, "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A=="],
|
"diff": ["[email protected]", "", {}, "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A=="],
|
||||||
|
|
||||||
"discord-api-types": ["[email protected]", "", {}, "sha512-XRdDQvZvID1XvcFftjSmd4dcmMi/RL/jSy5sduBDAvCGFcNFHThdIQXCEBDZFe52lCNEzuIL0QJoKYAmRmxLUA=="],
|
|
||||||
|
|
||||||
"discord.js": ["[email protected]", "", { "dependencies": { "@discordjs/builders": "^1.13.0", "@discordjs/collection": "1.5.3", "@discordjs/formatters": "^0.6.2", "@discordjs/rest": "^2.6.0", "@discordjs/util": "^1.2.0", "@discordjs/ws": "^1.2.3", "@sapphire/snowflake": "3.5.3", "discord-api-types": "^0.38.33", "fast-deep-equal": "3.1.3", "lodash.snakecase": "4.1.1", "magic-bytes.js": "^1.10.0", "tslib": "^2.6.3", "undici": "6.21.3" } }, "sha512-2l0gsPOLPs5t6GFZfQZKnL1OJNYFcuC/ETWsW4VtKVD/tg4ICa9x+jb9bkPffkMdRpRpuUaO/fKkHCBeiCKh8g=="],
|
|
||||||
|
|
||||||
"dlv": ["[email protected]", "", {}, "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="],
|
"dlv": ["[email protected]", "", {}, "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="],
|
||||||
|
|
||||||
"dom-serializer": ["[email protected]", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="],
|
"dom-serializer": ["[email protected]", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="],
|
||||||
@@ -1430,8 +1299,6 @@
|
|||||||
|
|
||||||
"ee-first": ["[email protected]", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="],
|
"ee-first": ["[email protected]", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="],
|
||||||
|
|
||||||
"effect": ["[email protected]", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "fast-check": "^3.23.1" } }, "sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA=="],
|
|
||||||
|
|
||||||
"ejs": ["[email protected]", "", { "dependencies": { "jake": "^10.8.5" }, "bin": { "ejs": "bin/cli.js" } }, "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA=="],
|
"ejs": ["[email protected]", "", { "dependencies": { "jake": "^10.8.5" }, "bin": { "ejs": "bin/cli.js" } }, "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA=="],
|
||||||
|
|
||||||
"electron-to-chromium": ["[email protected]", "", {}, "sha512-Oiv6+nGcMg0xuSUeYumk+eE0pDk0PuQ6Gnz16pErrPtlitaFZxq95hUtvGRg90kcJ/AdsM+AW5VkVUl3fGk+SQ=="],
|
"electron-to-chromium": ["[email protected]", "", {}, "sha512-Oiv6+nGcMg0xuSUeYumk+eE0pDk0PuQ6Gnz16pErrPtlitaFZxq95hUtvGRg90kcJ/AdsM+AW5VkVUl3fGk+SQ=="],
|
||||||
@@ -1440,10 +1307,6 @@
|
|||||||
|
|
||||||
"emoji-regex": ["[email protected]", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
"emoji-regex": ["[email protected]", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
||||||
|
|
||||||
"emoji-regex-xs": ["[email protected]", "", {}, "sha512-1QFuh8l7LqUcKe24LsPUNzjrzJQ7pgRwp1QMcZ5MX6mFplk2zQ08NVCM84++1cveaUUYtcCYHmeFEuNg16sU4g=="],
|
|
||||||
|
|
||||||
"empathic": ["[email protected]", "", {}, "sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA=="],
|
|
||||||
|
|
||||||
"encodeurl": ["[email protected]", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="],
|
"encodeurl": ["[email protected]", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="],
|
||||||
|
|
||||||
"encoding-sniffer": ["[email protected]", "", { "dependencies": { "iconv-lite": "^0.6.3", "whatwg-encoding": "^3.1.1" } }, "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw=="],
|
"encoding-sniffer": ["[email protected]", "", { "dependencies": { "iconv-lite": "^0.6.3", "whatwg-encoding": "^3.1.1" } }, "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw=="],
|
||||||
@@ -1500,17 +1363,13 @@
|
|||||||
|
|
||||||
"exif-parser": ["[email protected]", "", {}, "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw=="],
|
"exif-parser": ["[email protected]", "", {}, "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw=="],
|
||||||
|
|
||||||
"exsolve": ["[email protected]", "", {}, "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw=="],
|
|
||||||
|
|
||||||
"extend": ["[email protected]", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="],
|
"extend": ["[email protected]", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="],
|
||||||
|
|
||||||
"extract-zip": ["[email protected]", "", { "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0", "yauzl": "^2.10.0" }, "optionalDependencies": { "@types/yauzl": "^2.9.1" }, "bin": { "extract-zip": "cli.js" } }, "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg=="],
|
"extract-zip": ["[email protected]", "", { "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0", "yauzl": "^2.10.0" }, "optionalDependencies": { "@types/yauzl": "^2.9.1" }, "bin": { "extract-zip": "cli.js" } }, "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg=="],
|
||||||
|
|
||||||
"fast-check": ["[email protected]", "", { "dependencies": { "pure-rand": "^6.1.0" } }, "sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A=="],
|
|
||||||
|
|
||||||
"fast-content-type-parse": ["[email protected]", "", {}, "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg=="],
|
"fast-content-type-parse": ["[email protected]", "", {}, "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg=="],
|
||||||
|
|
||||||
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
|
"fast-deep-equal": ["fast-deep-equal@2.0.1", "", {}, "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w=="],
|
||||||
|
|
||||||
"fast-fifo": ["[email protected]", "", {}, "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ=="],
|
"fast-fifo": ["[email protected]", "", {}, "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ=="],
|
||||||
|
|
||||||
@@ -1596,8 +1455,6 @@
|
|||||||
|
|
||||||
"gifwrap": ["[email protected]", "", { "dependencies": { "image-q": "^4.0.0", "omggif": "^1.0.10" } }, "sha512-2760b1vpJHNmLzZ/ubTtNnEx5WApN/PYWJvXvgS+tL1egTTthayFYIQQNi136FLEDcN/IyEY2EcGpIITD6eYUw=="],
|
"gifwrap": ["[email protected]", "", { "dependencies": { "image-q": "^4.0.0", "omggif": "^1.0.10" } }, "sha512-2760b1vpJHNmLzZ/ubTtNnEx5WApN/PYWJvXvgS+tL1egTTthayFYIQQNi136FLEDcN/IyEY2EcGpIITD6eYUw=="],
|
||||||
|
|
||||||
"giget": ["[email protected]", "", { "dependencies": { "citty": "^0.1.6", "consola": "^3.4.0", "defu": "^6.1.4", "node-fetch-native": "^1.6.6", "nypm": "^0.6.0", "pathe": "^2.0.3" }, "bin": { "giget": "dist/cli.mjs" } }, "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA=="],
|
|
||||||
|
|
||||||
"github-slugger": ["[email protected]", "", {}, "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="],
|
"github-slugger": ["[email protected]", "", {}, "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="],
|
||||||
|
|
||||||
"glob": ["[email protected]", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
|
"glob": ["[email protected]", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
|
||||||
@@ -1656,8 +1513,6 @@
|
|||||||
|
|
||||||
"hastscript": ["[email protected]", "", { "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-parse-selector": "^4.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0" } }, "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w=="],
|
"hastscript": ["[email protected]", "", { "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-parse-selector": "^4.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0" } }, "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w=="],
|
||||||
|
|
||||||
"hex-rgb": ["[email protected]", "", {}, "sha512-Ox1pJVrDCyGHMG9CFg1tmrRUMRPRsAWYc/PinY0XzJU4K7y7vjNoLKIQ7BR5UJMCxNN8EM1MNDmHWA/B3aZUuw=="],
|
|
||||||
|
|
||||||
"hls.js": ["[email protected]", "", {}, "sha512-hNEzjZNHf5bFrUNvdS4/1RjIanuJ6szpWNfTaX5I6WfGynWXGT7K/YQLYtemSvFExzeMdgdE4SsyVLJbd5PcZA=="],
|
"hls.js": ["[email protected]", "", {}, "sha512-hNEzjZNHf5bFrUNvdS4/1RjIanuJ6szpWNfTaX5I6WfGynWXGT7K/YQLYtemSvFExzeMdgdE4SsyVLJbd5PcZA=="],
|
||||||
|
|
||||||
"html-escaper": ["[email protected]", "", {}, "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ=="],
|
"html-escaper": ["[email protected]", "", {}, "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ=="],
|
||||||
@@ -1828,8 +1683,6 @@
|
|||||||
|
|
||||||
"lie": ["[email protected]", "", { "dependencies": { "immediate": "~3.0.5" } }, "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ=="],
|
"lie": ["[email protected]", "", { "dependencies": { "immediate": "~3.0.5" } }, "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ=="],
|
||||||
|
|
||||||
"linebreak": ["[email protected]", "", { "dependencies": { "base64-js": "0.0.8", "unicode-trie": "^2.0.0" } }, "sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ=="],
|
|
||||||
|
|
||||||
"lines-and-columns": ["[email protected]", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="],
|
"lines-and-columns": ["[email protected]", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="],
|
||||||
|
|
||||||
"lodash": ["[email protected]", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="],
|
"lodash": ["[email protected]", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="],
|
||||||
@@ -1838,8 +1691,6 @@
|
|||||||
|
|
||||||
"lodash.debounce": ["[email protected]", "", {}, "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="],
|
"lodash.debounce": ["[email protected]", "", {}, "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="],
|
||||||
|
|
||||||
"lodash.snakecase": ["[email protected]", "", {}, "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw=="],
|
|
||||||
|
|
||||||
"lodash.sortby": ["[email protected]", "", {}, "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA=="],
|
"lodash.sortby": ["[email protected]", "", {}, "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA=="],
|
||||||
|
|
||||||
"long": ["[email protected]", "", {}, "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="],
|
"long": ["[email protected]", "", {}, "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="],
|
||||||
@@ -1848,22 +1699,20 @@
|
|||||||
|
|
||||||
"lru-cache": ["[email protected]", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
|
"lru-cache": ["[email protected]", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
|
||||||
|
|
||||||
|
"lz4-napi": ["[email protected]", "", { "optionalDependencies": { "@antoniomuso/lz4-napi-android-arm-eabi": "2.9.1", "@antoniomuso/lz4-napi-android-arm64": "2.9.1", "@antoniomuso/lz4-napi-darwin-arm64": "2.9.1", "@antoniomuso/lz4-napi-darwin-x64": "2.9.1", "@antoniomuso/lz4-napi-freebsd-x64": "2.9.1", "@antoniomuso/lz4-napi-linux-arm-gnueabihf": "2.9.1", "@antoniomuso/lz4-napi-linux-arm64-gnu": "2.9.1", "@antoniomuso/lz4-napi-linux-arm64-musl": "2.9.1", "@antoniomuso/lz4-napi-linux-ppc64-gnu": "2.9.1", "@antoniomuso/lz4-napi-linux-riscv64-gnu": "2.9.1", "@antoniomuso/lz4-napi-linux-s390x-gnu": "2.9.1", "@antoniomuso/lz4-napi-linux-x64-gnu": "2.9.1", "@antoniomuso/lz4-napi-linux-x64-musl": "2.9.1", "@antoniomuso/lz4-napi-openharmony-arm64": "2.9.1", "@antoniomuso/lz4-napi-win32-arm64-msvc": "2.9.1", "@antoniomuso/lz4-napi-win32-ia32-msvc": "2.9.1", "@antoniomuso/lz4-napi-win32-x64-msvc": "2.9.1" } }, "sha512-VjY1TAUQa3bo8j4vCcpQ0RBXh4mbC1OFHWH9rpOvx8qLYwaZTEzwxW/648ufD2cmz5/pFfPLDkX6N8+TqI9BYQ=="],
|
||||||
|
|
||||||
"lz4js": ["[email protected]", "", {}, "sha512-gY2Ia9Lm7Ep8qMiuGRhvUq0Q7qUereeldZPP1PMEJxPtEWHJLqw9pgX68oHajBH0nzJK4MaZEA/YNV3jT8u8Bg=="],
|
"lz4js": ["[email protected]", "", {}, "sha512-gY2Ia9Lm7Ep8qMiuGRhvUq0Q7qUereeldZPP1PMEJxPtEWHJLqw9pgX68oHajBH0nzJK4MaZEA/YNV3jT8u8Bg=="],
|
||||||
|
|
||||||
"lzma": ["[email protected]", "", { "bin": { "lzma.js": "bin/lzma.js" } }, "sha512-DcfiawQ1avYbW+hsILhF38IKAlnguc/fjHrychs9hdxe4qLykvhT5VTGNs5YRWgaNePh7NTxGD4uv4gKsRomCQ=="],
|
"lzma": ["[email protected]", "", { "bin": { "lzma.js": "bin/lzma.js" } }, "sha512-DcfiawQ1avYbW+hsILhF38IKAlnguc/fjHrychs9hdxe4qLykvhT5VTGNs5YRWgaNePh7NTxGD4uv4gKsRomCQ=="],
|
||||||
|
|
||||||
"maath": ["[email protected]", "", { "peerDependencies": { "@types/three": ">=0.134.0", "three": ">=0.134.0" } }, "sha512-tRvbDF0Pgqz+9XUa4jjfgAQ8/aPKmQdWXilFu2tMy4GWj4NOsx99HlULO4IeREfbO3a0sA145DZYyvXPkybm0g=="],
|
"maath": ["[email protected]", "", { "peerDependencies": { "@types/three": ">=0.134.0", "three": ">=0.134.0" } }, "sha512-tRvbDF0Pgqz+9XUa4jjfgAQ8/aPKmQdWXilFu2tMy4GWj4NOsx99HlULO4IeREfbO3a0sA145DZYyvXPkybm0g=="],
|
||||||
|
|
||||||
"magic-bytes.js": ["[email protected]", "", {}, "sha512-ThQLOhN86ZkJ7qemtVRGYM+gRgR8GEXNli9H/PMvpnZsE44Xfh3wx9kGJaldg314v85m+bFW6WBMaVHJc/c3zA=="],
|
|
||||||
|
|
||||||
"magic-string": ["[email protected]", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw=="],
|
"magic-string": ["[email protected]", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw=="],
|
||||||
|
|
||||||
"magicast": ["[email protected]", "", { "dependencies": { "@babel/parser": "^7.25.4", "@babel/types": "^7.25.4", "source-map-js": "^1.2.0" } }, "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ=="],
|
"magicast": ["[email protected]", "", { "dependencies": { "@babel/parser": "^7.25.4", "@babel/types": "^7.25.4", "source-map-js": "^1.2.0" } }, "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ=="],
|
||||||
|
|
||||||
"make-dir": ["[email protected]", "", { "dependencies": { "pify": "^3.0.0" } }, "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ=="],
|
"make-dir": ["[email protected]", "", { "dependencies": { "pify": "^3.0.0" } }, "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ=="],
|
||||||
|
|
||||||
"markdown-escape": ["[email protected]", "", {}, "sha512-Trz4v0+XWlwy68LJIyw3bLbsJiC8XAbRCKF9DbEtZjyndKOGVx6n+wNB0VfoRmY2LKboQLeniap3xrb6LGSJ8A=="],
|
|
||||||
|
|
||||||
"markdown-table": ["[email protected]", "", {}, "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw=="],
|
"markdown-table": ["[email protected]", "", {}, "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw=="],
|
||||||
|
|
||||||
"markdown-to-jsx": ["[email protected]", "", { "peerDependencies": { "react": ">= 0.14.0" } }, "sha512-DiueEq2bttFcSxUs85GJcQVrOr0+VVsPfj9AEUPqmExJ3f8P/iQNvZHltV4tm1XVhu1kl0vWBZWT3l99izRMaA=="],
|
"markdown-to-jsx": ["[email protected]", "", { "peerDependencies": { "react": ">= 0.14.0" } }, "sha512-DiueEq2bttFcSxUs85GJcQVrOr0+VVsPfj9AEUPqmExJ3f8P/iQNvZHltV4tm1XVhu1kl0vWBZWT3l99izRMaA=="],
|
||||||
@@ -2010,8 +1859,6 @@
|
|||||||
|
|
||||||
"nth-check": ["[email protected]", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="],
|
"nth-check": ["[email protected]", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="],
|
||||||
|
|
||||||
"nypm": ["[email protected]", "", { "dependencies": { "citty": "^0.1.6", "consola": "^3.4.2", "pathe": "^2.0.3", "pkg-types": "^2.3.0", "tinyexec": "^1.0.1" }, "bin": { "nypm": "dist/cli.mjs" } }, "sha512-7eM+hpOtrKrBDCh7Ypu2lJ9Z7PNZBdi/8AT3AX8xoCj43BBVHD0hPSTEvMtkMpfs8FCqBGhxB+uToIQimA111g=="],
|
|
||||||
|
|
||||||
"object-assign": ["[email protected]", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
|
"object-assign": ["[email protected]", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
|
||||||
|
|
||||||
"object-inspect": ["[email protected]", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="],
|
"object-inspect": ["[email protected]", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="],
|
||||||
@@ -2058,8 +1905,6 @@
|
|||||||
|
|
||||||
"parse-bmfont-xml": ["[email protected]", "", { "dependencies": { "xml-parse-from-string": "^1.0.0", "xml2js": "^0.5.0" } }, "sha512-0cEliVMZEhrFDwMh4SxIyVJpqYoOWDJ9P895tFuS+XuNzI5UBmBk5U5O4KuJdTnZpSBI4LFA2+ZiJaiwfSwlMA=="],
|
"parse-bmfont-xml": ["[email protected]", "", { "dependencies": { "xml-parse-from-string": "^1.0.0", "xml2js": "^0.5.0" } }, "sha512-0cEliVMZEhrFDwMh4SxIyVJpqYoOWDJ9P895tFuS+XuNzI5UBmBk5U5O4KuJdTnZpSBI4LFA2+ZiJaiwfSwlMA=="],
|
||||||
|
|
||||||
"parse-css-color": ["[email protected]", "", { "dependencies": { "color-name": "^1.1.4", "hex-rgb": "^4.1.0" } }, "sha512-bwS/GGIFV3b6KS4uwpzCFj4w297Yl3uqnSgIPsoQkx7GMLROXfMnWvxfNkL0oh8HVhZA4hvJoEoEIqonfJ3BWg=="],
|
|
||||||
|
|
||||||
"parse-json": ["[email protected]", "", { "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg=="],
|
"parse-json": ["[email protected]", "", { "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg=="],
|
||||||
|
|
||||||
"parse-latin": ["[email protected]", "", { "dependencies": { "@types/nlcst": "^2.0.0", "@types/unist": "^3.0.0", "nlcst-to-string": "^4.0.0", "unist-util-modify-children": "^4.0.0", "unist-util-visit-children": "^3.0.0", "vfile": "^6.0.0" } }, "sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ=="],
|
"parse-latin": ["[email protected]", "", { "dependencies": { "@types/nlcst": "^2.0.0", "@types/unist": "^3.0.0", "nlcst-to-string": "^4.0.0", "unist-util-modify-children": "^4.0.0", "unist-util-visit-children": "^3.0.0", "vfile": "^6.0.0" } }, "sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ=="],
|
||||||
@@ -2078,14 +1923,10 @@
|
|||||||
|
|
||||||
"path-parse": ["[email protected]", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="],
|
"path-parse": ["[email protected]", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="],
|
||||||
|
|
||||||
"pathe": ["[email protected]", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="],
|
|
||||||
|
|
||||||
"peek-readable": ["[email protected]", "", {}, "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg=="],
|
"peek-readable": ["[email protected]", "", {}, "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg=="],
|
||||||
|
|
||||||
"pend": ["[email protected]", "", {}, "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="],
|
"pend": ["[email protected]", "", {}, "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="],
|
||||||
|
|
||||||
"perfect-debounce": ["[email protected]", "", {}, "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA=="],
|
|
||||||
|
|
||||||
"permessage-deflate": ["[email protected]", "", { "dependencies": { "safe-buffer": "*" } }, "sha512-EUNi/RIsyJ1P1u9QHFwMOUWMYetqlE22ZgGbad7YP856WF4BFF0B7DuNy6vEGsgNNud6c/SkdWzkne71hH8MjA=="],
|
"permessage-deflate": ["[email protected]", "", { "dependencies": { "safe-buffer": "*" } }, "sha512-EUNi/RIsyJ1P1u9QHFwMOUWMYetqlE22ZgGbad7YP856WF4BFF0B7DuNy6vEGsgNNud6c/SkdWzkne71hH8MjA=="],
|
||||||
|
|
||||||
"pickleparser": ["[email protected]", "", { "bin": { "pickletojson": "bin/pickletojson.js", "pickleparser": "bin/pickletojson.js" } }, "sha512-kMzY3uFYcR6OjOqr7nV2nkaXaBsUEOafu3zgPxeD6s/2ueMfVQH8lrymcDWBPGx0OkVxGMikxQit6jgByXjwBg=="],
|
"pickleparser": ["[email protected]", "", { "bin": { "pickletojson": "bin/pickletojson.js", "pickleparser": "bin/pickletojson.js" } }, "sha512-kMzY3uFYcR6OjOqr7nV2nkaXaBsUEOafu3zgPxeD6s/2ueMfVQH8lrymcDWBPGx0OkVxGMikxQit6jgByXjwBg=="],
|
||||||
@@ -2102,24 +1943,18 @@
|
|||||||
|
|
||||||
"pixelmatch": ["[email protected]", "", { "dependencies": { "pngjs": "^6.0.0" }, "bin": { "pixelmatch": "bin/pixelmatch" } }, "sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q=="],
|
"pixelmatch": ["[email protected]", "", { "dependencies": { "pngjs": "^6.0.0" }, "bin": { "pixelmatch": "bin/pixelmatch" } }, "sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q=="],
|
||||||
|
|
||||||
"pkg-types": ["[email protected]", "", { "dependencies": { "confbox": "^0.2.2", "exsolve": "^1.0.7", "pathe": "^2.0.3" } }, "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig=="],
|
|
||||||
|
|
||||||
"pngjs": ["[email protected]", "", {}, "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow=="],
|
"pngjs": ["[email protected]", "", {}, "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow=="],
|
||||||
|
|
||||||
"possible-typed-array-names": ["[email protected]", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="],
|
"possible-typed-array-names": ["[email protected]", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="],
|
||||||
|
|
||||||
"postcss": ["[email protected]", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
|
"postcss": ["[email protected]", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
|
||||||
|
|
||||||
"postcss-value-parser": ["[email protected]", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="],
|
|
||||||
|
|
||||||
"potpack": ["[email protected]", "", {}, "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ=="],
|
"potpack": ["[email protected]", "", {}, "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ=="],
|
||||||
|
|
||||||
"prettier": ["[email protected]", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="],
|
"prettier": ["[email protected]", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="],
|
||||||
|
|
||||||
"pretty-bytes": ["[email protected]", "", {}, "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ=="],
|
"pretty-bytes": ["[email protected]", "", {}, "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ=="],
|
||||||
|
|
||||||
"prisma": ["[email protected]", "", { "dependencies": { "@prisma/config": "6.18.0", "@prisma/engines": "6.18.0" }, "peerDependencies": { "typescript": ">=5.1.0" }, "optionalPeers": ["typescript"], "bin": { "prisma": "build/index.js" } }, "sha512-bXWy3vTk8mnRmT+SLyZBQoC2vtV9Z8u7OHvEu+aULYxwiop/CPiFZ+F56KsNRNf35jw+8wcu8pmLsjxpBxAO9g=="],
|
|
||||||
|
|
||||||
"prismjs": ["[email protected]", "", {}, "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="],
|
"prismjs": ["[email protected]", "", {}, "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="],
|
||||||
|
|
||||||
"process": ["[email protected]", "", {}, "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="],
|
"process": ["[email protected]", "", {}, "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="],
|
||||||
@@ -2132,7 +1967,7 @@
|
|||||||
|
|
||||||
"prompts": ["[email protected]", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="],
|
"prompts": ["[email protected]", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="],
|
||||||
|
|
||||||
"property-graph": ["property-graph@3.0.0", "", {}, "sha512-TnzxUsttmGtw+OiU0LDw+0FlMbJ8vV8pOjyDI7+Kdni4Tj0hW5BFh7TatQu7Y68hcvvFmiFOHilKShsA4R82fA=="],
|
"property-graph": ["property-graph@4.1.0", "", {}, "sha512-AvPcP7XECNWy4LGmFQ77k7un4lSKM4eS29PTvW4ck95uYeLxXPWJM7hLuBqK91FaHqCcgJvIUCuNJjjxKE7VKQ=="],
|
||||||
|
|
||||||
"property-information": ["[email protected]", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="],
|
"property-information": ["[email protected]", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="],
|
||||||
|
|
||||||
@@ -2152,8 +1987,6 @@
|
|||||||
|
|
||||||
"puppeteer-core": ["[email protected]", "", { "dependencies": { "@puppeteer/browsers": "2.10.10", "chromium-bidi": "9.1.0", "debug": "^4.4.3", "devtools-protocol": "0.0.1495869", "typed-query-selector": "^2.12.0", "webdriver-bidi-protocol": "0.2.11", "ws": "^8.18.3" } }, "sha512-M/Jhg4PWRANSbL/C9im//Yb55wsWBS5wdp+h59iwM+EPicVQQCNs56iC5aEAO7avfDPRfxs4MM16wHjOYHNJEw=="],
|
"puppeteer-core": ["[email protected]", "", { "dependencies": { "@puppeteer/browsers": "2.10.10", "chromium-bidi": "9.1.0", "debug": "^4.4.3", "devtools-protocol": "0.0.1495869", "typed-query-selector": "^2.12.0", "webdriver-bidi-protocol": "0.2.11", "ws": "^8.18.3" } }, "sha512-M/Jhg4PWRANSbL/C9im//Yb55wsWBS5wdp+h59iwM+EPicVQQCNs56iC5aEAO7avfDPRfxs4MM16wHjOYHNJEw=="],
|
||||||
|
|
||||||
"pure-rand": ["[email protected]", "", {}, "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA=="],
|
|
||||||
|
|
||||||
"pwa-install-handler": ["[email protected]", "", {}, "sha512-F6/Q4emNJyh/kHLYF0fn5NTKQszvpEJh2oWQLtQED8q46+c23dfppSB3nRF1O99/5cxmc3FRVpLSZ7NE5l0DoA=="],
|
"pwa-install-handler": ["[email protected]", "", {}, "sha512-F6/Q4emNJyh/kHLYF0fn5NTKQszvpEJh2oWQLtQED8q46+c23dfppSB3nRF1O99/5cxmc3FRVpLSZ7NE5l0DoA=="],
|
||||||
|
|
||||||
"qs": ["[email protected]", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w=="],
|
"qs": ["[email protected]", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w=="],
|
||||||
@@ -2170,8 +2003,6 @@
|
|||||||
|
|
||||||
"range-parser": ["[email protected]", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="],
|
"range-parser": ["[email protected]", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="],
|
||||||
|
|
||||||
"rc9": ["[email protected]", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="],
|
|
||||||
|
|
||||||
"react": ["[email protected]", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="],
|
"react": ["[email protected]", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="],
|
||||||
|
|
||||||
"react-dom": ["[email protected]", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="],
|
"react-dom": ["[email protected]", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="],
|
||||||
@@ -2270,8 +2101,6 @@
|
|||||||
|
|
||||||
"safer-buffer": ["[email protected]", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
|
"safer-buffer": ["[email protected]", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
|
||||||
|
|
||||||
"satori": ["[email protected]", "", { "dependencies": { "@shuding/opentype.js": "1.4.0-beta.0", "css-background-parser": "^0.1.0", "css-box-shadow": "1.0.0-3", "css-gradient-parser": "^0.0.17", "css-to-react-native": "^3.0.0", "emoji-regex-xs": "^2.0.1", "escape-html": "^1.0.3", "linebreak": "^1.1.0", "parse-css-color": "^0.2.1", "postcss-value-parser": "^4.2.0", "yoga-layout": "^3.2.1" } }, "sha512-HanEzgXHlX3fzpGgxPoR3qI7FDpc/B+uE/KplzA6BkZGlWMaH98B/1Amq+OBF1pYPlGNzAXPYNHlrEVBvRBnHQ=="],
|
|
||||||
|
|
||||||
"sax": ["[email protected]", "", {}, "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="],
|
"sax": ["[email protected]", "", {}, "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="],
|
||||||
|
|
||||||
"scheduler": ["[email protected]", "", {}, "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA=="],
|
"scheduler": ["[email protected]", "", {}, "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA=="],
|
||||||
@@ -2326,7 +2155,7 @@
|
|||||||
|
|
||||||
"socks-proxy-agent": ["[email protected]", "", { "dependencies": { "agent-base": "^6.0.2", "debug": "^4.3.3", "socks": "^2.6.2" } }, "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww=="],
|
"socks-proxy-agent": ["[email protected]", "", { "dependencies": { "agent-base": "^6.0.2", "debug": "^4.3.3", "socks": "^2.6.2" } }, "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww=="],
|
||||||
|
|
||||||
"source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
|
"source-map": ["source-map@0.8.0-beta.0", "", { "dependencies": { "whatwg-url": "^7.0.0" } }, "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA=="],
|
||||||
|
|
||||||
"source-map-js": ["[email protected]", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
"source-map-js": ["[email protected]", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
||||||
|
|
||||||
@@ -2358,8 +2187,6 @@
|
|||||||
|
|
||||||
"string-width": ["[email protected]", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
"string-width": ["[email protected]", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
||||||
|
|
||||||
"string.prototype.codepointat": ["[email protected]", "", {}, "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg=="],
|
|
||||||
|
|
||||||
"string.prototype.matchall": ["[email protected]", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-abstract": "^1.23.6", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.6", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "internal-slot": "^1.1.0", "regexp.prototype.flags": "^1.5.3", "set-function-name": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA=="],
|
"string.prototype.matchall": ["[email protected]", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-abstract": "^1.23.6", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.6", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "internal-slot": "^1.1.0", "regexp.prototype.flags": "^1.5.3", "set-function-name": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA=="],
|
||||||
|
|
||||||
"string.prototype.trim": ["[email protected]", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", "define-data-property": "^1.1.4", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-object-atoms": "^1.0.0", "has-property-descriptors": "^1.0.2" } }, "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA=="],
|
"string.prototype.trim": ["[email protected]", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.2", "define-data-property": "^1.1.4", "define-properties": "^1.2.1", "es-abstract": "^1.23.5", "es-object-atoms": "^1.0.0", "has-property-descriptors": "^1.0.2" } }, "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA=="],
|
||||||
@@ -2428,6 +2255,8 @@
|
|||||||
|
|
||||||
"tr46": ["[email protected]", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA=="],
|
"tr46": ["[email protected]", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA=="],
|
||||||
|
|
||||||
|
"transliteration": ["[email protected]", "", { "bin": { "transliterate": "dist/bin/transliterate", "slugify": "dist/bin/slugify" } }, "sha512-hJ9BhrQAOnNTbpOr1MxsNjZISkn7ppvF5TKUeFmTE1mG4ZPD/XVxF0L0LUoIUCWmQyxH0gJpVtfYLAWf298U9w=="],
|
||||||
|
|
||||||
"trim-lines": ["[email protected]", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="],
|
"trim-lines": ["[email protected]", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="],
|
||||||
|
|
||||||
"troika-three-text": ["[email protected]", "", { "dependencies": { "bidi-js": "^1.0.2", "troika-three-utils": "^0.52.4", "troika-worker-utils": "^0.52.0", "webgl-sdf-generator": "1.1.1" }, "peerDependencies": { "three": ">=0.125.0" } }, "sha512-V50EwcYGruV5rUZ9F4aNsrytGdKcXKALjEtQXIOBfhVoZU9VAqZNIoGQ3TMiooVqFAbR1w15T+f+8gkzoFzawg=="],
|
"troika-three-text": ["[email protected]", "", { "dependencies": { "bidi-js": "^1.0.2", "troika-three-utils": "^0.52.4", "troika-worker-utils": "^0.52.0", "webgl-sdf-generator": "1.1.1" }, "peerDependencies": { "three": ">=0.125.0" } }, "sha512-V50EwcYGruV5rUZ9F4aNsrytGdKcXKALjEtQXIOBfhVoZU9VAqZNIoGQ3TMiooVqFAbR1w15T+f+8gkzoFzawg=="],
|
||||||
@@ -2440,8 +2269,6 @@
|
|||||||
|
|
||||||
"ts-deepmerge": ["[email protected]", "", {}, "sha512-Du/ZW2RfwV/D4cmA5rXafYjBQVuvu4qGiEEla4EmEHVHgRdx68Gftx7i66jn2bzHPwSVZY36Ae6OuDn9el4ZKA=="],
|
"ts-deepmerge": ["[email protected]", "", {}, "sha512-Du/ZW2RfwV/D4cmA5rXafYjBQVuvu4qGiEEla4EmEHVHgRdx68Gftx7i66jn2bzHPwSVZY36Ae6OuDn9el4ZKA=="],
|
||||||
|
|
||||||
"ts-mixer": ["[email protected]", "", {}, "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA=="],
|
|
||||||
|
|
||||||
"ts-poet": ["[email protected]", "", { "dependencies": { "dprint-node": "^1.0.8" } }, "sha512-xo+iRNMWqyvXpFTaOAvLPA5QAWO6TZrSUs5s4Odaya3epqofBu/fMLHEWl8jPmjhA0s9sgj9sNvF1BmaQlmQkA=="],
|
"ts-poet": ["[email protected]", "", { "dependencies": { "dprint-node": "^1.0.8" } }, "sha512-xo+iRNMWqyvXpFTaOAvLPA5QAWO6TZrSUs5s4Odaya3epqofBu/fMLHEWl8jPmjhA0s9sgj9sNvF1BmaQlmQkA=="],
|
||||||
|
|
||||||
"ts-proto": ["[email protected]", "", { "dependencies": { "@bufbuild/protobuf": "^2.0.0", "case-anything": "^2.1.13", "ts-poet": "^6.12.0", "ts-proto-descriptors": "2.0.0" }, "bin": { "protoc-gen-ts_proto": "protoc-gen-ts_proto" } }, "sha512-/OfN9/Yriji2bbpOysZ/Jzc96isOKz+eBTJEcKaIZ0PR6x1TNgVm4Lz0zfbo+J0jwFO7fJjJyssefBPQ0o1V9A=="],
|
"ts-proto": ["[email protected]", "", { "dependencies": { "@bufbuild/protobuf": "^2.0.0", "case-anything": "^2.1.13", "ts-poet": "^6.12.0", "ts-proto-descriptors": "2.0.0" }, "bin": { "protoc-gen-ts_proto": "protoc-gen-ts_proto" } }, "sha512-/OfN9/Yriji2bbpOysZ/Jzc96isOKz+eBTJEcKaIZ0PR6x1TNgVm4Lz0zfbo+J0jwFO7fJjJyssefBPQ0o1V9A=="],
|
||||||
@@ -2482,7 +2309,7 @@
|
|||||||
|
|
||||||
"uncrypto": ["[email protected]", "", {}, "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q=="],
|
"uncrypto": ["[email protected]", "", {}, "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q=="],
|
||||||
|
|
||||||
"undici": ["undici@6.21.3", "", {}, "sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw=="],
|
"undici": ["undici@7.16.0", "", {}, "sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g=="],
|
||||||
|
|
||||||
"undici-types": ["[email protected]", "", {}, "sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ=="],
|
"undici-types": ["[email protected]", "", {}, "sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ=="],
|
||||||
|
|
||||||
@@ -2562,7 +2389,7 @@
|
|||||||
|
|
||||||
"vfile-message": ["[email protected]", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="],
|
"vfile-message": ["[email protected]", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="],
|
||||||
|
|
||||||
"vite": ["vite@6.3.6", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-0msEVHJEScQbhkbVTb/4iHZdJ6SXp/AvxL2sjwYQFfBqleHtnCqv1J3sa9zbWz/6kW1m9Tfzn92vW+kZ1WV6QA=="],
|
"vite": ["vite@7.1.9", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-4nVGliEpxmhCL8DslSAUdxlB6+SMrhB0a1v5ijlh1xB1nEPuy1mxaHxysVucLHuWryAxLWg6a5ei+U4TLn/rFg=="],
|
||||||
|
|
||||||
"vite-plugin-pwa": ["[email protected]", "", { "dependencies": { "debug": "^4.3.6", "pretty-bytes": "^6.1.1", "tinyglobby": "^0.2.10", "workbox-build": "^7.3.0", "workbox-window": "^7.3.0" }, "peerDependencies": { "@vite-pwa/assets-generator": "^1.0.0", "vite": "^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" }, "optionalPeers": ["@vite-pwa/assets-generator"] }, "sha512-/OpqIpUldALGxcsEnv/ekQiQ5xHkQ53wcoN5ewX4jiIDNGs3W+eNcI1WYZeyOLmzoEjg09D7aX0O89YGjen1aw=="],
|
"vite-plugin-pwa": ["[email protected]", "", { "dependencies": { "debug": "^4.3.6", "pretty-bytes": "^6.1.1", "tinyglobby": "^0.2.10", "workbox-build": "^7.3.0", "workbox-window": "^7.3.0" }, "peerDependencies": { "@vite-pwa/assets-generator": "^1.0.0", "vite": "^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" }, "optionalPeers": ["@vite-pwa/assets-generator"] }, "sha512-/OpqIpUldALGxcsEnv/ekQiQ5xHkQ53wcoN5ewX4jiIDNGs3W+eNcI1WYZeyOLmzoEjg09D7aX0O89YGjen1aw=="],
|
||||||
|
|
||||||
@@ -2706,8 +2533,6 @@
|
|||||||
|
|
||||||
"yoctocolors": ["[email protected]", "", {}, "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug=="],
|
"yoctocolors": ["[email protected]", "", {}, "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug=="],
|
||||||
|
|
||||||
"yoga-layout": ["[email protected]", "", {}, "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ=="],
|
|
||||||
|
|
||||||
"zod": ["[email protected]", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
"zod": ["[email protected]", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
||||||
|
|
||||||
"zod-to-json-schema": ["[email protected]", "", { "peerDependencies": { "zod": "^3.24.1" } }, "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg=="],
|
"zod-to-json-schema": ["[email protected]", "", { "peerDependencies": { "zod": "^3.24.1" } }, "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg=="],
|
||||||
@@ -2722,6 +2547,8 @@
|
|||||||
|
|
||||||
"@astrojs/markdown-remark/@astrojs/internal-helpers": ["@astrojs/[email protected]", "", {}, "sha512-lDA9MqE8WGi7T/t2BMi+EAXhs4Vcvr94Gqx3q15cFEz8oFZMO4/SFBqYr/UcmNlvW+35alowkVj+w9VhLvs5Cw=="],
|
"@astrojs/markdown-remark/@astrojs/internal-helpers": ["@astrojs/[email protected]", "", {}, "sha512-lDA9MqE8WGi7T/t2BMi+EAXhs4Vcvr94Gqx3q15cFEz8oFZMO4/SFBqYr/UcmNlvW+35alowkVj+w9VhLvs5Cw=="],
|
||||||
|
|
||||||
|
"@astrojs/react/vite": ["[email protected]", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-0msEVHJEScQbhkbVTb/4iHZdJ6SXp/AvxL2sjwYQFfBqleHtnCqv1J3sa9zbWz/6kW1m9Tfzn92vW+kZ1WV6QA=="],
|
||||||
|
|
||||||
"@babel/core/semver": ["[email protected]", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
"@babel/core/semver": ["[email protected]", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
||||||
|
|
||||||
"@babel/helper-compilation-targets/lru-cache": ["[email protected]", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
|
"@babel/helper-compilation-targets/lru-cache": ["[email protected]", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
|
||||||
@@ -2734,24 +2561,6 @@
|
|||||||
|
|
||||||
"@babel/preset-env/semver": ["[email protected]", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
"@babel/preset-env/semver": ["[email protected]", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
||||||
|
|
||||||
"@blitzkit/app/typescript": ["[email protected]", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw=="],
|
|
||||||
|
|
||||||
"@blitzkit/bot/prisma": ["[email protected]", "", { "dependencies": { "@prisma/config": "6.19.2", "@prisma/engines": "6.19.2" }, "peerDependencies": { "typescript": ">=5.1.0" }, "optionalPeers": ["typescript"], "bin": { "prisma": "build/index.js" } }, "sha512-XTKeKxtQElcq3U9/jHyxSPgiRgeYDKxWTPOf6NkXA0dNj5j40MfEsZkMbyNpwDWCUv7YBFUl7I2VK/6ALbmhEg=="],
|
|
||||||
|
|
||||||
"@blitzkit/website/vite": ["[email protected]", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-4nVGliEpxmhCL8DslSAUdxlB6+SMrhB0a1v5ijlh1xB1nEPuy1mxaHxysVucLHuWryAxLWg6a5ei+U4TLn/rFg=="],
|
|
||||||
|
|
||||||
"@discordjs/rest/@discordjs/collection": ["@discordjs/[email protected]", "", {}, "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg=="],
|
|
||||||
|
|
||||||
"@discordjs/rest/@discordjs/util": ["@discordjs/[email protected]", "", {}, "sha512-eddz6UnOBEB1oITPinyrB2Pttej49M9FZQY8NxgEvc3tq6ZICZ19m70RsmzRdDHk80O9NoYN/25AqJl8vPVf/g=="],
|
|
||||||
|
|
||||||
"@discordjs/rest/discord-api-types": ["[email protected]", "", {}, "sha512-xpmPviHjIJ6dFu1eNwNDIGQ3N6qmPUUYFVAx/YZ64h7ZgPkTcKjnciD8bZe8Vbeji7yS5uYljyciunpq0J5NSw=="],
|
|
||||||
|
|
||||||
"@discordjs/ws/@discordjs/collection": ["@discordjs/[email protected]", "", {}, "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg=="],
|
|
||||||
|
|
||||||
"@discordjs/ws/@discordjs/util": ["@discordjs/[email protected]", "", {}, "sha512-eddz6UnOBEB1oITPinyrB2Pttej49M9FZQY8NxgEvc3tq6ZICZ19m70RsmzRdDHk80O9NoYN/25AqJl8vPVf/g=="],
|
|
||||||
|
|
||||||
"@discordjs/ws/discord-api-types": ["[email protected]", "", {}, "sha512-xpmPviHjIJ6dFu1eNwNDIGQ3N6qmPUUYFVAx/YZ64h7ZgPkTcKjnciD8bZe8Vbeji7yS5uYljyciunpq0J5NSw=="],
|
|
||||||
|
|
||||||
"@jimp/core/file-type": ["[email protected]", "", { "dependencies": { "readable-web-to-node-stream": "^3.0.0", "strtok3": "^6.2.4", "token-types": "^4.1.1" } }, "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw=="],
|
"@jimp/core/file-type": ["[email protected]", "", { "dependencies": { "readable-web-to-node-stream": "^3.0.0", "strtok3": "^6.2.4", "token-types": "^4.1.1" } }, "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw=="],
|
||||||
|
|
||||||
"@octokit/endpoint/@octokit/types": ["@octokit/[email protected]", "", { "dependencies": { "@octokit/openapi-types": "^25.1.0" } }, "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g=="],
|
"@octokit/endpoint/@octokit/types": ["@octokit/[email protected]", "", { "dependencies": { "@octokit/openapi-types": "^25.1.0" } }, "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g=="],
|
||||||
@@ -2778,10 +2587,10 @@
|
|||||||
|
|
||||||
"@rollup/pluginutils/estree-walker": ["[email protected]", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
|
"@rollup/pluginutils/estree-walker": ["[email protected]", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
|
||||||
|
|
||||||
"@shuding/opentype.js/fflate": ["[email protected]", "", {}, "sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw=="],
|
|
||||||
|
|
||||||
"@surma/rollup-plugin-off-main-thread/magic-string": ["[email protected]", "", { "dependencies": { "sourcemap-codec": "^1.4.8" } }, "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ=="],
|
"@surma/rollup-plugin-off-main-thread/magic-string": ["[email protected]", "", { "dependencies": { "sourcemap-codec": "^1.4.8" } }, "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ=="],
|
||||||
|
|
||||||
|
"ajv/fast-deep-equal": ["[email protected]", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
|
||||||
|
|
||||||
"anymatch/picomatch": ["[email protected]", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
"anymatch/picomatch": ["[email protected]", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
||||||
|
|
||||||
"astro/@astrojs/internal-helpers": ["@astrojs/[email protected]", "", {}, "sha512-lDA9MqE8WGi7T/t2BMi+EAXhs4Vcvr94Gqx3q15cFEz8oFZMO4/SFBqYr/UcmNlvW+35alowkVj+w9VhLvs5Cw=="],
|
"astro/@astrojs/internal-helpers": ["@astrojs/[email protected]", "", {}, "sha512-lDA9MqE8WGi7T/t2BMi+EAXhs4Vcvr94Gqx3q15cFEz8oFZMO4/SFBqYr/UcmNlvW+35alowkVj+w9VhLvs5Cw=="],
|
||||||
@@ -2790,6 +2599,8 @@
|
|||||||
|
|
||||||
"astro/sharp": ["[email protected]", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.0", "semver": "^7.7.2" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.4", "@img/sharp-darwin-x64": "0.34.4", "@img/sharp-libvips-darwin-arm64": "1.2.3", "@img/sharp-libvips-darwin-x64": "1.2.3", "@img/sharp-libvips-linux-arm": "1.2.3", "@img/sharp-libvips-linux-arm64": "1.2.3", "@img/sharp-libvips-linux-ppc64": "1.2.3", "@img/sharp-libvips-linux-s390x": "1.2.3", "@img/sharp-libvips-linux-x64": "1.2.3", "@img/sharp-libvips-linuxmusl-arm64": "1.2.3", "@img/sharp-libvips-linuxmusl-x64": "1.2.3", "@img/sharp-linux-arm": "0.34.4", "@img/sharp-linux-arm64": "0.34.4", "@img/sharp-linux-ppc64": "0.34.4", "@img/sharp-linux-s390x": "0.34.4", "@img/sharp-linux-x64": "0.34.4", "@img/sharp-linuxmusl-arm64": "0.34.4", "@img/sharp-linuxmusl-x64": "0.34.4", "@img/sharp-wasm32": "0.34.4", "@img/sharp-win32-arm64": "0.34.4", "@img/sharp-win32-ia32": "0.34.4", "@img/sharp-win32-x64": "0.34.4" } }, "sha512-FUH39xp3SBPnxWvd5iib1X8XY7J0K0X7d93sie9CJg2PO8/7gmg89Nve6OjItK53/MlAushNNxteBYfM6DEuoA=="],
|
"astro/sharp": ["[email protected]", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.0", "semver": "^7.7.2" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.4", "@img/sharp-darwin-x64": "0.34.4", "@img/sharp-libvips-darwin-arm64": "1.2.3", "@img/sharp-libvips-darwin-x64": "1.2.3", "@img/sharp-libvips-linux-arm": "1.2.3", "@img/sharp-libvips-linux-arm64": "1.2.3", "@img/sharp-libvips-linux-ppc64": "1.2.3", "@img/sharp-libvips-linux-s390x": "1.2.3", "@img/sharp-libvips-linux-x64": "1.2.3", "@img/sharp-libvips-linuxmusl-arm64": "1.2.3", "@img/sharp-libvips-linuxmusl-x64": "1.2.3", "@img/sharp-linux-arm": "0.34.4", "@img/sharp-linux-arm64": "0.34.4", "@img/sharp-linux-ppc64": "0.34.4", "@img/sharp-linux-s390x": "0.34.4", "@img/sharp-linux-x64": "0.34.4", "@img/sharp-linuxmusl-arm64": "0.34.4", "@img/sharp-linuxmusl-x64": "0.34.4", "@img/sharp-wasm32": "0.34.4", "@img/sharp-win32-arm64": "0.34.4", "@img/sharp-win32-ia32": "0.34.4", "@img/sharp-win32-x64": "0.34.4" } }, "sha512-FUH39xp3SBPnxWvd5iib1X8XY7J0K0X7d93sie9CJg2PO8/7gmg89Nve6OjItK53/MlAushNNxteBYfM6DEuoA=="],
|
||||||
|
|
||||||
|
"astro/vite": ["[email protected]", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-0msEVHJEScQbhkbVTb/4iHZdJ6SXp/AvxL2sjwYQFfBqleHtnCqv1J3sa9zbWz/6kW1m9Tfzn92vW+kZ1WV6QA=="],
|
||||||
|
|
||||||
"babel-plugin-polyfill-corejs2/semver": ["[email protected]", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
"babel-plugin-polyfill-corejs2/semver": ["[email protected]", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
||||||
|
|
||||||
"binarykvparser/long": ["[email protected]", "", { "bundled": true }, "sha512-ZYvPPOMqUwPoDsbJaR10iQJYnMuZhRTvHYl62ErLIEX7RgFlziSBUUvrt3OVfc47QlHHpzPZYP17g3Fv7oeJkg=="],
|
"binarykvparser/long": ["[email protected]", "", { "bundled": true }, "sha512-ZYvPPOMqUwPoDsbJaR10iQJYnMuZhRTvHYl62ErLIEX7RgFlziSBUUvrt3OVfc47QlHHpzPZYP17g3Fv7oeJkg=="],
|
||||||
@@ -2798,10 +2609,6 @@
|
|||||||
|
|
||||||
"bytebuffer/long": ["[email protected]", "", {}, "sha512-ZYvPPOMqUwPoDsbJaR10iQJYnMuZhRTvHYl62ErLIEX7RgFlziSBUUvrt3OVfc47QlHHpzPZYP17g3Fv7oeJkg=="],
|
"bytebuffer/long": ["[email protected]", "", {}, "sha512-ZYvPPOMqUwPoDsbJaR10iQJYnMuZhRTvHYl62ErLIEX7RgFlziSBUUvrt3OVfc47QlHHpzPZYP17g3Fv7oeJkg=="],
|
||||||
|
|
||||||
"c12/dotenv": ["[email protected]", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="],
|
|
||||||
|
|
||||||
"cheerio/undici": ["[email protected]", "", {}, "sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g=="],
|
|
||||||
|
|
||||||
"cliui/wrap-ansi": ["[email protected]", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
|
"cliui/wrap-ansi": ["[email protected]", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
|
||||||
|
|
||||||
"decompress-tarbz2/file-type": ["[email protected]", "", {}, "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg=="],
|
"decompress-tarbz2/file-type": ["[email protected]", "", {}, "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg=="],
|
||||||
@@ -2810,6 +2617,8 @@
|
|||||||
|
|
||||||
"dprint-node/detect-libc": ["[email protected]", "", { "bin": { "detect-libc": "./bin/detect-libc.js" } }, "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg=="],
|
"dprint-node/detect-libc": ["[email protected]", "", { "bin": { "detect-libc": "./bin/detect-libc.js" } }, "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg=="],
|
||||||
|
|
||||||
|
"escodegen/source-map": ["[email protected]", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
|
||||||
|
|
||||||
"extract-zip/get-stream": ["[email protected]", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="],
|
"extract-zip/get-stream": ["[email protected]", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="],
|
||||||
|
|
||||||
"favilib/sharp": ["[email protected]", "", { "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.3", "semver": "^7.6.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.33.5", "@img/sharp-darwin-x64": "0.33.5", "@img/sharp-libvips-darwin-arm64": "1.0.4", "@img/sharp-libvips-darwin-x64": "1.0.4", "@img/sharp-libvips-linux-arm": "1.0.5", "@img/sharp-libvips-linux-arm64": "1.0.4", "@img/sharp-libvips-linux-s390x": "1.0.4", "@img/sharp-libvips-linux-x64": "1.0.4", "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", "@img/sharp-libvips-linuxmusl-x64": "1.0.4", "@img/sharp-linux-arm": "0.33.5", "@img/sharp-linux-arm64": "0.33.5", "@img/sharp-linux-s390x": "0.33.5", "@img/sharp-linux-x64": "0.33.5", "@img/sharp-linuxmusl-arm64": "0.33.5", "@img/sharp-linuxmusl-x64": "0.33.5", "@img/sharp-wasm32": "0.33.5", "@img/sharp-win32-ia32": "0.33.5", "@img/sharp-win32-x64": "0.33.5" } }, "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw=="],
|
"favilib/sharp": ["[email protected]", "", { "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.3", "semver": "^7.6.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.33.5", "@img/sharp-darwin-x64": "0.33.5", "@img/sharp-libvips-darwin-arm64": "1.0.4", "@img/sharp-libvips-darwin-x64": "1.0.4", "@img/sharp-libvips-linux-arm": "1.0.5", "@img/sharp-libvips-linux-arm64": "1.0.4", "@img/sharp-libvips-linux-s390x": "1.0.4", "@img/sharp-libvips-linux-x64": "1.0.4", "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", "@img/sharp-libvips-linuxmusl-x64": "1.0.4", "@img/sharp-linux-arm": "0.33.5", "@img/sharp-linux-arm64": "0.33.5", "@img/sharp-linux-s390x": "0.33.5", "@img/sharp-linux-x64": "0.33.5", "@img/sharp-linuxmusl-arm64": "0.33.5", "@img/sharp-linuxmusl-x64": "0.33.5", "@img/sharp-wasm32": "0.33.5", "@img/sharp-win32-ia32": "0.33.5", "@img/sharp-win32-x64": "0.33.5" } }, "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw=="],
|
||||||
@@ -2818,6 +2627,8 @@
|
|||||||
|
|
||||||
"filelist/minimatch": ["[email protected]", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="],
|
"filelist/minimatch": ["[email protected]", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="],
|
||||||
|
|
||||||
|
"fontkit/fast-deep-equal": ["[email protected]", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
|
||||||
|
|
||||||
"get-uri/data-uri-to-buffer": ["[email protected]", "", {}, "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw=="],
|
"get-uri/data-uri-to-buffer": ["[email protected]", "", {}, "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw=="],
|
||||||
|
|
||||||
"hast-util-to-parse5/property-information": ["[email protected]", "", {}, "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig=="],
|
"hast-util-to-parse5/property-information": ["[email protected]", "", {}, "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig=="],
|
||||||
@@ -2834,8 +2645,6 @@
|
|||||||
|
|
||||||
"its-fine/@types/react-reconciler": ["@types/[email protected]", "", { "peerDependencies": { "@types/react": "*" } }, "sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg=="],
|
"its-fine/@types/react-reconciler": ["@types/[email protected]", "", { "peerDependencies": { "@types/react": "*" } }, "sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg=="],
|
||||||
|
|
||||||
"linebreak/base64-js": ["[email protected]", "", {}, "sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw=="],
|
|
||||||
|
|
||||||
"make-dir/pify": ["[email protected]", "", {}, "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg=="],
|
"make-dir/pify": ["[email protected]", "", {}, "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg=="],
|
||||||
|
|
||||||
"micromatch/picomatch": ["[email protected]", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
"micromatch/picomatch": ["[email protected]", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
||||||
@@ -2862,8 +2671,6 @@
|
|||||||
|
|
||||||
"react-dom/scheduler": ["[email protected]", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
|
"react-dom/scheduler": ["[email protected]", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
|
||||||
|
|
||||||
"react-promise-suspense/fast-deep-equal": ["[email protected]", "", {}, "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w=="],
|
|
||||||
|
|
||||||
"readable-stream/safe-buffer": ["[email protected]", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="],
|
"readable-stream/safe-buffer": ["[email protected]", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="],
|
||||||
|
|
||||||
"readable-web-to-node-stream/readable-stream": ["[email protected]", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="],
|
"readable-web-to-node-stream/readable-stream": ["[email protected]", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="],
|
||||||
@@ -2874,6 +2681,8 @@
|
|||||||
|
|
||||||
"simple-swizzle/is-arrayish": ["[email protected]", "", {}, "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA=="],
|
"simple-swizzle/is-arrayish": ["[email protected]", "", {}, "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA=="],
|
||||||
|
|
||||||
|
"source-map-support/source-map": ["[email protected]", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
|
||||||
|
|
||||||
"stats-gl/three": ["[email protected]", "", {}, "sha512-FQK+LEpYc0fBD+J8g6oSEyyNzjp+Q7Ks1C568WWaoMRLW+TkNNWmenWeGgJjV105Gd+p/2ql1ZcjYvNiPZBhuQ=="],
|
"stats-gl/three": ["[email protected]", "", {}, "sha512-FQK+LEpYc0fBD+J8g6oSEyyNzjp+Q7Ks1C568WWaoMRLW+TkNNWmenWeGgJjV105Gd+p/2ql1ZcjYvNiPZBhuQ=="],
|
||||||
|
|
||||||
"steam-appticket/@doctormckay/stdlib": ["@doctormckay/[email protected]", "", {}, "sha512-XhuUOzElz6fnNdt70IYNKqhPAEpGaL4JHOhAvklRh0hAhVPW+/wLxaWT3DWUbaG5Dta5YvIp7+cZK3GhIpAuug=="],
|
"steam-appticket/@doctormckay/stdlib": ["@doctormckay/[email protected]", "", {}, "sha512-XhuUOzElz6fnNdt70IYNKqhPAEpGaL4JHOhAvklRh0hAhVPW+/wLxaWT3DWUbaG5Dta5YvIp7+cZK3GhIpAuug=="],
|
||||||
@@ -2920,8 +2729,6 @@
|
|||||||
|
|
||||||
"workbox-build/rollup": ["[email protected]", "", { "optionalDependencies": { "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ=="],
|
"workbox-build/rollup": ["[email protected]", "", { "optionalDependencies": { "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ=="],
|
||||||
|
|
||||||
"workbox-build/source-map": ["[email protected]", "", { "dependencies": { "whatwg-url": "^7.0.0" } }, "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA=="],
|
|
||||||
|
|
||||||
"wrap-ansi/string-width": ["[email protected]", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
|
"wrap-ansi/string-width": ["[email protected]", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
|
||||||
|
|
||||||
"wrap-ansi/strip-ansi": ["[email protected]", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="],
|
"wrap-ansi/strip-ansi": ["[email protected]", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="],
|
||||||
@@ -2934,10 +2741,6 @@
|
|||||||
|
|
||||||
"yaml-language-server/yaml": ["[email protected]", "", {}, "sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA=="],
|
"yaml-language-server/yaml": ["[email protected]", "", {}, "sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA=="],
|
||||||
|
|
||||||
"@blitzkit/bot/prisma/@prisma/config": ["@prisma/[email protected]", "", { "dependencies": { "c12": "3.1.0", "deepmerge-ts": "7.1.5", "effect": "3.18.4", "empathic": "2.0.0" } }, "sha512-kadBGDl+aUswv/zZMk9Mx0C8UZs1kjao8H9/JpI4Wh4SHZaM7zkTwiKn/iFLfRg+XtOAo/Z/c6pAYhijKl0nzQ=="],
|
|
||||||
|
|
||||||
"@blitzkit/bot/prisma/@prisma/engines": ["@prisma/[email protected]", "", { "dependencies": { "@prisma/debug": "6.19.2", "@prisma/engines-version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7", "@prisma/fetch-engine": "6.19.2", "@prisma/get-platform": "6.19.2" } }, "sha512-TTkJ8r+uk/uqczX40wb+ODG0E0icVsMgwCTyTHXehaEfb0uo80M9g1aW1tEJrxmFHeOZFXdI2sTA1j1AgcHi4A=="],
|
|
||||||
|
|
||||||
"@octokit/endpoint/@octokit/types/@octokit/openapi-types": ["@octokit/[email protected]", "", {}, "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA=="],
|
"@octokit/endpoint/@octokit/types/@octokit/openapi-types": ["@octokit/[email protected]", "", {}, "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA=="],
|
||||||
|
|
||||||
"@octokit/graphql/@octokit/types/@octokit/openapi-types": ["@octokit/[email protected]", "", {}, "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA=="],
|
"@octokit/graphql/@octokit/types/@octokit/openapi-types": ["@octokit/[email protected]", "", {}, "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA=="],
|
||||||
@@ -3120,14 +2923,6 @@
|
|||||||
|
|
||||||
"yaml-language-server/vscode-languageserver/vscode-languageserver-protocol": ["[email protected]", "", { "dependencies": { "vscode-jsonrpc": "6.0.0", "vscode-languageserver-types": "3.16.0" } }, "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A=="],
|
"yaml-language-server/vscode-languageserver/vscode-languageserver-protocol": ["[email protected]", "", { "dependencies": { "vscode-jsonrpc": "6.0.0", "vscode-languageserver-types": "3.16.0" } }, "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A=="],
|
||||||
|
|
||||||
"@blitzkit/bot/prisma/@prisma/engines/@prisma/debug": ["@prisma/[email protected]", "", {}, "sha512-lFnEZsLdFLmEVCVNdskLDCL8Uup41GDfU0LUfquw+ercJC8ODTuL0WNKgOKmYxCJVvFwf0OuZBzW99DuWmoH2A=="],
|
|
||||||
|
|
||||||
"@blitzkit/bot/prisma/@prisma/engines/@prisma/engines-version": ["@prisma/[email protected]", "", {}, "sha512-03bgb1VD5gvuumNf+7fVGBzfpJPjmqV423l/WxsWk2cNQ42JD0/SsFBPhN6z8iAvdHs07/7ei77SKu7aZfq8bA=="],
|
|
||||||
|
|
||||||
"@blitzkit/bot/prisma/@prisma/engines/@prisma/fetch-engine": ["@prisma/[email protected]", "", { "dependencies": { "@prisma/debug": "6.19.2", "@prisma/engines-version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7", "@prisma/get-platform": "6.19.2" } }, "sha512-h4Ff4Pho+SR1S8XerMCC12X//oY2bG3Iug/fUnudfcXEUnIeRiBdXHFdGlGOgQ3HqKgosTEhkZMvGM9tWtYC+Q=="],
|
|
||||||
|
|
||||||
"@blitzkit/bot/prisma/@prisma/engines/@prisma/get-platform": ["@prisma/[email protected]", "", { "dependencies": { "@prisma/debug": "6.19.2" } }, "sha512-PGLr06JUSTqIvztJtAzIxOwtWKtJm5WwOG6xpsgD37Rc84FpfUBGLKz65YpJBGtkRQGXTYEFie7pYALocC3MtA=="],
|
|
||||||
|
|
||||||
"astro/sharp/@img/sharp-wasm32/@emnapi/runtime": ["@emnapi/[email protected]", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ=="],
|
"astro/sharp/@img/sharp-wasm32/@emnapi/runtime": ["@emnapi/[email protected]", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ=="],
|
||||||
|
|
||||||
"boxen/string-width/strip-ansi/ansi-regex": ["[email protected]", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
|
"boxen/string-width/strip-ansi/ansi-regex": ["[email protected]", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"words": [
|
||||||
|
"gamemodes",
|
||||||
|
"Tankopedia"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# BlitzKit 1.29.15
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
- Tanks now use alpha clipping to render translucency, fixing a lot of "ghostly" looking tanks
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# BlitzKit 1.29.16
|
||||||
|
|
||||||
|
Thank you to [GonnaHetzMe](https://github.com/karelpak1) for your contributions this update.
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
- [GonnaHetzMe] The turret for Centurion I is no longer offset from the body
|
||||||
|
- Please allow up to 24 hours for the model to update
|
||||||
|
- Vertical Stabilizers now give the correct 12% buff instead of 15%
|
||||||
|
- Re-ordering tanks in Compare now works once again
|
||||||
|
- Fixed review videos from being about the Object 452K across all tanks
|
||||||
|
- Please allow up to 2 weeks for all tanks to refresh their videos
|
||||||
|
- Tanks in Mixer with oscillating turrets are not handled properly
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Headings in the Compare tool are now even more compact for mobile devices
|
||||||
|
- Enabled all tiers for the randomizer in Mixer
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# BlitzKit 1.30.0
|
||||||
|
|
||||||
|
Thank you to [GonnaHetzMe](https://github.com/karelpak1) for your contributions this update.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Added an equalizer mode for Tankopedia and Compare to preview what tank stats will look like in the upcoming Equalizer game mode
|
||||||
|
- This feature is in Beta and the stats are subject to change
|
||||||
|
- Thanks to WoTB News for sourcing data well ahead of the release of the gamemode
|
||||||
|
- Added a toggle in Tankopedia, right beneath Provisions
|
||||||
|
- Added button under the shell selector in the Tank Sandbox
|
||||||
|
- Added another toggle in the Compare table to enable equalizer for all tanks
|
||||||
|
|
||||||
|
## Technical Features
|
||||||
|
|
||||||
|
- [GonnaHetzMe] Enabling dev mode now displays the tank's non-numerical id
|
||||||
|
- [GonnaHetzMe] The dev id and the new dev name are now copyable on click
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
- [GonnaHetzMe] Tech trees that start at tiers higher than tier 1 like the Blitz Nation ones now properly render their trees in Tankopedia
|
||||||
|
- [GonnaHetzMe] The tank pitch/yaw inputs in the Tank Sandbox now initialize with the correct values instead of 0
|
||||||
|
- [GonnaHetzMe] Large Repair Kits once again use the correct modern icon
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# BlitzKit 1.30.1
|
||||||
|
|
||||||
|
Thank you to [GonnaHetzMe](https://github.com/karelpak1) for your contributions this update.
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
- [GonnaHetzMe] Tank hit points in Equalizer mode is now accurate to the game
|
||||||
|
- Armor highlighting now reflects the actual thicknesses of tanks in Equalizer mode
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# BlitzKit 1.30.2
|
||||||
|
|
||||||
|
Thank you to [GonnaHetzMe](https://github.com/karelpak1) for your contributions this update.
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
- [GonnaHetzMe] Tungsten shells are now properly cropped
|
||||||
|
- Equalizer no longer gives insanely high penetration values
|
||||||
|
- The tank reveal animation no longer repeats when you scroll away and back to the tank sandbox
|
||||||
|
- [GonnaHetzMe] The RHM. Pzw.'s turret no longer has the floating plate
|
||||||
|
- Please give BlitzKit up to 1 hour to update the model
|
||||||
|
- [GonnaHetzMe] Tanks with inclined turret rings like the Minotauro now display the correct pitch in the tank sandbox inputs
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# BlitzKit 1.30.3
|
||||||
|
|
||||||
|
Thank you to [GonnaHetzMe](https://github.com/karelpak1) for your contributions this update.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- [GonnaHetzMe] Added tooltips to the module selector in Tankopedia
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
- Added aggressive re-rendering for the Guess mini-game's score readout to make inspect-element harder
|
||||||
|
- Removed tank visual and collision model caching
|
||||||
|
- Guesser once again breaks streaks if not all tiers are selected
|
||||||
|
- BlitzKit now properly unloads tank models from memory when visually hidden in Guesser
|
||||||
|
- [GonnaHetzMe] Tanks with complex transparency like the Herdbreaker once again handle opacity correctly
|
||||||
|
- [GonnaHetzMe] Pieces of tank models that have transparency now handle culling properly (they're visible from both sides)
|
||||||
|
- [GonnaHetzMe] Tanks with "cardboard" textures have been fixed, thanks to better PVR file parsing
|
||||||
|
- [GonnaHetzMe] Tank icons are now scaled correctly so small tanks are now properly zoomed out in contrast to bigger ones
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# BlitzKit 1.30.4
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
- BlitzKit now correctly implements minor WoTB updates
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# BlitzKit 1.30.5
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Reduced the amount of code that executes for every rendered frame, hopefully improving performance
|
||||||
|
- Reduced the number of lights by 20% to decrease the amount of shadow calculations
|
||||||
|
- Decreased the ground size by 80% for an equal reduction in shadow texture sizes
|
||||||
|
- Added the ability for BlitzKit to dismount the components that handled the intro lighting animation when not animating, reducing checks running every frame
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# BlitzKit 1.30.6
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
- Tanks no longer "randomly" appear dark in Tankopedia and Mixer
|
||||||
|
- The ground is now as dark as other modes when Static Armor is selected in Tankopedia
|
||||||
|
- Fixed some naming issues with the "equal" icon, improving performance a tiny tiny bit
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
# BlitzKit 1.30.7
|
||||||
|
|
||||||
|
Thank you to [Mark Greene](https://github.com/Hitjack007) for your contributions this update.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Dragging items in the Tier List now automatically scrolls the screen if you reach the top/bottom edge of the screen
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
- [Mark Greene] Clicking on the armor multiple times with HE no longer crashes BlitzKit
|
||||||
|
- [Mark Greene] Ricochets that later intersect with external modules no longer falsely claim a successful damaging penetration
|
||||||
|
- The lighting animation no longer stops prematurely when BlitzKit is unfocused
|
||||||
|
- The spot light angle has been increased to more evenly light up larger tanks
|
||||||
|
- BlitzKit once again uses soft shadows, reducing the pixelated shadows
|
||||||
|
- Fixed the weird patterns that formed on the tracks of tanks under self-shadows
|
||||||
|
- Increased the floor size and light decay to create the illusion that the floor is infinite
|
||||||
|
- [Mark Greene] Safari no longer crashes when unloading textures for unloaded tanks
|
||||||
|
- The gun depression transition between two constraints (like often behind tanks) now uses a gentler zoned and can never be 0
|
||||||
|
- [Mark Greene] Armor plate names in Static Armor are now properly capitalized in English and translated to other languages
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# BlitzKit 1.30.8
|
||||||
|
|
||||||
|
Support for tanks with Chinese names.
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
- The URL generator for BlitzKit now handles names that have only Chinese characters
|
||||||
|
- The Mixed Virtual File System now handles non-existent directories correctly
|
||||||
|
- Updated equipments to match the game again
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# BlitzKit 1.31.0
|
||||||
|
|
||||||
|
This update massively upgrades BlitzKit's graphical fidelity (while making it faster) and updates the way BlitzKit deploys updates, speeding up future versions.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Improved the performance of the Tank Sandbox in Tankopedia
|
||||||
|
- Reduced the number of lights by 25%
|
||||||
|
- Reduced the resolution of shadows by 50%
|
||||||
|
- Improved the graphical fidelity of tanks in the Tankopedia
|
||||||
|
- Added soft contact shadows below tanks
|
||||||
|
- Added sky and ground reflected lighting to the top and bottom of tanks
|
||||||
|
- Removed the fog that used to darken tanks when zoomed far away
|
||||||
|
- Made BlitzKitLand™ fade out circularly to hide the sharp edges
|
||||||
|
- Pointed the lights 1.5m above the ground
|
||||||
|
- This genuinely makes BlitzKit almost photo-realistic in my opinion
|
||||||
|
- Non-PBR tanks are now lit up brighter to accommodate for their dark textures
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
- Fixed a bug where the ambient occlusion map (a measure of how dark a part of a tank gets due to low light bounces) was applied to the color of the tank directly, making many tanks appear dark even in direct light
|
||||||
|
- Tanks with chinese characters now generate urls through transliteration
|
||||||
|
|
||||||
|
## Known Issues
|
||||||
|
|
||||||
|
- The flags found behind the selected tank in the tech tree section of the Tankopedia is offset incorrectly
|
||||||
|
|
||||||
|
## Technical Features
|
||||||
|
|
||||||
|
- BlitzKit can now calculate and store performance statistics and account details for up 10,000,000,000 players
|
||||||
|
- This will help make the BlitzKit Performance tool more accurate, and play well with an upcoming, unannounced major feature
|
||||||
|
|
||||||
|
## Technical Changes
|
||||||
|
|
||||||
|
- The `production` branch now deploys updates to `blitzkit.app` instead of the `main` branch
|
||||||
|
- `robots.txt` now disables indexing of BlitzKit variants based on the environment
|
||||||
|
- The website is now compiled in "chunks" of which the `api` chunk now takes on the task of mangling what was previously stored in `assets3`
|
||||||
|
- `assets3` will be removed in `1.31.1`, please migrate to the new `api` if you use any BlitzKit assets
|
||||||
|
- Removed the `bot` and `app` packages
|
||||||
|
- Removed Prisma
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# BlitzKit 1.31.1
|
||||||
|
|
||||||
|
This update adds capabilities to release BlitzKit OpenTest and Preview.
|
||||||
@@ -2,17 +2,6 @@
|
|||||||
|
|
||||||
🎉 Services for everything and anything World of Tanks Blitz
|
🎉 Services for everything and anything World of Tanks Blitz
|
||||||
|
|
||||||
## Bot
|
|
||||||
|
|
||||||
BlitzKit is available as a Discord bot and can be [installed very easily](/guide/invite).
|
|
||||||
|
|
||||||
- Track statistics
|
|
||||||
- Find inactive players in a clan
|
|
||||||
- Lookup owned tanks
|
|
||||||
- Create embeds for streams
|
|
||||||
- Track a player/tanks statistical evolution
|
|
||||||
- ...and a variety of other similar things
|
|
||||||
|
|
||||||
## Website
|
## Website
|
||||||
|
|
||||||
Provides a bunch of very helpful tools; https://blitzkit.app/
|
Provides a bunch of very helpful tools; https://blitzkit.app/
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
# Inviting the Bot
|
|
||||||
|
|
||||||
Go to [application directory for BlitzKit](https://discord.com/application-directory/1097673957865443370) and click "Add to Server." Voila! You're ready to go.
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"robots": false,
|
||||||
|
"canonical": "https://blitzkit.app",
|
||||||
|
|
||||||
|
"paths": {
|
||||||
|
"default": null,
|
||||||
|
"api": null
|
||||||
|
},
|
||||||
|
"nodes": {
|
||||||
|
"default": "blitzkit/deploy-node-beta.blitzkit.app",
|
||||||
|
"api": "blitzkit/deploy-node-api.beta.blitzkit.app"
|
||||||
|
},
|
||||||
|
"aliases": {
|
||||||
|
"api": "https://api.beta.blitzkit.app",
|
||||||
|
"static": "https://static.beta.blitzkit.app"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"robots": false,
|
||||||
|
"canonical": "https://blitzkit.app",
|
||||||
|
|
||||||
|
"paths": {
|
||||||
|
"default": null,
|
||||||
|
"api": "api"
|
||||||
|
},
|
||||||
|
"nodes": {},
|
||||||
|
"aliases": {
|
||||||
|
"api": "/api",
|
||||||
|
"static": "https://static.blitzkit.app"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"robots": false,
|
||||||
|
"canonical": "https://blitzkit.app",
|
||||||
|
|
||||||
|
"paths": {
|
||||||
|
"default": null,
|
||||||
|
"api": null
|
||||||
|
},
|
||||||
|
"nodes": {
|
||||||
|
"default": "blitzkit/deploy-node-opentest.blitzkit.app",
|
||||||
|
"api": "blitzkit/deploy-node-api.opentest.blitzkit.app"
|
||||||
|
},
|
||||||
|
"aliases": {
|
||||||
|
"api": "https://api.opentest.blitzkit.app",
|
||||||
|
"static": "https://static.opentest.blitzkit.app"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"robots": false,
|
||||||
|
"canonical": "https://blitzkit.app",
|
||||||
|
|
||||||
|
"paths": {
|
||||||
|
"default": null,
|
||||||
|
"api": null
|
||||||
|
},
|
||||||
|
"nodes": {
|
||||||
|
"default": "blitzkit/deploy-node-preview.blitzkit.app",
|
||||||
|
"api": "blitzkit/deploy-node-api.preview.blitzkit.app"
|
||||||
|
},
|
||||||
|
"aliases": {
|
||||||
|
"api": "https://api.preview.blitzkit.app",
|
||||||
|
"static": "https://static.preview.blitzkit.app"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"robots": true,
|
||||||
|
"canonical": "https://blitzkit.app",
|
||||||
|
|
||||||
|
"paths": {
|
||||||
|
"default": null,
|
||||||
|
"api": null
|
||||||
|
},
|
||||||
|
"nodes": {
|
||||||
|
"default": "blitzkit/deploy-node-blitzkit.app",
|
||||||
|
"api": "blitzkit/deploy-node-api.blitzkit.app"
|
||||||
|
},
|
||||||
|
"aliases": {
|
||||||
|
"api": "https://api.blitzkit.app",
|
||||||
|
"static": "https://static.blitzkit.app"
|
||||||
|
}
|
||||||
|
}
|
||||||
+9
-36
@@ -1,50 +1,23 @@
|
|||||||
{
|
{
|
||||||
"name": "blitzkit",
|
"name": "blitzkit",
|
||||||
"version": "1.29.14",
|
"version": "1.31.1",
|
||||||
"license": "BlitzKit License",
|
"license": "BlitzKit License",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build:assets": "cd packages/scripts && bun run build:assets",
|
"dev": "cd packages/website && bun run dev",
|
||||||
"build:averages": "bun --filter=@blitzkit/scripts run build:averages",
|
"build": "cd packages/website && bun run build",
|
||||||
"build:bot": "cd packages/scripts && bun run build:bot",
|
"discover-ids": "cd packages/scripts && bun run discover-ids",
|
||||||
"build:website": "cd packages/website && bun run build",
|
"build-protos": "cd packages/scripts && bun run build-protos",
|
||||||
"build:prisma": "prisma generate",
|
"record-performance": "cd packages/scripts && bun run record-performance",
|
||||||
"build:proxyclient": "cd packages/scripts && bun run build:proxyclient",
|
"download-client": "cd packages/scripts && bun run download-client"
|
||||||
"build:catalogitemaccesssor": "cd packages/scripts && bun run build:catalogitemaccesssor",
|
|
||||||
"build:ratingleaderboard": "cd packages/scripts && bun run build:ratingleaderboard",
|
|
||||||
"build:app": "cd packages/app && bun run build",
|
|
||||||
"dev:bot": "bun run build:bot --dev && bun start:bot --dev",
|
|
||||||
"start:bot": "bun dist/bot/main.js",
|
|
||||||
"dev:docs": "vitepress dev docs",
|
|
||||||
"dev:website": "cd packages/website && bun run dev",
|
|
||||||
"dev:app": "cd packages/app && bun run dev",
|
|
||||||
"dev": "bun run dev:website",
|
|
||||||
"dev:api": "bun --filter=@blitzkit/api run dev",
|
|
||||||
"setup:depotdownloader": "bun --filter=@blitzkit/scripts run setup:depotdownloader",
|
|
||||||
"setup:patches": "bun --filter=@blitzkit/scripts run setup:patches",
|
|
||||||
"start:website": "bun --filter=@blitzkit/website run start",
|
|
||||||
"host:docs": "vitepress preview docs",
|
|
||||||
"lint": "tsc",
|
|
||||||
"lint:website": "cd packages/website && bun run lint",
|
|
||||||
"format": "prettier --write \"**/*.@(json|js|jsx|css|md|ts|tsx|html|xml|yml|gltf)\"",
|
|
||||||
"update": "yarn upgrade --latest",
|
|
||||||
"tunnel": "cloudflared tunnel --url http://localhost:3000",
|
|
||||||
"discoverids": "scripts/discoverIds.ts",
|
|
||||||
"build:protos": "cd packages/scripts && bun run build:protos",
|
|
||||||
"preview:website": "cd packages/website && bun run preview",
|
|
||||||
"build:reviews": "cd packages/scripts && bun build:reviews",
|
|
||||||
"build:ids": "cd packages/scripts && bun build:ids",
|
|
||||||
"prunestrings": "cd packages/scripts && bun prunestrings",
|
|
||||||
"setup": "bun install && bun run build:prisma && bun run build:protos && bun run build:proxyclient",
|
|
||||||
"patchnotes": "cd packages/scripts && bun run patchnotes"
|
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@prisma/client": "^6.18.0",
|
"@gltf-transform/extensions": "^4.4.2",
|
||||||
"prisma": "^6.18.0",
|
"lz4js": "^0.2.0",
|
||||||
"sharp": "^0.34.5",
|
"sharp": "^0.34.5",
|
||||||
"typescript": "^5.9.3"
|
"typescript": "^5.9.3"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@blitzkit/app",
|
|
||||||
"private": true,
|
|
||||||
"type": "module",
|
|
||||||
"scripts": {
|
|
||||||
"dev": "vite",
|
|
||||||
"build": "tsc && vite build",
|
|
||||||
"preview": "vite preview",
|
|
||||||
"tauri": "tauri"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@tauri-apps/api": "^2",
|
|
||||||
"@tauri-apps/plugin-opener": "^2",
|
|
||||||
"@tauri-apps/cli": "^2",
|
|
||||||
"vite": "^6.0.3",
|
|
||||||
"typescript": "~5.6.2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
# Generated by Cargo
|
|
||||||
# will have compiled files and executables
|
|
||||||
/target/
|
|
||||||
|
|
||||||
# Generated by Tauri
|
|
||||||
# will have schema files for capabilities auto-completion
|
|
||||||
/gen/schemas
|
|
||||||
Generated
-5286
File diff suppressed because it is too large.
Load diff
@@ -1,25 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "blitzkit"
|
|
||||||
version = "0.1.0"
|
|
||||||
description = "A Tauri App"
|
|
||||||
authors = ["you"]
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
# The `_lib` suffix may seem redundant but it is necessary
|
|
||||||
# to make the lib name unique and wouldn't conflict with the bin name.
|
|
||||||
# This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519
|
|
||||||
name = "blitzkit_lib"
|
|
||||||
crate-type = ["staticlib", "cdylib", "rlib"]
|
|
||||||
|
|
||||||
[build-dependencies]
|
|
||||||
tauri-build = { version = "2", features = [] }
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
tauri = { version = "2", features = [] }
|
|
||||||
tauri-plugin-opener = "2"
|
|
||||||
serde = { version = "1", features = ["derive"] }
|
|
||||||
serde_json = "1"
|
|
||||||
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
fn main() {
|
|
||||||
tauri_build::build()
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "../gen/schemas/desktop-schema.json",
|
|
||||||
"identifier": "default",
|
|
||||||
"description": "Capability for the main window",
|
|
||||||
"windows": ["main"],
|
|
||||||
"permissions": [
|
|
||||||
"core:default",
|
|
||||||
"opener:default"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
|
|
||||||
#[tauri::command]
|
|
||||||
fn greet(name: &str) -> String {
|
|
||||||
format!("Hello, {}! You've been greeted from Rust!", name)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
|
||||||
pub fn run() {
|
|
||||||
tauri::Builder::default()
|
|
||||||
.plugin(tauri_plugin_opener::init())
|
|
||||||
.invoke_handler(tauri::generate_handler![greet])
|
|
||||||
.run(tauri::generate_context!())
|
|
||||||
.expect("error while running tauri application");
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
|
||||||
|
|
||||||
use std::process::{Command, Stdio};
|
|
||||||
use tauri::Manager;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
tauri::Builder::default()
|
|
||||||
.setup(|app| {
|
|
||||||
let app_handle = app.handle();
|
|
||||||
|
|
||||||
let entry = app_handle
|
|
||||||
.path_resolver()
|
|
||||||
.resolve_resource("../../dist/website/server/entry.mjs")
|
|
||||||
.expect("failed to resolve server.ts");
|
|
||||||
|
|
||||||
Command::new("bun")
|
|
||||||
.arg("run")
|
|
||||||
.arg(entry)
|
|
||||||
.stderr(Stdio::null())
|
|
||||||
.spawn()
|
|
||||||
.expect("failed to start Bun server");
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
})
|
|
||||||
.run(tauri::generate_context!())
|
|
||||||
.expect("error while running Tauri app");
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
|
||||||
"productName": "blitzkit",
|
|
||||||
"version": "0.1.0",
|
|
||||||
"identifier": "com.tresabhi.blitzkit",
|
|
||||||
"build": {
|
|
||||||
"beforeDevCommand": "cd ../website && bun run dev",
|
|
||||||
"_beforeBuildCommand": "cd ../website && bun run build",
|
|
||||||
"frontendDist": "../../../dist/website/client",
|
|
||||||
"devUrl": "http://localhost:4321"
|
|
||||||
},
|
|
||||||
"app": {
|
|
||||||
"withGlobalTauri": true,
|
|
||||||
"windows": [
|
|
||||||
{
|
|
||||||
"url": "http://localhost:4321",
|
|
||||||
"title": "BlitzKit",
|
|
||||||
"fullscreen": false,
|
|
||||||
"resizable": true,
|
|
||||||
"maximized": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"security": {
|
|
||||||
"csp": null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"bundle": {
|
|
||||||
"active": true,
|
|
||||||
"targets": "all",
|
|
||||||
"icon": [
|
|
||||||
"icons/32x32.png",
|
|
||||||
"icons/128x128.png",
|
|
||||||
"icons/[email protected]",
|
|
||||||
"icons/icon.icns",
|
|
||||||
"icons/icon.ico"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": ["../../tsconfig.json"],
|
|
||||||
"compilerOptions": {
|
|
||||||
"target": "ES2020",
|
|
||||||
"useDefineForClassFields": true,
|
|
||||||
"module": "ESNext",
|
|
||||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"moduleResolution": "bundler",
|
|
||||||
"allowImportingTsExtensions": true,
|
|
||||||
"resolveJsonModule": true,
|
|
||||||
"isolatedModules": true,
|
|
||||||
"noEmit": true,
|
|
||||||
"strict": true,
|
|
||||||
"noUnusedLocals": true,
|
|
||||||
"noUnusedParameters": true,
|
|
||||||
"noFallthroughCasesInSwitch": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@blitzkit/bot",
|
|
||||||
"dependencies": {
|
|
||||||
"@blitzkit/core": "workspace:*",
|
|
||||||
"@blitzkit/i18n": "workspace:*",
|
|
||||||
"@radix-ui/colors": "^3.0.0",
|
|
||||||
"@radix-ui/themes": "^3.3.0",
|
|
||||||
"@resvg/resvg-js": "^2.6.2",
|
|
||||||
"@types/adm-zip": "^0.5.7",
|
|
||||||
"@types/bun": "^1.3.9",
|
|
||||||
"@types/lodash-es": "^4.17.12",
|
|
||||||
"@types/markdown-escape": "^1.1.3",
|
|
||||||
"@types/react": "^19.2.14",
|
|
||||||
"adm-zip": "^0.5.16",
|
|
||||||
"bepaint": "^0.1.0-beta.3",
|
|
||||||
"discord.js": "^14.25.1",
|
|
||||||
"dotenv": "^17.3.1",
|
|
||||||
"fuzzysort": "^3.1.0",
|
|
||||||
"lodash-es": "^4.17.23",
|
|
||||||
"markdown-escape": "^2.0.0",
|
|
||||||
"pickleparser": "^0.2.1",
|
|
||||||
"prisma": "^6.19.2",
|
|
||||||
"protobufjs": "^7.5.4",
|
|
||||||
"react": "^19.2.4",
|
|
||||||
"satori": "^0.18.4",
|
|
||||||
"sharp": "^0.34.5"
|
|
||||||
},
|
|
||||||
"private": true,
|
|
||||||
"scripts": {
|
|
||||||
"dev": "bun --watch src/main.ts",
|
|
||||||
"start": "bun src/main.ts"
|
|
||||||
},
|
|
||||||
"type": "module",
|
|
||||||
"types": "src/types.d.ts"
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
|
|
||||||
import { translator } from "../core/localization/translator";
|
|
||||||
import {
|
|
||||||
commandsArray,
|
|
||||||
type CommandRegistry,
|
|
||||||
} from "../events/interactionCreate";
|
|
||||||
|
|
||||||
const subcommands = [
|
|
||||||
"embeds",
|
|
||||||
"introduction",
|
|
||||||
"invite",
|
|
||||||
"timezones",
|
|
||||||
"credits",
|
|
||||||
] as const;
|
|
||||||
type Subcommand = (typeof subcommands)[number];
|
|
||||||
|
|
||||||
const DOCS: Record<Subcommand, string> = {
|
|
||||||
embeds: "guide/embeds",
|
|
||||||
introduction: "guide/introduction",
|
|
||||||
invite: "guide/invite",
|
|
||||||
timezones: "guide/timezones",
|
|
||||||
credits: "about/credits",
|
|
||||||
};
|
|
||||||
|
|
||||||
export const aboutCommand = new Promise<CommandRegistry>(async (resolve) => {
|
|
||||||
resolve({
|
|
||||||
command: createLocalizedCommand("about", [
|
|
||||||
{ subcommand: "commands" },
|
|
||||||
...subcommands.map((subcommand) => ({ subcommand })),
|
|
||||||
]),
|
|
||||||
|
|
||||||
async handler(interaction) {
|
|
||||||
const subcommand = interaction.options.getSubcommand();
|
|
||||||
const { strings } = translator(interaction.locale);
|
|
||||||
|
|
||||||
if (subcommand === "commands") {
|
|
||||||
return `${strings.bot.commands.about.subcommands.commands.body}${(
|
|
||||||
await Promise.all(commandsArray)
|
|
||||||
)
|
|
||||||
.sort((a, b) =>
|
|
||||||
(a.command.name_localizations?.[interaction.locale] ??
|
|
||||||
a.command.name) <
|
|
||||||
(b.command.name_localizations?.[interaction.locale] ??
|
|
||||||
b.command.name)
|
|
||||||
? -1
|
|
||||||
: 1,
|
|
||||||
)
|
|
||||||
.map(
|
|
||||||
(registry) =>
|
|
||||||
`- \`/${
|
|
||||||
registry.command.name_localizations?.[interaction.locale] ??
|
|
||||||
registry.command.name
|
|
||||||
}\`: ${
|
|
||||||
registry.command.description_localizations?.[
|
|
||||||
interaction.locale
|
|
||||||
] ?? registry.command.description
|
|
||||||
}`,
|
|
||||||
)
|
|
||||||
.join("\n")}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const url = `https://raw.githubusercontent.com/tresabhi/blitzkit/main/docs/${DOCS[subcommand as Subcommand]}.md`;
|
|
||||||
const content = fetch(url).then((response) => response.text());
|
|
||||||
|
|
||||||
return content;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
import { addPeriodicFilterOptions } from "../../core/discord/addPeriodicFilterOptions";
|
|
||||||
import { addUsernameChoices } from "../../core/discord/addUsernameChoices";
|
|
||||||
import { autocompleteTanks } from "../../core/discord/autocompleteTanks";
|
|
||||||
import { autocompleteUsername } from "../../core/discord/autocompleteUsername";
|
|
||||||
import { createLocalizedCommand } from "../../core/discord/createLocalizedCommand";
|
|
||||||
import { getFiltersFromButton } from "../../core/discord/getFiltersFromButton";
|
|
||||||
import { resolvePeriodFromButton } from "../../core/discord/resolvePeriodFromButton";
|
|
||||||
import { resolvePlayerFromButton } from "../../core/discord/resolvePlayerFromButton";
|
|
||||||
import { translator } from "../../core/localization/translator";
|
|
||||||
import type { CommandRegistry } from "../../events/interactionCreate";
|
|
||||||
import { renderBreakdown } from "./render";
|
|
||||||
|
|
||||||
export const breakdownCommand = new Promise<CommandRegistry>(
|
|
||||||
async (resolve) => {
|
|
||||||
resolve({
|
|
||||||
command: await addPeriodicFilterOptions(
|
|
||||||
createLocalizedCommand("breakdown"),
|
|
||||||
(option) => option.addStringOption(addUsernameChoices),
|
|
||||||
),
|
|
||||||
|
|
||||||
async handler(interaction) {
|
|
||||||
const { strings } = translator(interaction.locale);
|
|
||||||
return strings.bot.commands.dead;
|
|
||||||
|
|
||||||
// const player = await resolvePlayerFromCommand(interaction);
|
|
||||||
// const period = resolvePeriodFromCommand(player.region, interaction);
|
|
||||||
// const filters = await getFiltersFromCommand(interaction);
|
|
||||||
// const path = commandToURL(interaction, {
|
|
||||||
// ...player,
|
|
||||||
// ...getCustomPeriodParams(interaction),
|
|
||||||
// ...filters,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// return [
|
|
||||||
// ...(await renderBreakdown(
|
|
||||||
// player,
|
|
||||||
// period,
|
|
||||||
// filters,
|
|
||||||
// interaction.locale,
|
|
||||||
// )),
|
|
||||||
// buttonRefresh(interaction, path),
|
|
||||||
// await getBlitzStarsLinkButton(player.region, player.id),
|
|
||||||
// ];
|
|
||||||
},
|
|
||||||
|
|
||||||
autocomplete: (interaction) => {
|
|
||||||
autocompleteUsername(interaction);
|
|
||||||
autocompleteTanks(interaction);
|
|
||||||
},
|
|
||||||
|
|
||||||
async button(interaction) {
|
|
||||||
const player = await resolvePlayerFromButton(interaction);
|
|
||||||
const period = resolvePeriodFromButton(player.region, interaction);
|
|
||||||
const filters = getFiltersFromButton(interaction);
|
|
||||||
|
|
||||||
return await renderBreakdown(
|
|
||||||
player,
|
|
||||||
period,
|
|
||||||
filters,
|
|
||||||
interaction.locale,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
@@ -1,295 +0,0 @@
|
|||||||
import {
|
|
||||||
type BlitzStats,
|
|
||||||
calculateWN8,
|
|
||||||
getAccountInfo,
|
|
||||||
getClanAccountInfo,
|
|
||||||
getTankStats,
|
|
||||||
getWN8Percentile,
|
|
||||||
TankDefinition,
|
|
||||||
} from "@blitzkit/core";
|
|
||||||
import { literals } from "@blitzkit/i18n";
|
|
||||||
import { Locale } from "discord.js";
|
|
||||||
import { chunk } from "lodash-es";
|
|
||||||
import * as Breakdown from "../../components/Breakdown";
|
|
||||||
import { CommandWrapper } from "../../components/CommandWrapper";
|
|
||||||
import { NoData } from "../../components/NoData";
|
|
||||||
import { TitleBar } from "../../components/TitleBar";
|
|
||||||
import { filtersToDescription } from "../../core/blitzkit/filtersToDescription";
|
|
||||||
import {
|
|
||||||
averageDefinitions,
|
|
||||||
tankDefinitions,
|
|
||||||
} from "../../core/blitzkit/nonBlockingPromises";
|
|
||||||
import { UserError } from "../../core/blitzkit/userError";
|
|
||||||
import {
|
|
||||||
filterStats,
|
|
||||||
type StatFilters,
|
|
||||||
} from "../../core/blitzstars/filterStats";
|
|
||||||
import { getStatsInPeriod } from "../../core/blitzstars/getStatsInPeriod";
|
|
||||||
import type { ResolvedPeriod } from "../../core/discord/resolvePeriodFromCommand";
|
|
||||||
import type { ResolvedPlayer } from "../../core/discord/resolvePlayerFromCommand";
|
|
||||||
import { translator } from "../../core/localization/translator";
|
|
||||||
|
|
||||||
const ROWS_PER_PAGE = 8;
|
|
||||||
const MAX_PAGES = 9;
|
|
||||||
|
|
||||||
export async function renderBreakdown(
|
|
||||||
{ region, id }: ResolvedPlayer,
|
|
||||||
{ start, end, name }: ResolvedPeriod,
|
|
||||||
filters: StatFilters,
|
|
||||||
locale: Locale,
|
|
||||||
) {
|
|
||||||
const { strings, unwrap } = translator(locale);
|
|
||||||
const awaitedTankDefinitions = await tankDefinitions;
|
|
||||||
const awaitedTankAverages = await averageDefinitions;
|
|
||||||
const statsInPeriod = await getStatsInPeriod(region, id, start, end, locale);
|
|
||||||
const { filteredOrder } = await filterStats(statsInPeriod, filters);
|
|
||||||
const accountInfo = await getAccountInfo(region, id);
|
|
||||||
const clanData = await getClanAccountInfo(region, id, ["clan"]);
|
|
||||||
const tankStats = await getTankStats(region, id);
|
|
||||||
const filterDescriptions = await filtersToDescription(filters, locale);
|
|
||||||
const orderedCurrentStats: BlitzStats[] = [];
|
|
||||||
const orderedCareerStats: BlitzStats[] = [];
|
|
||||||
const orderedCurrentWN8: (number | undefined)[] = [];
|
|
||||||
const orderedCareerWN8: (number | undefined)[] = [];
|
|
||||||
const orderedCareerWN8Full: (number | undefined)[] = [];
|
|
||||||
|
|
||||||
if (tankStats === null) {
|
|
||||||
throw new UserError(strings.bot.common.errors.no_tank_stats);
|
|
||||||
}
|
|
||||||
|
|
||||||
filteredOrder.forEach((id) => {
|
|
||||||
const tankAveragesEntry = awaitedTankAverages.averages[id];
|
|
||||||
const current = statsInPeriod.diff[id];
|
|
||||||
const career = tankStats.find((tank) => tank.tank_id === id)!.all;
|
|
||||||
const currentWN8 = tankAveragesEntry
|
|
||||||
? calculateWN8(tankAveragesEntry.mu, current)
|
|
||||||
: undefined;
|
|
||||||
const careerWN8 = tankAveragesEntry
|
|
||||||
? calculateWN8(tankAveragesEntry.mu, career)
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
orderedCurrentStats.push(current);
|
|
||||||
orderedCareerStats.push(career);
|
|
||||||
orderedCurrentWN8.push(currentWN8);
|
|
||||||
orderedCareerWN8.push(careerWN8);
|
|
||||||
});
|
|
||||||
tankStats.forEach((tank) => {
|
|
||||||
const tankAveragesEntry = awaitedTankAverages.averages[tank.tank_id];
|
|
||||||
|
|
||||||
orderedCareerWN8Full.push(
|
|
||||||
tankAveragesEntry
|
|
||||||
? calculateWN8(tankAveragesEntry.mu, tank.all)
|
|
||||||
: undefined,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
const currentBattles = orderedCurrentStats.reduce(
|
|
||||||
(accumulator, current) => accumulator + current.battles,
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
const careerBattles = tankStats.reduce(
|
|
||||||
(accumulator, current) => accumulator + current.all.battles,
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
const currentWinrate =
|
|
||||||
orderedCurrentStats.reduce(
|
|
||||||
(accumulator, current) => accumulator + current.wins,
|
|
||||||
0,
|
|
||||||
) / currentBattles;
|
|
||||||
const careerWinrate =
|
|
||||||
tankStats.reduce(
|
|
||||||
(accumulator, current) => accumulator + current.all.wins,
|
|
||||||
0,
|
|
||||||
) / careerBattles;
|
|
||||||
const currentWN8 =
|
|
||||||
orderedCurrentWN8.reduce<number>(
|
|
||||||
(accumulator, current, index) =>
|
|
||||||
accumulator + (current ?? 0) * orderedCurrentStats[index].battles,
|
|
||||||
0,
|
|
||||||
) /
|
|
||||||
orderedCurrentStats.reduce(
|
|
||||||
(accumulator, current, index) =>
|
|
||||||
accumulator +
|
|
||||||
(orderedCurrentWN8[index] === undefined ? 0 : current.battles),
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
const careerWN8 =
|
|
||||||
orderedCareerWN8Full.reduce<number>(
|
|
||||||
(accumulator, current) => accumulator + (current ?? 0),
|
|
||||||
0,
|
|
||||||
) /
|
|
||||||
tankStats.reduce(
|
|
||||||
(accumulator, current, index) =>
|
|
||||||
accumulator +
|
|
||||||
(orderedCareerWN8Full[index] === undefined ? 0 : current.all.battles),
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
const currentDamage =
|
|
||||||
orderedCurrentStats.reduce(
|
|
||||||
(accumulator, current) => accumulator + current.damage_dealt,
|
|
||||||
0,
|
|
||||||
) / currentBattles;
|
|
||||||
const careerDamage =
|
|
||||||
tankStats.reduce(
|
|
||||||
(accumulator, current) => accumulator + current.all.damage_dealt,
|
|
||||||
0,
|
|
||||||
) / careerBattles;
|
|
||||||
|
|
||||||
const children: React.JSX.Element[] = [];
|
|
||||||
|
|
||||||
if (filteredOrder.length > 0) {
|
|
||||||
children.push(
|
|
||||||
<Breakdown.Row
|
|
||||||
key={id}
|
|
||||||
displayType="summary"
|
|
||||||
title={strings.bot.commands.breakdown.body.total}
|
|
||||||
stats={[
|
|
||||||
{
|
|
||||||
title: strings.bot.commands.breakdown.body.battles,
|
|
||||||
current: currentBattles,
|
|
||||||
career: careerBattles,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: strings.bot.commands.breakdown.body.winrate,
|
|
||||||
current: `${(100 * currentWinrate).toFixed(2)}%`,
|
|
||||||
career: `${(100 * careerWinrate).toFixed(2)}%`,
|
|
||||||
delta: currentWinrate - careerWinrate,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: strings.bot.commands.breakdown.body.wn8,
|
|
||||||
current:
|
|
||||||
currentWN8 === undefined
|
|
||||||
? undefined
|
|
||||||
: Math.round(currentWN8).toLocaleString(),
|
|
||||||
career:
|
|
||||||
careerWN8 === undefined
|
|
||||||
? undefined
|
|
||||||
: Math.round(careerWN8).toLocaleString(),
|
|
||||||
percentile:
|
|
||||||
currentWN8 === undefined
|
|
||||||
? undefined
|
|
||||||
: getWN8Percentile(currentWN8),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: strings.bot.commands.breakdown.body.damage,
|
|
||||||
current: Math.round(currentDamage).toLocaleString(),
|
|
||||||
career: Math.round(careerDamage).toLocaleString(),
|
|
||||||
delta: currentDamage - careerDamage,
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
/>,
|
|
||||||
);
|
|
||||||
|
|
||||||
filteredOrder.forEach((id, index) => {
|
|
||||||
const tankDefinition = awaitedTankDefinitions.tanks[id] as
|
|
||||||
| TankDefinition
|
|
||||||
| undefined;
|
|
||||||
const current = orderedCurrentStats[index];
|
|
||||||
const career = orderedCareerStats[index];
|
|
||||||
const currentWN8 = orderedCurrentWN8[index];
|
|
||||||
const careerWN8 = orderedCareerWN8[index];
|
|
||||||
|
|
||||||
children.push(
|
|
||||||
<Breakdown.Row
|
|
||||||
key={id}
|
|
||||||
displayType="tank"
|
|
||||||
class={tankDefinition?.class}
|
|
||||||
type={tankDefinition?.type}
|
|
||||||
title={
|
|
||||||
tankDefinition
|
|
||||||
? unwrap(tankDefinition.name)
|
|
||||||
: literals(strings.bot.commands.breakdown.body.unknown_tank, {
|
|
||||||
id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
stats={[
|
|
||||||
{
|
|
||||||
title: strings.bot.commands.breakdown.body.battles,
|
|
||||||
current: current.battles.toLocaleString(),
|
|
||||||
career: career.battles.toLocaleString(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: strings.bot.commands.breakdown.body.winrate,
|
|
||||||
current: `${(100 * (current.wins / current.battles)).toFixed(
|
|
||||||
2,
|
|
||||||
)}%`,
|
|
||||||
career: `${(100 * (career.wins / career.battles)).toFixed(2)}%`,
|
|
||||||
delta:
|
|
||||||
current.wins / current.battles - career.wins / career.battles,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: strings.bot.commands.breakdown.body.wn8,
|
|
||||||
current:
|
|
||||||
currentWN8 === undefined
|
|
||||||
? undefined
|
|
||||||
: Math.round(currentWN8).toLocaleString(),
|
|
||||||
career:
|
|
||||||
careerWN8 === undefined
|
|
||||||
? undefined
|
|
||||||
: Math.round(careerWN8).toLocaleString(),
|
|
||||||
percentile:
|
|
||||||
currentWN8 === undefined
|
|
||||||
? undefined
|
|
||||||
: getWN8Percentile(currentWN8),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: strings.bot.commands.breakdown.body.damage,
|
|
||||||
current: Math.round(
|
|
||||||
current.damage_dealt / current.battles,
|
|
||||||
).toLocaleString(),
|
|
||||||
career: Math.round(
|
|
||||||
career.damage_dealt / career.battles,
|
|
||||||
).toLocaleString(),
|
|
||||||
delta:
|
|
||||||
current.damage_dealt / current.battles -
|
|
||||||
career.damage_dealt / career.battles,
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
/>,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const pages = chunk(
|
|
||||||
children,
|
|
||||||
Math.max(Math.ceil(children.length / MAX_PAGES), ROWS_PER_PAGE),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (filteredOrder.length > 0) {
|
|
||||||
return pages
|
|
||||||
.map((page, index) => (
|
|
||||||
<CommandWrapper>
|
|
||||||
{index === 0 && (
|
|
||||||
<TitleBar
|
|
||||||
title={accountInfo.nickname}
|
|
||||||
image={
|
|
||||||
clanData?.clan
|
|
||||||
? `https://wotblitz-gc.gcdn.co/icons/clanEmblems1x/clan-icon-v2-${clanData?.clan?.emblem_set_id}.png`
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
description={`${name} • ${filterDescriptions}`}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Breakdown.Root>{page}</Breakdown.Root>
|
|
||||||
</CommandWrapper>
|
|
||||||
))
|
|
||||||
.reverse();
|
|
||||||
} else {
|
|
||||||
return [
|
|
||||||
<CommandWrapper>
|
|
||||||
<TitleBar
|
|
||||||
title={accountInfo.nickname}
|
|
||||||
image={
|
|
||||||
clanData?.clan
|
|
||||||
? `https://wotblitz-gc.gcdn.co/icons/clanEmblems1x/clan-icon-v2-${clanData?.clan?.emblem_set_id}.png`
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
description={`${name} • ${filterDescriptions}`}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<NoData type="battles_in_period" locale={locale} />
|
|
||||||
</CommandWrapper>,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
import packageJSON from "../../../../package.json";
|
|
||||||
import { client } from "../core/discord/client";
|
|
||||||
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
|
|
||||||
import { translator } from "../core/localization/translator";
|
|
||||||
import type { CommandRegistry } from "../events/interactionCreate";
|
|
||||||
|
|
||||||
const executionStart = new Date().getTime();
|
|
||||||
|
|
||||||
export const debugCommand = new Promise<CommandRegistry>((resolve) => {
|
|
||||||
resolve({
|
|
||||||
command: createLocalizedCommand("debug"),
|
|
||||||
|
|
||||||
async handler(interaction) {
|
|
||||||
const { strings } = translator(interaction.locale);
|
|
||||||
const currentTime = new Date().getTime();
|
|
||||||
const uptime = currentTime - executionStart;
|
|
||||||
const list = [
|
|
||||||
[strings.bot.commands.debug.body.version, packageJSON.version],
|
|
||||||
[
|
|
||||||
strings.bot.commands.debug.body.shard.label,
|
|
||||||
client.shard?.ids[0] ?? strings.bot.commands.debug.body.shard.default,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
strings.bot.commands.debug.body.uptime,
|
|
||||||
`${Math.floor((uptime / 1000 / 60 / 60) % 24)}h ${Math.floor(
|
|
||||||
(uptime / 1000 / 60) % 60
|
|
||||||
)}m ${Math.floor((uptime / 1000) % 60)}s ${Math.floor(
|
|
||||||
uptime % 1000
|
|
||||||
)}ms`,
|
|
||||||
],
|
|
||||||
];
|
|
||||||
return `${strings.bot.commands.debug.body.title}${list
|
|
||||||
.map(([key, value]) => `- ${key}: ${value}`)
|
|
||||||
.join("\n")}`;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,182 +0,0 @@
|
|||||||
import { emblemURL, getAccountInfo, getClanAccountInfo } from "@blitzkit/core";
|
|
||||||
import { Locale, SlashCommandSubcommandGroupBuilder } from "discord.js";
|
|
||||||
import { CommandWrapper } from "../components/CommandWrapper";
|
|
||||||
import * as Graph from "../components/Graph";
|
|
||||||
import { LineColor } from "../components/Graph/components/Line/constants";
|
|
||||||
import { NoData } from "../components/NoData";
|
|
||||||
import { TitleBar } from "../components/TitleBar";
|
|
||||||
import { getPlayerHistories } from "../core/blitzstars/getPlayerHistories";
|
|
||||||
import { getTankHistories } from "../core/blitzstars/getTankHistories";
|
|
||||||
import { addPeriodSubCommands } from "../core/discord/addPeriodSubCommands";
|
|
||||||
import { addTankChoices } from "../core/discord/addTankChoices";
|
|
||||||
import { addUsernameChoices } from "../core/discord/addUsernameChoices";
|
|
||||||
import { autocompleteTanks } from "../core/discord/autocompleteTanks";
|
|
||||||
import { autocompleteUsername } from "../core/discord/autocompleteUsername";
|
|
||||||
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
|
|
||||||
import { resolvePeriodFromButton } from "../core/discord/resolvePeriodFromButton";
|
|
||||||
import { type ResolvedPeriod } from "../core/discord/resolvePeriodFromCommand";
|
|
||||||
import { resolvePlayerFromButton } from "../core/discord/resolvePlayerFromButton";
|
|
||||||
import { type ResolvedPlayer } from "../core/discord/resolvePlayerFromCommand";
|
|
||||||
import { translator } from "../core/localization/translator";
|
|
||||||
import type { CommandRegistry } from "../events/interactionCreate";
|
|
||||||
|
|
||||||
type EvolutionStatType = "player" | "tank";
|
|
||||||
|
|
||||||
async function render(
|
|
||||||
{ region, id }: ResolvedPlayer,
|
|
||||||
{ start, end, name }: ResolvedPeriod,
|
|
||||||
type: "player" | "tank",
|
|
||||||
tankId: number | null,
|
|
||||||
locale: Locale,
|
|
||||||
) {
|
|
||||||
const accountInfo = await getAccountInfo(region, id);
|
|
||||||
const clan = (await getClanAccountInfo(region, id, ["clan"]))?.clan;
|
|
||||||
const logo = clan ? emblemURL(clan.emblem_set_id) : undefined;
|
|
||||||
const histories = await (type === "player"
|
|
||||||
? getPlayerHistories(region, id, {
|
|
||||||
start,
|
|
||||||
end,
|
|
||||||
includeLatestHistories: true,
|
|
||||||
includePreviousHistories: true,
|
|
||||||
})
|
|
||||||
: getTankHistories(region, id, locale, {
|
|
||||||
tankId: tankId!,
|
|
||||||
start,
|
|
||||||
end,
|
|
||||||
includeLatestHistories: true,
|
|
||||||
includePreviousHistories: true,
|
|
||||||
}));
|
|
||||||
const plot = histories.map(
|
|
||||||
(history) =>
|
|
||||||
[
|
|
||||||
history.all.battles,
|
|
||||||
(history.all.wins / history.all.battles) * 100,
|
|
||||||
] as Graph.PlotItem,
|
|
||||||
);
|
|
||||||
const times = histories.map((history) => history.last_battle_time);
|
|
||||||
const minTime = Math.min(...times);
|
|
||||||
const maxTime = Math.max(...times);
|
|
||||||
const ys = plot.map(([, y]) => y);
|
|
||||||
const xs = plot.map(([x]) => x);
|
|
||||||
const maxY = Math.max(...ys);
|
|
||||||
const minY = Math.min(...ys);
|
|
||||||
const maxX = Math.max(...xs);
|
|
||||||
const minX = Math.min(...xs);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<CommandWrapper>
|
|
||||||
<TitleBar title={accountInfo.nickname} image={logo} description={name} />
|
|
||||||
|
|
||||||
{plot.length > 0 && (
|
|
||||||
<Graph.Root
|
|
||||||
verticalMargin={{
|
|
||||||
min: minY,
|
|
||||||
max: maxY,
|
|
||||||
suffix: "%",
|
|
||||||
precision: 2,
|
|
||||||
}}
|
|
||||||
horizontalMargin={{
|
|
||||||
min: minX,
|
|
||||||
max: maxX,
|
|
||||||
precision: 0,
|
|
||||||
}}
|
|
||||||
xMinLabel={new Date(minTime * 1000).toLocaleDateString(locale)}
|
|
||||||
xMaxLabel={new Date(maxTime * 1000).toLocaleDateString(locale)}
|
|
||||||
>
|
|
||||||
{Graph.Line({
|
|
||||||
color: LineColor.Red,
|
|
||||||
plot: plot,
|
|
||||||
minY,
|
|
||||||
maxY,
|
|
||||||
})}
|
|
||||||
</Graph.Root>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{plot.length === 0 && <NoData type="battles_in_period" locale={locale} />}
|
|
||||||
</CommandWrapper>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const evolutionCommand = new Promise<CommandRegistry>(
|
|
||||||
async (resolve) => {
|
|
||||||
resolve({
|
|
||||||
command: createLocalizedCommand("evolution", [
|
|
||||||
{
|
|
||||||
group: "player",
|
|
||||||
modify(option: SlashCommandSubcommandGroupBuilder) {
|
|
||||||
addPeriodSubCommands(option, (option) =>
|
|
||||||
option.addStringOption(addUsernameChoices),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
group: "tank",
|
|
||||||
modify(option: SlashCommandSubcommandGroupBuilder) {
|
|
||||||
addPeriodSubCommands(option, (option) =>
|
|
||||||
option
|
|
||||||
.addStringOption(addTankChoices)
|
|
||||||
.addStringOption(addUsernameChoices),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
|
|
||||||
async handler(interaction) {
|
|
||||||
const { strings } = translator(interaction.locale);
|
|
||||||
return strings.bot.commands.dead;
|
|
||||||
|
|
||||||
// const commandGroup =
|
|
||||||
// interaction.options.getSubcommandGroup() as EvolutionStatType;
|
|
||||||
// const player = await resolvePlayerFromCommand(interaction);
|
|
||||||
// const period = resolvePeriodFromCommand(player.region, interaction);
|
|
||||||
// const tankIdRaw = interaction.options.getString("tank")!;
|
|
||||||
// const tankId =
|
|
||||||
// commandGroup === "tank"
|
|
||||||
// ? await resolveTankId(tankIdRaw, interaction.locale)
|
|
||||||
// : null;
|
|
||||||
// const path = commandToURL(interaction, {
|
|
||||||
// ...player,
|
|
||||||
// ...getCustomPeriodParams(interaction),
|
|
||||||
// tankId,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// return [
|
|
||||||
// await render(
|
|
||||||
// player,
|
|
||||||
// period,
|
|
||||||
// commandGroup,
|
|
||||||
// tankId,
|
|
||||||
// interaction.locale
|
|
||||||
// ),
|
|
||||||
// buttonRefresh(interaction, path),
|
|
||||||
// await getBlitzStarsLinkButton(
|
|
||||||
// player.region,
|
|
||||||
// player.id,
|
|
||||||
// tankId ?? undefined
|
|
||||||
// ),
|
|
||||||
// ];
|
|
||||||
},
|
|
||||||
|
|
||||||
autocomplete: (interaction) => {
|
|
||||||
autocompleteUsername(interaction);
|
|
||||||
autocompleteTanks(interaction);
|
|
||||||
},
|
|
||||||
|
|
||||||
async button(interaction) {
|
|
||||||
const url = new URL(`https://example.com/${interaction.customId}`);
|
|
||||||
const path = url.pathname.split("/");
|
|
||||||
const commandGroup = path[2] as EvolutionStatType;
|
|
||||||
const player = await resolvePlayerFromButton(interaction);
|
|
||||||
const period = resolvePeriodFromButton(player.region, interaction);
|
|
||||||
|
|
||||||
return await render(
|
|
||||||
player,
|
|
||||||
period,
|
|
||||||
commandGroup,
|
|
||||||
parseInt(url.searchParams.get("tankId") ?? "0") || null,
|
|
||||||
interaction.locale,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
import {
|
|
||||||
emblemURL,
|
|
||||||
getAccountInfo,
|
|
||||||
getClanAccountInfo,
|
|
||||||
getTierWeights,
|
|
||||||
} from "@blitzkit/core";
|
|
||||||
import { Locale } from "discord.js";
|
|
||||||
import { CommandWrapper } from "../components/CommandWrapper";
|
|
||||||
import { GenericAllStats } from "../components/GenericAllStats";
|
|
||||||
import { NoData } from "../components/NoData";
|
|
||||||
import { TierWeights } from "../components/TierWeights";
|
|
||||||
import { TitleBar } from "../components/TitleBar";
|
|
||||||
import { filtersToDescription } from "../core/blitzkit/filtersToDescription";
|
|
||||||
import { filterStats, type StatFilters } from "../core/blitzstars/filterStats";
|
|
||||||
import { getStatsInPeriod } from "../core/blitzstars/getStatsInPeriod";
|
|
||||||
import { addPeriodicFilterOptions } from "../core/discord/addPeriodicFilterOptions";
|
|
||||||
import { addUsernameChoices } from "../core/discord/addUsernameChoices";
|
|
||||||
import { autocompleteTanks } from "../core/discord/autocompleteTanks";
|
|
||||||
import { autocompleteUsername } from "../core/discord/autocompleteUsername";
|
|
||||||
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
|
|
||||||
import { getFiltersFromButton } from "../core/discord/getFiltersFromButton";
|
|
||||||
import { resolvePeriodFromButton } from "../core/discord/resolvePeriodFromButton";
|
|
||||||
import { type ResolvedPeriod } from "../core/discord/resolvePeriodFromCommand";
|
|
||||||
import { resolvePlayerFromButton } from "../core/discord/resolvePlayerFromButton";
|
|
||||||
import { type ResolvedPlayer } from "../core/discord/resolvePlayerFromCommand";
|
|
||||||
import { translator } from "../core/localization/translator";
|
|
||||||
import type { CommandRegistry } from "../events/interactionCreate";
|
|
||||||
|
|
||||||
async function render(
|
|
||||||
{ region, id }: ResolvedPlayer,
|
|
||||||
{ start, end, name }: ResolvedPeriod,
|
|
||||||
filters: StatFilters,
|
|
||||||
locale: Locale,
|
|
||||||
) {
|
|
||||||
const { nickname } = await getAccountInfo(region, id);
|
|
||||||
const clan = (await getClanAccountInfo(region, id, ["clan"]))?.clan;
|
|
||||||
const clanImage = clan ? emblemURL(clan.emblem_set_id) : undefined;
|
|
||||||
const diffedTankStats = await getStatsInPeriod(
|
|
||||||
region,
|
|
||||||
id,
|
|
||||||
start,
|
|
||||||
end,
|
|
||||||
locale,
|
|
||||||
);
|
|
||||||
const { stats, supplementary, filteredOrder } = await filterStats(
|
|
||||||
diffedTankStats,
|
|
||||||
filters,
|
|
||||||
);
|
|
||||||
const filterDescriptions = await filtersToDescription(filters, locale);
|
|
||||||
const tierWeights = await getTierWeights(diffedTankStats.diff, filteredOrder);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<CommandWrapper>
|
|
||||||
<TitleBar
|
|
||||||
title={nickname}
|
|
||||||
image={clanImage}
|
|
||||||
description={`${name} • ${filterDescriptions}`}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{stats.battles === 0 && (
|
|
||||||
<NoData type="battles_in_period" locale={locale} />
|
|
||||||
)}
|
|
||||||
{stats.battles > 0 && <TierWeights weights={tierWeights!} />}
|
|
||||||
{stats.battles > 0 && (
|
|
||||||
<GenericAllStats
|
|
||||||
stats={stats}
|
|
||||||
supplementaryStats={supplementary}
|
|
||||||
locale={locale}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</CommandWrapper>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const fullStatsCommand = new Promise<CommandRegistry>(
|
|
||||||
async (resolve) => {
|
|
||||||
resolve({
|
|
||||||
command: await addPeriodicFilterOptions(
|
|
||||||
createLocalizedCommand("full-stats"),
|
|
||||||
(option) => option.addStringOption(addUsernameChoices),
|
|
||||||
),
|
|
||||||
|
|
||||||
async handler(interaction) {
|
|
||||||
const { strings } = translator(interaction.locale);
|
|
||||||
return strings.bot.commands.dead;
|
|
||||||
|
|
||||||
// const player = await resolvePlayerFromCommand(interaction);
|
|
||||||
// const period = resolvePeriodFromCommand(player.region, interaction);
|
|
||||||
// const filters = await getFiltersFromCommand(interaction);
|
|
||||||
// const path = commandToURL(interaction, {
|
|
||||||
// ...player,
|
|
||||||
// ...getCustomPeriodParams(interaction),
|
|
||||||
// ...filters,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// return Promise.all([
|
|
||||||
// render(player, period, filters, interaction.locale),
|
|
||||||
// buttonRefresh(interaction, path),
|
|
||||||
// getBlitzStarsLinkButton(player.region, player.id),
|
|
||||||
// ]);
|
|
||||||
},
|
|
||||||
|
|
||||||
autocomplete: (interaction) => {
|
|
||||||
autocompleteUsername(interaction);
|
|
||||||
autocompleteTanks(interaction);
|
|
||||||
},
|
|
||||||
|
|
||||||
async button(interaction) {
|
|
||||||
const player = await resolvePlayerFromButton(interaction);
|
|
||||||
const period = resolvePeriodFromButton(player.region, interaction);
|
|
||||||
const filters = getFiltersFromButton(interaction);
|
|
||||||
|
|
||||||
return await render(player, period, filters, interaction.locale);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
import { getAccountInfo, getClanInfo } from "@blitzkit/core";
|
|
||||||
import { literals } from "@blitzkit/i18n";
|
|
||||||
import { Locale } from "discord.js";
|
|
||||||
import { CommandWrapper } from "../components/CommandWrapper";
|
|
||||||
import { GenericStats } from "../components/GenericStats";
|
|
||||||
import { NoData } from "../components/NoData";
|
|
||||||
import { TitleBar } from "../components/TitleBar";
|
|
||||||
import { addClanChoices } from "../core/discord/addClanChoices";
|
|
||||||
import { autocompleteClan } from "../core/discord/autocompleteClan";
|
|
||||||
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
|
|
||||||
import { localizationObject } from "../core/discord/localizationObject";
|
|
||||||
import { resolveClanFromCommand } from "../core/discord/resolveClanFromCommand";
|
|
||||||
import { translator } from "../core/localization/translator";
|
|
||||||
import type { CommandRegistry } from "../events/interactionCreate";
|
|
||||||
|
|
||||||
const DEFAULT_THRESHOLD = 7;
|
|
||||||
|
|
||||||
export const inactiveCommand = new Promise<CommandRegistry>((resolve) => {
|
|
||||||
resolve({
|
|
||||||
command: createLocalizedCommand("inactive")
|
|
||||||
.addStringOption(addClanChoices)
|
|
||||||
.addNumberOption((option) => {
|
|
||||||
const { strings } = translator(Locale.EnglishUS);
|
|
||||||
|
|
||||||
return option
|
|
||||||
.setName("threshold")
|
|
||||||
.setNameLocalizations(
|
|
||||||
localizationObject(
|
|
||||||
(strings) => strings.bot.commands.inactive.options.threshold.name,
|
|
||||||
undefined,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.setDescription(
|
|
||||||
strings.bot.commands.inactive.options.threshold.description
|
|
||||||
)
|
|
||||||
.setDescriptionLocalizations(
|
|
||||||
localizationObject(
|
|
||||||
(strings) =>
|
|
||||||
strings.bot.commands.inactive.options.threshold.description
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.setMinValue(0);
|
|
||||||
}),
|
|
||||||
|
|
||||||
async handler(interaction) {
|
|
||||||
const { strings } = translator(interaction.locale);
|
|
||||||
const { region, id } = await resolveClanFromCommand(interaction);
|
|
||||||
const threshold =
|
|
||||||
interaction.options.getNumber("threshold")! ?? DEFAULT_THRESHOLD;
|
|
||||||
const time = new Date().getTime() / 1000;
|
|
||||||
const clanInfo = await getClanInfo(region, id);
|
|
||||||
const accountInfo = await getAccountInfo(region, clanInfo.members_ids);
|
|
||||||
const inactive = accountInfo
|
|
||||||
.map(
|
|
||||||
(account) =>
|
|
||||||
[
|
|
||||||
account.nickname,
|
|
||||||
(time - account.last_battle_time) / 60 / 60 / 24,
|
|
||||||
] as [string, number]
|
|
||||||
)
|
|
||||||
.filter(([, inactiveDays]) => inactiveDays >= threshold)
|
|
||||||
.sort((a, b) => b[1] - a[1])
|
|
||||||
.map(
|
|
||||||
([name, days]) =>
|
|
||||||
[
|
|
||||||
name,
|
|
||||||
literals(strings.bot.commands.inactive.body.listing, {
|
|
||||||
days: days.toFixed(0),
|
|
||||||
}),
|
|
||||||
] as [string, string]
|
|
||||||
);
|
|
||||||
const hasInactiveMembers = inactive.length > 0;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<CommandWrapper>
|
|
||||||
<TitleBar
|
|
||||||
title={clanInfo.name}
|
|
||||||
image={`https://wotblitz-gc.gcdn.co/icons/clanEmblems1x/clan-icon-v2-${clanInfo.emblem_set_id}.png`}
|
|
||||||
description={`${literals(
|
|
||||||
strings.bot.commands.inactive.body.subtitle,
|
|
||||||
{ days: threshold }
|
|
||||||
)} • ${new Date().toLocaleDateString(interaction.locale)}`}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{!hasInactiveMembers && (
|
|
||||||
<NoData type="players_in_period" locale={interaction.locale} />
|
|
||||||
)}
|
|
||||||
{hasInactiveMembers && <GenericStats stats={inactive} />}
|
|
||||||
</CommandWrapper>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
autocomplete: autocompleteClan,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,193 +0,0 @@
|
|||||||
import { getAccountInfo, getClanAccountInfo } from '@blitzkit/core';
|
|
||||||
import { teal } from '@radix-ui/colors';
|
|
||||||
import { Glow } from '../components/AllStatsOverview/components/HeroStat/components/Glow';
|
|
||||||
import { CommandWrapper } from '../components/CommandWrapper';
|
|
||||||
import { linkBlitzAndDiscord } from '../core/db/linkBlitzAndDiscord';
|
|
||||||
import { addUsernameChoices } from '../core/discord/addUsernameChoices';
|
|
||||||
import { autocompleteUsername } from '../core/discord/autocompleteUsername';
|
|
||||||
import { createLocalizedCommand } from '../core/discord/createLocalizedCommand';
|
|
||||||
import { embedInfo } from '../core/discord/embedInfo';
|
|
||||||
import { resolvePlayerFromCommand } from '../core/discord/resolvePlayerFromCommand';
|
|
||||||
import { translator } from '../core/localization/translator';
|
|
||||||
import type { CommandRegistry } from '../events/interactionCreate';
|
|
||||||
import { theme } from '../stitches.config';
|
|
||||||
|
|
||||||
export const verifyCommand = new Promise<CommandRegistry>((resolve) => {
|
|
||||||
resolve({
|
|
||||||
command: createLocalizedCommand('link').addStringOption((option) =>
|
|
||||||
addUsernameChoices(option).setRequired(true),
|
|
||||||
),
|
|
||||||
|
|
||||||
async handler(interaction) {
|
|
||||||
const { strings } = translator(interaction.locale);
|
|
||||||
const { id, region } = await resolvePlayerFromCommand(interaction);
|
|
||||||
const discordId = BigInt(interaction.user.id);
|
|
||||||
const accountInfo = await getAccountInfo(region, id);
|
|
||||||
const clanAccountInfo = await getClanAccountInfo(region, id, ['clan']);
|
|
||||||
|
|
||||||
await linkBlitzAndDiscord(discordId, id);
|
|
||||||
|
|
||||||
return [
|
|
||||||
<CommandWrapper fat>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'space-between',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Glow color={teal.teal9} rotation={90} />
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
gap: 16,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
gap: 8,
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
alt="avatar"
|
|
||||||
src={
|
|
||||||
interaction.user.avatarURL({ extension: 'png' }) ??
|
|
||||||
'https://i.stack.imgur.com/l60Hf.png'
|
|
||||||
}
|
|
||||||
style={{
|
|
||||||
width: 64,
|
|
||||||
height: 64,
|
|
||||||
borderRadius: 32,
|
|
||||||
objectFit: 'cover',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
gap: 4,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 32,
|
|
||||||
color: theme.colors.textHighContrast,
|
|
||||||
fontWeight: 900,
|
|
||||||
maxWidth: 240,
|
|
||||||
overflow: 'hidden',
|
|
||||||
textOverflow: 'ellipsis',
|
|
||||||
whiteSpace: 'nowrap',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{interaction.user.displayName}
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 16,
|
|
||||||
color: theme.colors.textLowContrast,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
@{interaction.user.username}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
gap: 4,
|
|
||||||
color: theme.colors.textLowContrast_teal,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
alt="accounts linked"
|
|
||||||
src="https://i.imgur.com/jIcRgog.png"
|
|
||||||
style={{
|
|
||||||
width: 16,
|
|
||||||
height: 16,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<span style={{ fontSize: 16 }}>
|
|
||||||
{strings.bot.commands.link.body.accounts_linked}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
gap: 8,
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{clanAccountInfo?.clan ? (
|
|
||||||
<img
|
|
||||||
alt="clan emblem"
|
|
||||||
style={{
|
|
||||||
width: 64,
|
|
||||||
height: 64,
|
|
||||||
borderRadius: 32,
|
|
||||||
objectFit: 'cover',
|
|
||||||
}}
|
|
||||||
src={`https://wotblitz-gc.gcdn.co/icons/clanEmblems1x/clan-icon-v2-${clanAccountInfo?.clan?.emblem_set_id}.png`}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
gap: 4,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 32,
|
|
||||||
color: theme.colors.textHighContrast,
|
|
||||||
fontWeight: 900,
|
|
||||||
maxWidth: 240,
|
|
||||||
overflow: 'hidden',
|
|
||||||
textOverflow: 'ellipsis',
|
|
||||||
whiteSpace: 'nowrap',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{accountInfo.nickname}
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 16,
|
|
||||||
color: theme.colors.textLowContrast,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{clanAccountInfo?.clan
|
|
||||||
? `[${clanAccountInfo?.clan?.tag}] • `
|
|
||||||
: ''}
|
|
||||||
{strings.common.regions.normal[region]}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Glow color={teal.teal9} rotation={-90} />
|
|
||||||
</div>
|
|
||||||
</CommandWrapper>,
|
|
||||||
|
|
||||||
embedInfo(
|
|
||||||
strings.bot.commands.link.embed.title,
|
|
||||||
strings.bot.commands.link.embed.description,
|
|
||||||
),
|
|
||||||
];
|
|
||||||
},
|
|
||||||
|
|
||||||
autocomplete: autocompleteUsername,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
import {
|
|
||||||
TANK_CLASSES,
|
|
||||||
TIER_ROMAN_NUMERALS,
|
|
||||||
TankDefinition,
|
|
||||||
flags,
|
|
||||||
getAccountInfo,
|
|
||||||
getTankStats,
|
|
||||||
} from "@blitzkit/core";
|
|
||||||
import { literals } from "@blitzkit/i18n";
|
|
||||||
import markdownEscape from "markdown-escape";
|
|
||||||
import {
|
|
||||||
gameDefinitions,
|
|
||||||
tankDefinitions,
|
|
||||||
} from "../core/blitzkit/nonBlockingPromises";
|
|
||||||
import { addTierChoices } from "../core/discord/addTierChoices";
|
|
||||||
import { addUsernameChoices } from "../core/discord/addUsernameChoices";
|
|
||||||
import { autocompleteUsername } from "../core/discord/autocompleteUsername";
|
|
||||||
import { chunkLines } from "../core/discord/chunkLines";
|
|
||||||
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
|
|
||||||
import { resolvePlayerFromCommand } from "../core/discord/resolvePlayerFromCommand";
|
|
||||||
import { translator } from "../core/localization/translator";
|
|
||||||
import { type CommandRegistry } from "../events/interactionCreate";
|
|
||||||
|
|
||||||
export const ownedTanksCommand = new Promise<CommandRegistry>((resolve) => {
|
|
||||||
resolve({
|
|
||||||
command: createLocalizedCommand("owned-tanks")
|
|
||||||
.addStringOption(addTierChoices)
|
|
||||||
.addStringOption(addUsernameChoices),
|
|
||||||
|
|
||||||
async handler(interaction) {
|
|
||||||
const { strings, unwrap } = translator(interaction.locale);
|
|
||||||
const tier = Number(interaction.options.getString("tier"));
|
|
||||||
const { id, region } = await resolvePlayerFromCommand(interaction);
|
|
||||||
const accountInfo = await getAccountInfo(region, id);
|
|
||||||
const tankStats = await getTankStats(region, id);
|
|
||||||
|
|
||||||
if (tankStats === null) {
|
|
||||||
return strings.bot.common.errors.no_tank_stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
const filteredTanks = (
|
|
||||||
await Promise.all(
|
|
||||||
tankStats.map(async (tankData) => ({
|
|
||||||
tankDefinitions: (await tankDefinitions).tanks[tankData.tank_id]!,
|
|
||||||
id: tankData.tank_id,
|
|
||||||
}))
|
|
||||||
)
|
|
||||||
).filter((tank) => tank.tankDefinitions?.tier === tier);
|
|
||||||
const groupedTanks: Record<string, TankDefinition[]> = {};
|
|
||||||
const nations: string[] = [];
|
|
||||||
|
|
||||||
filteredTanks.forEach((tank) => {
|
|
||||||
if (groupedTanks[tank.tankDefinitions.nation] === undefined) {
|
|
||||||
groupedTanks[tank.tankDefinitions.nation] = [tank.tankDefinitions];
|
|
||||||
nations.push(tank.tankDefinitions.nation);
|
|
||||||
} else {
|
|
||||||
groupedTanks[tank.tankDefinitions.nation].push(tank.tankDefinitions);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const awaitedTankDefinitions = await tankDefinitions;
|
|
||||||
const awaitedGameDefinitions = await gameDefinitions;
|
|
||||||
const title = literals(strings.bot.commands.owned_tanks.body.title, {
|
|
||||||
name: markdownEscape(accountInfo.nickname),
|
|
||||||
tier: TIER_ROMAN_NUMERALS[tier],
|
|
||||||
});
|
|
||||||
const tankList = tankStats
|
|
||||||
.map(({ tank_id }) => awaitedTankDefinitions.tanks[tank_id])
|
|
||||||
.filter((tank) => tank.tier === tier)
|
|
||||||
.sort(
|
|
||||||
(a, b) =>
|
|
||||||
TANK_CLASSES.indexOf(a.class) - TANK_CLASSES.indexOf(b.class)
|
|
||||||
)
|
|
||||||
.sort(
|
|
||||||
(a, b) =>
|
|
||||||
awaitedGameDefinitions.nations.indexOf(a.nation) -
|
|
||||||
awaitedGameDefinitions.nations.indexOf(b.nation)
|
|
||||||
)
|
|
||||||
.map(
|
|
||||||
(tank) =>
|
|
||||||
`[${flags[tank.nation]} ${markdownEscape(unwrap(tank.name))}](<https://blitzkit.app/tanks/${tank.slug}>)`
|
|
||||||
);
|
|
||||||
const lines = [title, ...tankList];
|
|
||||||
|
|
||||||
return chunkLines(lines);
|
|
||||||
},
|
|
||||||
|
|
||||||
autocomplete: autocompleteUsername,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
import { literals } from "@blitzkit/i18n";
|
|
||||||
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
|
|
||||||
import { translator } from "../core/localization/translator";
|
|
||||||
import { CommandRegistry } from "../events/interactionCreate";
|
|
||||||
|
|
||||||
export const permissionsCommand = new Promise<CommandRegistry>((resolve) => {
|
|
||||||
resolve({
|
|
||||||
command: createLocalizedCommand("permissions"),
|
|
||||||
|
|
||||||
async handler(interaction) {
|
|
||||||
const { strings } = translator(interaction.locale);
|
|
||||||
// friday the 13th permissions easter egg
|
|
||||||
const isFridayThe13th =
|
|
||||||
new Date().getDay() === 5 && new Date().getDate() === 13;
|
|
||||||
const permissions = [
|
|
||||||
[
|
|
||||||
interaction.appPermissions?.has("ViewChannel"),
|
|
||||||
strings.bot.commands.permissions.body.view_channels,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
interaction.appPermissions?.has("ReadMessageHistory"),
|
|
||||||
strings.bot.commands.permissions.body.read_message_history,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
interaction.appPermissions?.has("AttachFiles"),
|
|
||||||
strings.bot.commands.permissions.body.attach_files,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
interaction.appPermissions?.has("UseExternalEmojis"),
|
|
||||||
strings.bot.commands.permissions.body.external_emojis,
|
|
||||||
],
|
|
||||||
];
|
|
||||||
const body = permissions
|
|
||||||
.map(([hasPermission, description]) => {
|
|
||||||
if (hasPermission) {
|
|
||||||
return `${isFridayThe13th ? "😇" : "✅"} ${description}`;
|
|
||||||
} else {
|
|
||||||
return `${isFridayThe13th ? "💀" : "❌"} ${description}`;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.join("\n");
|
|
||||||
|
|
||||||
return literals(strings.bot.commands.permissions.body.title, { body });
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
import { literals } from "@blitzkit/i18n";
|
|
||||||
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
|
|
||||||
import { translator } from "../core/localization/translator";
|
|
||||||
import type { CommandRegistry } from "../events/interactionCreate";
|
|
||||||
|
|
||||||
export const pingCommand = new Promise<CommandRegistry>((resolve) => {
|
|
||||||
resolve({
|
|
||||||
handlesInteraction: true,
|
|
||||||
|
|
||||||
command: createLocalizedCommand("ping", [
|
|
||||||
{ subcommand: "blitzkit" },
|
|
||||||
{ subcommand: "wotb" },
|
|
||||||
]),
|
|
||||||
|
|
||||||
async handler(interaction) {
|
|
||||||
const { strings } = translator(interaction.locale);
|
|
||||||
const subcommand = interaction.options.getSubcommand();
|
|
||||||
const executionStart = Date.now();
|
|
||||||
|
|
||||||
if (subcommand === "blitzkit") {
|
|
||||||
await interaction.editReply(strings.bot.commands.ping.body.pong);
|
|
||||||
} else {
|
|
||||||
await fetch("https://api.wotblitz.com/");
|
|
||||||
}
|
|
||||||
|
|
||||||
const executionTime = Date.now() - executionStart;
|
|
||||||
interaction.editReply(
|
|
||||||
literals(strings.bot.commands.ping.body.pong_with_time, {
|
|
||||||
time: executionTime.toFixed(0),
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
import { getAccountInfo } from "@blitzkit/core";
|
|
||||||
import { literals } from "@blitzkit/i18n";
|
|
||||||
import markdownEscape from "markdown-escape";
|
|
||||||
import { addUsernameChoices } from "../core/discord/addUsernameChoices";
|
|
||||||
import { autocompleteUsername } from "../core/discord/autocompleteUsername";
|
|
||||||
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
|
|
||||||
import { embedInfo } from "../core/discord/embedInfo";
|
|
||||||
import { markdownTable } from "../core/discord/markdownTable";
|
|
||||||
import { resolvePlayerFromCommand } from "../core/discord/resolvePlayerFromCommand";
|
|
||||||
import { translator } from "../core/localization/translator";
|
|
||||||
import { CommandRegistry } from "../events/interactionCreate";
|
|
||||||
|
|
||||||
export const playerInfoCommand = new Promise<CommandRegistry>((resolve) => {
|
|
||||||
resolve({
|
|
||||||
command:
|
|
||||||
createLocalizedCommand("player-info").addStringOption(addUsernameChoices),
|
|
||||||
|
|
||||||
async handler(interaction) {
|
|
||||||
const { strings } = translator(interaction.locale);
|
|
||||||
const account = await resolvePlayerFromCommand(interaction);
|
|
||||||
const { id, region: region } = account;
|
|
||||||
const accountInfo = await getAccountInfo(region, id);
|
|
||||||
|
|
||||||
return embedInfo(
|
|
||||||
literals(strings.bot.commands.player_info.body.title, {
|
|
||||||
name: markdownEscape(accountInfo.nickname),
|
|
||||||
}),
|
|
||||||
|
|
||||||
markdownTable([
|
|
||||||
[
|
|
||||||
strings.bot.commands.player_info.body.nickname,
|
|
||||||
`${accountInfo.nickname}`,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
strings.bot.commands.player_info.body.battles,
|
|
||||||
`${accountInfo.statistics.all.battles}`,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
strings.bot.commands.player_info.body.winrate,
|
|
||||||
`${(
|
|
||||||
100 *
|
|
||||||
(accountInfo.statistics.all.wins /
|
|
||||||
accountInfo.statistics.all.battles)
|
|
||||||
).toFixed(2)}%`,
|
|
||||||
],
|
|
||||||
[],
|
|
||||||
[
|
|
||||||
strings.bot.commands.player_info.body.account_id,
|
|
||||||
`${accountInfo.account_id}`,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
strings.bot.commands.player_info.body.created,
|
|
||||||
new Date(accountInfo.created_at * 1000).toLocaleDateString(
|
|
||||||
interaction.locale
|
|
||||||
),
|
|
||||||
],
|
|
||||||
[
|
|
||||||
strings.bot.commands.player_info.body.last_battle,
|
|
||||||
new Date(accountInfo.last_battle_time * 1000).toLocaleDateString(
|
|
||||||
interaction.locale
|
|
||||||
),
|
|
||||||
],
|
|
||||||
])
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
autocomplete: autocompleteUsername,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,535 +0,0 @@
|
|||||||
import {
|
|
||||||
deltaBkrlBlitzStats,
|
|
||||||
emblemURL,
|
|
||||||
getAccountInfo,
|
|
||||||
getArchivedRatingLeaderboard,
|
|
||||||
getClanAccountInfo,
|
|
||||||
getLeagueFromScore,
|
|
||||||
getRatingInfo,
|
|
||||||
getRatingNeighbors,
|
|
||||||
imgur,
|
|
||||||
} from "@blitzkit/core";
|
|
||||||
import { literals } from "@blitzkit/i18n";
|
|
||||||
import { SlashCommandSubcommandBuilder } from "discord.js";
|
|
||||||
import markdownEscape from "markdown-escape";
|
|
||||||
import { Glow } from "../components/AllStatsOverview/components/HeroStat/components/Glow";
|
|
||||||
import { CommandWrapper } from "../components/CommandWrapper";
|
|
||||||
import { DeltaCaret } from "../components/DeltaCaret";
|
|
||||||
import { TitleBar } from "../components/TitleBar";
|
|
||||||
import { normalizeLeagueIcon } from "../core/blitz/normalizeLeagueIcon";
|
|
||||||
import { iconPng } from "../core/blitzkit/iconPng";
|
|
||||||
import { addUsernameChoices } from "../core/discord/addUsernameChoices";
|
|
||||||
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
|
|
||||||
import { resolvePlayerFromCommand } from "../core/discord/resolvePlayerFromCommand";
|
|
||||||
import { translator } from "../core/localization/translator";
|
|
||||||
import type { CommandRegistry } from "../events/interactionCreate";
|
|
||||||
import { theme } from "../stitches.config";
|
|
||||||
|
|
||||||
const LEAGUE_ACCENT = [
|
|
||||||
"_purple",
|
|
||||||
"_sand",
|
|
||||||
"_amber",
|
|
||||||
"_mauve",
|
|
||||||
"_brown",
|
|
||||||
] as const;
|
|
||||||
|
|
||||||
export const ratingCommand = new Promise<CommandRegistry>((resolve) => {
|
|
||||||
resolve({
|
|
||||||
command: createLocalizedCommand("rating", [
|
|
||||||
{
|
|
||||||
subcommand: "today",
|
|
||||||
modify(option: SlashCommandSubcommandBuilder) {
|
|
||||||
option.addStringOption(addUsernameChoices);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subcommand: "season",
|
|
||||||
modify(option: SlashCommandSubcommandBuilder) {
|
|
||||||
option.addStringOption(addUsernameChoices);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
|
|
||||||
async handler(interaction) {
|
|
||||||
const subcommand = interaction.options.getSubcommand(true) as
|
|
||||||
| "season"
|
|
||||||
| "today";
|
|
||||||
const { strings } = translator(interaction.locale);
|
|
||||||
const { id, region } = await resolvePlayerFromCommand(interaction);
|
|
||||||
const clan = (await getClanAccountInfo(region, id, ["clan"]))?.clan;
|
|
||||||
const clanImage = clan ? emblemURL(clan.emblem_set_id) : undefined;
|
|
||||||
|
|
||||||
const ratingInfo = await getRatingInfo(region);
|
|
||||||
|
|
||||||
if (ratingInfo.detail) {
|
|
||||||
throw new Error(`Rating info not available for ${region}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const leaderboard = await getArchivedRatingLeaderboard(
|
|
||||||
region,
|
|
||||||
ratingInfo.current_season - (subcommand === "today" ? 0 : 1)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (leaderboard.version!.$case === "v1") {
|
|
||||||
throw new Error(
|
|
||||||
"Encountered bkrl minimal format in latest season. Wait till next cron?"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const accountInfo = await getAccountInfo(region, id, [
|
|
||||||
"statistics.rating",
|
|
||||||
]);
|
|
||||||
const statsIndex = leaderboard.version!.value.entries.findIndex(
|
|
||||||
(entry) => entry.id === id
|
|
||||||
);
|
|
||||||
const statsA = leaderboard
|
|
||||||
? leaderboard.version!.value.entries[statsIndex!]
|
|
||||||
: null;
|
|
||||||
const positionA = leaderboard ? statsIndex! + 1 : undefined;
|
|
||||||
const statsB1 = accountInfo.statistics.rating!;
|
|
||||||
const statsB2Array = (await getRatingNeighbors(region, id, 0)).neighbors;
|
|
||||||
|
|
||||||
if (statsB2Array === undefined) {
|
|
||||||
return literals(strings.bot.commands.rating.errors.no_participation, {
|
|
||||||
name: markdownEscape(accountInfo.nickname),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const [statsB2] = statsB2Array;
|
|
||||||
const league = getLeagueFromScore(statsB2.score);
|
|
||||||
|
|
||||||
if (!statsA) {
|
|
||||||
return strings.bot.commands.rating.errors.unrecorded_stats;
|
|
||||||
}
|
|
||||||
if (!statsB1) {
|
|
||||||
return literals(strings.bot.commands.rating.errors.no_participation, {
|
|
||||||
name: markdownEscape(accountInfo.nickname),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const reward = ratingInfo.rewards.find(
|
|
||||||
(reward) =>
|
|
||||||
statsB2.number >= reward.from_position &&
|
|
||||||
statsB2.number <= reward.to_position
|
|
||||||
);
|
|
||||||
const positionDelta = leaderboard
|
|
||||||
? statsB2.number - positionA!
|
|
||||||
: undefined;
|
|
||||||
const delta = deltaBkrlBlitzStats(
|
|
||||||
statsA,
|
|
||||||
accountInfo.statistics.rating!,
|
|
||||||
statsB2
|
|
||||||
);
|
|
||||||
const leagueTheme = LEAGUE_ACCENT[league.index];
|
|
||||||
let rewardImage = reward
|
|
||||||
? reward.type === "vehicle"
|
|
||||||
? reward.vehicle.preview_image_url
|
|
||||||
: reward.stuff.image_url
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
if (rewardImage) {
|
|
||||||
const { ok } = await fetch(rewardImage);
|
|
||||||
|
|
||||||
if (!ok) {
|
|
||||||
rewardImage = imgur("kP88vqr");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<CommandWrapper>
|
|
||||||
<TitleBar
|
|
||||||
title={accountInfo.nickname}
|
|
||||||
image={clanImage}
|
|
||||||
description={`${
|
|
||||||
strings.bot.commands.rating.body.subtitle[subcommand]
|
|
||||||
} • ${new Date().toLocaleDateString(interaction.locale)}`}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
position: "relative",
|
|
||||||
display: "flex",
|
|
||||||
overflow: "hidden",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
position: "relative",
|
|
||||||
padding: 16,
|
|
||||||
backgroundColor: theme.colors[`appBackground2${leagueTheme}`],
|
|
||||||
borderRadius: 4,
|
|
||||||
border: `1px solid ${
|
|
||||||
theme.colors[`componentInteractive${leagueTheme}`]
|
|
||||||
}`,
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
width: "100%",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{reward === undefined && (
|
|
||||||
<Glow
|
|
||||||
endOpacity={3 / 4}
|
|
||||||
color={theme.colors[`solidBackground${leagueTheme}`]}
|
|
||||||
style={{
|
|
||||||
transform: "translateX(-16px) rotate(90deg)",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
gap: 8,
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
alt={`League ${league.name}`}
|
|
||||||
style={{
|
|
||||||
width: 64,
|
|
||||||
height: 64,
|
|
||||||
objectFit: "contain",
|
|
||||||
}}
|
|
||||||
src={normalizeLeagueIcon(
|
|
||||||
ratingInfo.leagues[league.index].big_icon
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "flex-start",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color: theme.colors[`textHighContrast${leagueTheme}`],
|
|
||||||
fontSize: 24,
|
|
||||||
fontWeight: 900,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{statsB2.score.toLocaleString(interaction.locale)}
|
|
||||||
</span>
|
|
||||||
{delta.score !== 0 && (
|
|
||||||
<>
|
|
||||||
<DeltaCaret delta={delta.score} />
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color:
|
|
||||||
delta.score > 0
|
|
||||||
? theme.colors.textLowContrast_green
|
|
||||||
: theme.colors.textLowContrast_red,
|
|
||||||
fontSize: 16,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{Math.abs(delta.score).toLocaleString(
|
|
||||||
interaction.locale
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "flex-start",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color: theme.colors[`textLowContrast${leagueTheme}`],
|
|
||||||
fontSize: 16,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
#{statsB2.number.toLocaleString(interaction.locale)}
|
|
||||||
</span>
|
|
||||||
{positionDelta !== undefined && positionDelta !== 0 && (
|
|
||||||
<>
|
|
||||||
<DeltaCaret delta={-positionDelta} />
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color:
|
|
||||||
positionDelta > 0
|
|
||||||
? theme.colors.textLowContrast_red
|
|
||||||
: theme.colors.textLowContrast_green,
|
|
||||||
fontSize: 16,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{Math.abs(positionDelta).toLocaleString(
|
|
||||||
interaction.locale
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{reward && (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
gap: 8,
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "flex-end",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color: theme.colors[`textHighContrast${leagueTheme}`],
|
|
||||||
fontSize: 16,
|
|
||||||
maxWidth: 136,
|
|
||||||
textAlign: "right",
|
|
||||||
whiteSpace: "nowrap",
|
|
||||||
textOverflow: "ellipsis",
|
|
||||||
overflow: "hidden",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{reward.type === "vehicle"
|
|
||||||
? reward.vehicle.user_string
|
|
||||||
: reward.stuff.title}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "flex-end",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color: theme.colors[`textLowContrast${leagueTheme}`],
|
|
||||||
fontSize: 16,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Reward
|
|
||||||
{reward.type === "stuff" ? ` x${reward.count}` : ""}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<img
|
|
||||||
style={{
|
|
||||||
width: 64,
|
|
||||||
height: 64,
|
|
||||||
objectFit: "cover",
|
|
||||||
}}
|
|
||||||
src={await iconPng(rewardImage!)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{reward === undefined && (
|
|
||||||
<Glow
|
|
||||||
endOpacity={3 / 4}
|
|
||||||
color={theme.colors[`solidBackground${leagueTheme}`]}
|
|
||||||
style={{
|
|
||||||
transform: "translateX(16px) rotate(-90deg)",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* separated because fragment middle man invalidates relative parent: https://github.com/vercel/satori/issues/605 */}
|
|
||||||
{reward && (
|
|
||||||
<Glow
|
|
||||||
direction="reverse"
|
|
||||||
color={theme.colors[`solidBackground${leagueTheme}`]}
|
|
||||||
style={{
|
|
||||||
position: "absolute",
|
|
||||||
top: -40,
|
|
||||||
left: "50%",
|
|
||||||
transform: "translateX(-50%)",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{reward && (
|
|
||||||
<Glow
|
|
||||||
color={theme.colors[`solidBackground${leagueTheme}`]}
|
|
||||||
style={{
|
|
||||||
position: "absolute",
|
|
||||||
bottom: -40,
|
|
||||||
left: "50%",
|
|
||||||
transform: "translateX(-50%)",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{delta.battles > 0 && (
|
|
||||||
<div style={{ padding: "8px 0", display: "flex" }}>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
gap: 4,
|
|
||||||
flex: 1,
|
|
||||||
flexDirection: "column",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 24,
|
|
||||||
color: theme.colors.textHighContrast,
|
|
||||||
fontWeight: "bold",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{delta.battles.toLocaleString(interaction.locale)}
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 16,
|
|
||||||
color: theme.colors.textLowContrast,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Battles
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
gap: 4,
|
|
||||||
flex: 1,
|
|
||||||
flexDirection: "column",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 24,
|
|
||||||
color: theme.colors.textHighContrast,
|
|
||||||
fontWeight: "bold",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{(100 * (delta.wins / delta.battles)).toFixed(0)}%
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 16,
|
|
||||||
color: theme.colors.textLowContrast,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Winrate
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
gap: 4,
|
|
||||||
flex: 1,
|
|
||||||
flexDirection: "column",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 24,
|
|
||||||
color: theme.colors.textHighContrast,
|
|
||||||
fontWeight: "bold",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{Math.round(delta.damage / delta.battles).toLocaleString(
|
|
||||||
interaction.locale
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 16,
|
|
||||||
color: theme.colors.textLowContrast,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Damage
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
gap: 4,
|
|
||||||
flex: 1,
|
|
||||||
flexDirection: "column",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 24,
|
|
||||||
color: theme.colors.textHighContrast,
|
|
||||||
fontWeight: "bold",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{(100 * (delta.survived / delta.battles)).toFixed(0)}%
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 16,
|
|
||||||
color: theme.colors.textLowContrast,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Survival
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
gap: 4,
|
|
||||||
flex: 1,
|
|
||||||
flexDirection: "column",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 24,
|
|
||||||
color: theme.colors.textHighContrast,
|
|
||||||
fontWeight: "bold",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{(delta.kills / delta.battles).toFixed(2)}
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 16,
|
|
||||||
color: theme.colors.textLowContrast,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Kills
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</CommandWrapper>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,468 +0,0 @@
|
|||||||
import {
|
|
||||||
FIRST_MINIMAL_ARCHIVED_RATING_SEASON,
|
|
||||||
getAccountInfo,
|
|
||||||
getArchivedLatestSeasonNumber,
|
|
||||||
getArchivedRatingLeaderboard,
|
|
||||||
getClanAccountInfo,
|
|
||||||
getRatingInfo,
|
|
||||||
getRatingLeague,
|
|
||||||
getRatingNeighbors,
|
|
||||||
imgur,
|
|
||||||
isOnGoingRatingSeason,
|
|
||||||
LEAGUES,
|
|
||||||
type RatingInfo,
|
|
||||||
RatingLeaderboard,
|
|
||||||
type Region,
|
|
||||||
} from "@blitzkit/core";
|
|
||||||
import { literals } from "@blitzkit/i18n";
|
|
||||||
import {
|
|
||||||
type APIApplicationCommandOptionChoice,
|
|
||||||
Locale,
|
|
||||||
SlashCommandSubcommandBuilder,
|
|
||||||
} from "discord.js";
|
|
||||||
import { range } from "lodash-es";
|
|
||||||
import markdownEscape from "markdown-escape";
|
|
||||||
import { CommandWrapper } from "../components/CommandWrapper";
|
|
||||||
import * as Leaderboard from "../components/Leaderboard";
|
|
||||||
import { TitleBar } from "../components/TitleBar";
|
|
||||||
import { UserError } from "../core/blitzkit/userError";
|
|
||||||
import { addRegionChoices } from "../core/discord/addRegionChoices";
|
|
||||||
import { addUsernameChoices } from "../core/discord/addUsernameChoices";
|
|
||||||
import { autocompleteUsername } from "../core/discord/autocompleteUsername";
|
|
||||||
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
|
|
||||||
import { localizationObject } from "../core/discord/localizationObject";
|
|
||||||
import { resolvePlayerFromCommand } from "../core/discord/resolvePlayerFromCommand";
|
|
||||||
import { translator } from "../core/localization/translator";
|
|
||||||
import type { CommandRegistry } from "../events/interactionCreate";
|
|
||||||
|
|
||||||
interface SimplifiedPlayer {
|
|
||||||
id: number;
|
|
||||||
score: number;
|
|
||||||
position: number;
|
|
||||||
clan: string | undefined;
|
|
||||||
nickname: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const DEFAULT_LIMIT = 10;
|
|
||||||
|
|
||||||
export const ratingLeaderboardCommand = new Promise<CommandRegistry>(
|
|
||||||
async (resolve) => {
|
|
||||||
const latestArchivedSeasonNumber = await getArchivedLatestSeasonNumber();
|
|
||||||
const onGoingSeason = await isOnGoingRatingSeason();
|
|
||||||
const seasonNumbers = range(
|
|
||||||
FIRST_MINIMAL_ARCHIVED_RATING_SEASON,
|
|
||||||
latestArchivedSeasonNumber + (onGoingSeason ? 1 : 0) + 1
|
|
||||||
).slice(-25);
|
|
||||||
|
|
||||||
function addOptions(option: SlashCommandSubcommandBuilder) {
|
|
||||||
const { strings } = translator(Locale.EnglishUS);
|
|
||||||
|
|
||||||
return option
|
|
||||||
.addIntegerOption((option) =>
|
|
||||||
option
|
|
||||||
.setName(strings.bot.commands.rating_leaderboard.options.limit.name)
|
|
||||||
.setNameLocalizations(
|
|
||||||
localizationObject(
|
|
||||||
(strings) =>
|
|
||||||
strings.bot.commands.rating_leaderboard.options.limit.name,
|
|
||||||
undefined,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.setDescription(
|
|
||||||
literals(
|
|
||||||
strings.bot.commands.rating_leaderboard.options.limit
|
|
||||||
.description,
|
|
||||||
{ count: DEFAULT_LIMIT }
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.setDescriptionLocalizations(
|
|
||||||
localizationObject(
|
|
||||||
(strings) =>
|
|
||||||
strings.bot.commands.rating_leaderboard.options.limit
|
|
||||||
.description,
|
|
||||||
{ count: DEFAULT_LIMIT }
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.setRequired(false)
|
|
||||||
.setMinValue(5)
|
|
||||||
.setMaxValue(30)
|
|
||||||
)
|
|
||||||
.addStringOption((option) =>
|
|
||||||
option
|
|
||||||
.setName(
|
|
||||||
strings.bot.commands.rating_leaderboard.options.season.name
|
|
||||||
)
|
|
||||||
.setNameLocalizations(
|
|
||||||
localizationObject(
|
|
||||||
(strings) =>
|
|
||||||
strings.bot.commands.rating_leaderboard.options.season.name,
|
|
||||||
undefined,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.setDescription(
|
|
||||||
strings.bot.commands.rating_leaderboard.options.season.description
|
|
||||||
)
|
|
||||||
.setDescriptionLocalizations(
|
|
||||||
localizationObject(
|
|
||||||
(strings) =>
|
|
||||||
strings.bot.commands.rating_leaderboard.options.season
|
|
||||||
.description
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.setRequired(false)
|
|
||||||
.addChoices(
|
|
||||||
...seasonNumbers
|
|
||||||
.map((number, index) => {
|
|
||||||
const current =
|
|
||||||
index === seasonNumbers.length - 1 && onGoingSeason;
|
|
||||||
|
|
||||||
return {
|
|
||||||
name: current
|
|
||||||
? literals(
|
|
||||||
strings.bot.commands.rating_leaderboard.options.season
|
|
||||||
.choices.current,
|
|
||||||
{ season: number }
|
|
||||||
)
|
|
||||||
: `${number}`,
|
|
||||||
value: `${number}`,
|
|
||||||
name_localizations: current
|
|
||||||
? localizationObject(
|
|
||||||
(strings) =>
|
|
||||||
strings.bot.commands.rating_leaderboard.options
|
|
||||||
.season.choices.current,
|
|
||||||
{ season: number }
|
|
||||||
)
|
|
||||||
: undefined,
|
|
||||||
} satisfies APIApplicationCommandOptionChoice<string>;
|
|
||||||
})
|
|
||||||
.reverse()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
resolve({
|
|
||||||
command: createLocalizedCommand("rating-leaderboard", [
|
|
||||||
{
|
|
||||||
subcommand: "neighbors",
|
|
||||||
modify(option: SlashCommandSubcommandBuilder) {
|
|
||||||
option.addStringOption(addUsernameChoices);
|
|
||||||
addOptions(option);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subcommand: "league",
|
|
||||||
modify(option: SlashCommandSubcommandBuilder) {
|
|
||||||
option
|
|
||||||
.addStringOption((option) => {
|
|
||||||
const { strings } = translator(Locale.EnglishUS);
|
|
||||||
|
|
||||||
return option
|
|
||||||
.setName(
|
|
||||||
strings.bot.commands.rating_leaderboard.options.league.name
|
|
||||||
)
|
|
||||||
.setNameLocalizations(
|
|
||||||
localizationObject(
|
|
||||||
(strings) =>
|
|
||||||
strings.bot.commands.rating_leaderboard.options.league
|
|
||||||
.name,
|
|
||||||
undefined,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.setDescription(
|
|
||||||
strings.bot.commands.rating_leaderboard.options.league
|
|
||||||
.description
|
|
||||||
)
|
|
||||||
.setDescriptionLocalizations(
|
|
||||||
localizationObject(
|
|
||||||
(strings) =>
|
|
||||||
strings.bot.commands.rating_leaderboard.options.league
|
|
||||||
.description
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.addChoices(
|
|
||||||
...LEAGUES.map(
|
|
||||||
({ name }, value) =>
|
|
||||||
({
|
|
||||||
name: (
|
|
||||||
strings.common.leagues as Record<string, string>
|
|
||||||
)[name],
|
|
||||||
value: `${value}`,
|
|
||||||
name_localizations: localizationObject(
|
|
||||||
(strings) =>
|
|
||||||
(
|
|
||||||
strings.common.leagues as Record<string, string>
|
|
||||||
)[name]
|
|
||||||
),
|
|
||||||
} satisfies APIApplicationCommandOptionChoice<string>)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.setRequired(true);
|
|
||||||
})
|
|
||||||
.addStringOption(addRegionChoices);
|
|
||||||
addOptions(option);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
|
|
||||||
// BIG TODO: title seems to be in english
|
|
||||||
|
|
||||||
async handler(interaction) {
|
|
||||||
const { strings } = translator(interaction.locale);
|
|
||||||
const subcommand = interaction.options.getSubcommand(true) as
|
|
||||||
| "league"
|
|
||||||
| "neighbors";
|
|
||||||
const limit = interaction.options.getInteger("limit") ?? DEFAULT_LIMIT;
|
|
||||||
const seasonOption = interaction.options.getString("season");
|
|
||||||
const season = seasonOption
|
|
||||||
? parseInt(seasonOption)
|
|
||||||
: onGoingSeason
|
|
||||||
? latestArchivedSeasonNumber + 1
|
|
||||||
: latestArchivedSeasonNumber;
|
|
||||||
const isCurrentSeason = season === latestArchivedSeasonNumber + 1;
|
|
||||||
let titleName: string;
|
|
||||||
let titleImage: string | undefined;
|
|
||||||
let titleDescription: string;
|
|
||||||
let playersAfter: number;
|
|
||||||
let players: SimplifiedPlayer[] | undefined;
|
|
||||||
let archivedLeaderboard: RatingLeaderboard | null;
|
|
||||||
let playerId: number | undefined;
|
|
||||||
let regionRatingInfo: RatingInfo | null;
|
|
||||||
|
|
||||||
if (subcommand === "league") {
|
|
||||||
const leagueIndex = parseInt(
|
|
||||||
interaction.options.getString("league")!
|
|
||||||
);
|
|
||||||
const region = interaction.options.getString("region") as Region;
|
|
||||||
regionRatingInfo = await (isCurrentSeason
|
|
||||||
? getRatingInfo(region)
|
|
||||||
: null);
|
|
||||||
|
|
||||||
if (
|
|
||||||
regionRatingInfo !== null &&
|
|
||||||
regionRatingInfo.detail !== undefined
|
|
||||||
) {
|
|
||||||
return strings.bot.commands.rating_leaderboard.body
|
|
||||||
.no_ongoing_season;
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = isCurrentSeason
|
|
||||||
? await getRatingLeague(region, leagueIndex).then(async (result) =>
|
|
||||||
result.slice(0, limit).map(
|
|
||||||
(player) =>
|
|
||||||
({
|
|
||||||
id: player.spa_id,
|
|
||||||
score: player.score,
|
|
||||||
position: player.number,
|
|
||||||
clan: player.clan_tag,
|
|
||||||
nickname: player.nickname,
|
|
||||||
} satisfies SimplifiedPlayer)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
: await getArchivedRatingLeaderboard(region, season!).then(
|
|
||||||
async (players) => {
|
|
||||||
const firstPlayerIndex =
|
|
||||||
leagueIndex === 0
|
|
||||||
? 0
|
|
||||||
: players.version!.value.entries.findIndex(
|
|
||||||
(player) =>
|
|
||||||
player.score < LEAGUES[leagueIndex - 1].minScore
|
|
||||||
);
|
|
||||||
const lastPlayerIndex = firstPlayerIndex + limit - 1;
|
|
||||||
const trimmed = players.version!.value.entries.slice(
|
|
||||||
firstPlayerIndex,
|
|
||||||
lastPlayerIndex + 1
|
|
||||||
);
|
|
||||||
const clanData = await getClanAccountInfo(
|
|
||||||
region,
|
|
||||||
trimmed.map(({ id }) => id),
|
|
||||||
["clan"]
|
|
||||||
);
|
|
||||||
|
|
||||||
return trimmed.map(
|
|
||||||
(player, index) =>
|
|
||||||
({
|
|
||||||
id: player.id,
|
|
||||||
score: player.score,
|
|
||||||
position: firstPlayerIndex + index + 1,
|
|
||||||
clan: clanData[player.id]?.clan?.tag,
|
|
||||||
nickname:
|
|
||||||
clanData[index]?.account_name ??
|
|
||||||
literals(
|
|
||||||
strings.bot.commands.rating_leaderboard.body
|
|
||||||
.deleted_player,
|
|
||||||
{ id: player.id }
|
|
||||||
),
|
|
||||||
} satisfies SimplifiedPlayer)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
const leagueInfo = LEAGUES[leagueIndex];
|
|
||||||
archivedLeaderboard = await getArchivedRatingLeaderboard(
|
|
||||||
region,
|
|
||||||
season
|
|
||||||
);
|
|
||||||
|
|
||||||
players = result;
|
|
||||||
playersAfter =
|
|
||||||
(regionRatingInfo === null
|
|
||||||
? archivedLeaderboard.version!.value.entries.length
|
|
||||||
: regionRatingInfo.count) - result[result.length - 1].position;
|
|
||||||
titleName = `${
|
|
||||||
leagueInfo
|
|
||||||
? (strings.common.leagues as Record<string, string>)[
|
|
||||||
LEAGUES[leagueInfo.index].name
|
|
||||||
]
|
|
||||||
: ""
|
|
||||||
} - ${strings.common.regions.short[region]}`;
|
|
||||||
titleImage = imgur(leagueInfo.icon);
|
|
||||||
titleDescription = literals(
|
|
||||||
strings.bot.commands.rating_leaderboard.body.top_players,
|
|
||||||
{ count: limit }
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
const { region, id } = await resolvePlayerFromCommand(interaction);
|
|
||||||
regionRatingInfo = isCurrentSeason
|
|
||||||
? await getRatingInfo(region)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
if (
|
|
||||||
regionRatingInfo !== null &&
|
|
||||||
regionRatingInfo.detail !== undefined
|
|
||||||
) {
|
|
||||||
return strings.bot.commands.rating_leaderboard.body
|
|
||||||
.no_ongoing_season;
|
|
||||||
}
|
|
||||||
|
|
||||||
const accountInfo = await getAccountInfo(region, id);
|
|
||||||
const clan = (await getClanAccountInfo(region, id, ["clan"]))?.clan;
|
|
||||||
const neighbors = isCurrentSeason
|
|
||||||
? await getRatingNeighbors(region, id, Math.round(limit / 2)).then(
|
|
||||||
(players) =>
|
|
||||||
players.neighbors.map(
|
|
||||||
(player) =>
|
|
||||||
({
|
|
||||||
id: player.spa_id,
|
|
||||||
position: player.number,
|
|
||||||
score: player.score,
|
|
||||||
clan: player.clan_tag,
|
|
||||||
nickname: player.nickname,
|
|
||||||
} satisfies SimplifiedPlayer)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
: await getArchivedRatingLeaderboard(region, season!).then(
|
|
||||||
async (players) => {
|
|
||||||
const playerIndex = players.version!.value.entries.findIndex(
|
|
||||||
(player) => player.id === id
|
|
||||||
);
|
|
||||||
|
|
||||||
if (playerIndex === -1) {
|
|
||||||
throw new UserError(
|
|
||||||
literals(
|
|
||||||
strings.bot.commands.rating_leaderboard.body
|
|
||||||
.no_participation,
|
|
||||||
{ player: markdownEscape(accountInfo.nickname), season }
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const halfRange = Math.round(limit / 2);
|
|
||||||
const trimmed = players.version!.value.entries.slice(
|
|
||||||
playerIndex - halfRange,
|
|
||||||
playerIndex + halfRange + 1
|
|
||||||
);
|
|
||||||
const clanData = await getClanAccountInfo(
|
|
||||||
region,
|
|
||||||
trimmed.map((player) => player.id),
|
|
||||||
["clan"]
|
|
||||||
);
|
|
||||||
|
|
||||||
return trimmed.map((player, index) => ({
|
|
||||||
id: player.id,
|
|
||||||
score: player.score,
|
|
||||||
position: playerIndex + index + 1,
|
|
||||||
clan: clanData[index]?.clan?.tag,
|
|
||||||
nickname: clanData[index]
|
|
||||||
? clanData[index]!.account_name
|
|
||||||
: `Deleted ${player.id}`,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
);
|
|
||||||
archivedLeaderboard = await getArchivedRatingLeaderboard(
|
|
||||||
region,
|
|
||||||
season
|
|
||||||
);
|
|
||||||
|
|
||||||
players = neighbors;
|
|
||||||
titleImage = clan
|
|
||||||
? `https://wotblitz-gc.gcdn.co/icons/clanEmblems1x/clan-icon-v2-${clan.emblem_set_id}.png`
|
|
||||||
: undefined;
|
|
||||||
titleName = neighbors ? accountInfo.nickname : "";
|
|
||||||
titleDescription =
|
|
||||||
strings.bot.commands.rating_leaderboard.body.neighbors;
|
|
||||||
playersAfter =
|
|
||||||
(regionRatingInfo === null
|
|
||||||
? archivedLeaderboard.version!.value.entries.length
|
|
||||||
: regionRatingInfo.count) -
|
|
||||||
neighbors[neighbors.length - 1].position;
|
|
||||||
playerId = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
const items = players.map((player) => {
|
|
||||||
const midnightIndex =
|
|
||||||
archivedLeaderboard?.version!.value.entries.findIndex(
|
|
||||||
(item) => item.id === player.id
|
|
||||||
);
|
|
||||||
const midnightScore =
|
|
||||||
midnightIndex === undefined
|
|
||||||
? player.score
|
|
||||||
: archivedLeaderboard!.version!.value.entries[midnightIndex]
|
|
||||||
.score;
|
|
||||||
const midnightPosition =
|
|
||||||
midnightIndex === undefined ? player.position : midnightIndex + 1;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Leaderboard.Item
|
|
||||||
nickname={player.nickname}
|
|
||||||
score={player.score}
|
|
||||||
position={player.position}
|
|
||||||
clan={player.clan}
|
|
||||||
deltaScore={player.score - midnightScore}
|
|
||||||
deltaPosition={midnightPosition - player.position}
|
|
||||||
key={player.id}
|
|
||||||
highlight={player.id === playerId}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<CommandWrapper>
|
|
||||||
<TitleBar
|
|
||||||
title={titleName}
|
|
||||||
image={titleImage}
|
|
||||||
description={titleDescription}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{items && (
|
|
||||||
<Leaderboard.Root>
|
|
||||||
{items}
|
|
||||||
{playersAfter > 0 && (
|
|
||||||
<Leaderboard.Gap
|
|
||||||
message={literals(
|
|
||||||
strings.bot.commands.rating_leaderboard.body.more,
|
|
||||||
{ count: playersAfter.toLocaleString(interaction.locale) }
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Leaderboard.Root>
|
|
||||||
)}
|
|
||||||
</CommandWrapper>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
autocomplete: autocompleteUsername,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
@@ -1,592 +0,0 @@
|
|||||||
import {
|
|
||||||
calculateWN8,
|
|
||||||
emblemURL,
|
|
||||||
getClanAccountInfo,
|
|
||||||
idToRegion,
|
|
||||||
tankIcon,
|
|
||||||
TIER_ROMAN_NUMERALS,
|
|
||||||
} from "@blitzkit/core";
|
|
||||||
import { Locale } from "discord.js";
|
|
||||||
import { clamp } from "lodash-es";
|
|
||||||
import { CommandWrapper } from "../components/CommandWrapper";
|
|
||||||
import { TitleBar } from "../components/TitleBar";
|
|
||||||
import { iconPng } from "../core/blitzkit/iconPng";
|
|
||||||
import {
|
|
||||||
averageDefinitions,
|
|
||||||
mapDefinitions,
|
|
||||||
tankDefinitions,
|
|
||||||
} from "../core/blitzkit/nonBlockingPromises";
|
|
||||||
import { RenderConfiguration } from "../core/blitzkit/renderConfiguration";
|
|
||||||
import { buttonLink } from "../core/discord/buttonLink";
|
|
||||||
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
|
|
||||||
import { localizationObject } from "../core/discord/localizationObject";
|
|
||||||
import { translator } from "../core/localization/translator";
|
|
||||||
import { type CommandRegistry } from "../events/interactionCreate";
|
|
||||||
import { theme } from "../stitches.config";
|
|
||||||
|
|
||||||
type WotInspectorReplaySubmission =
|
|
||||||
| { status: "error"; data: unknown; error: { message: string } }
|
|
||||||
| {
|
|
||||||
status: "ok";
|
|
||||||
data: {
|
|
||||||
download_url: string;
|
|
||||||
view_url: string;
|
|
||||||
summary: {
|
|
||||||
battle_start_time: string;
|
|
||||||
map_name: string;
|
|
||||||
battle_start_timestamp: number;
|
|
||||||
battle_duration: number;
|
|
||||||
title: string;
|
|
||||||
arena_unique_id: string;
|
|
||||||
allies: number[];
|
|
||||||
enemies: number[];
|
|
||||||
protagonist: number;
|
|
||||||
player_name: string;
|
|
||||||
vehicle: string;
|
|
||||||
exp_base: number;
|
|
||||||
exp_total: number;
|
|
||||||
credits_base: number;
|
|
||||||
credits_total: number;
|
|
||||||
room_type: number;
|
|
||||||
battle_type: number;
|
|
||||||
mastery_badge: number;
|
|
||||||
battle_result: number;
|
|
||||||
vehicle_tier: number;
|
|
||||||
vehicle_type: number;
|
|
||||||
protagonist_team: number;
|
|
||||||
winner_team: number;
|
|
||||||
details: {
|
|
||||||
achievements: unknown[];
|
|
||||||
base_capture_points: number;
|
|
||||||
base_defend_points: number;
|
|
||||||
chassis_id: unknown | null;
|
|
||||||
clan_tag: string;
|
|
||||||
clanid: number;
|
|
||||||
credits: number;
|
|
||||||
damage_assisted: number;
|
|
||||||
damage_assisted_track: number;
|
|
||||||
damage_blocked: unknown | null;
|
|
||||||
damage_made: number;
|
|
||||||
damage_received: number;
|
|
||||||
dbid: number;
|
|
||||||
death_reason: number;
|
|
||||||
distance_travelled: number;
|
|
||||||
enemies_damaged: number;
|
|
||||||
enemies_destroyed: number;
|
|
||||||
enemies_spotted: number;
|
|
||||||
entity_id: number;
|
|
||||||
exp: number;
|
|
||||||
exp_for_assist: number;
|
|
||||||
exp_for_damage: number;
|
|
||||||
exp_team_bonus: number;
|
|
||||||
gun_id: unknown | null;
|
|
||||||
hero_bonus_credits: number;
|
|
||||||
hero_bonus_exp: number;
|
|
||||||
hitpoints_left: number;
|
|
||||||
hits_bounced: number;
|
|
||||||
hits_pen: number;
|
|
||||||
hits_received: number;
|
|
||||||
hits_splash: number;
|
|
||||||
killed_by: number;
|
|
||||||
name: string;
|
|
||||||
shots_hit: number;
|
|
||||||
shots_made: number;
|
|
||||||
shots_pen: number;
|
|
||||||
shots_splash: number;
|
|
||||||
squad_index: number;
|
|
||||||
team: number;
|
|
||||||
time_alive: number;
|
|
||||||
turret_id: unknown | null;
|
|
||||||
vehicle_descr: number;
|
|
||||||
wp_points_earned: number;
|
|
||||||
wp_points_stolen: number;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
error: {};
|
|
||||||
};
|
|
||||||
|
|
||||||
interface WotInspectorReplay {
|
|
||||||
id: string;
|
|
||||||
map_id: number;
|
|
||||||
battle_duration: number;
|
|
||||||
title: unknown | null;
|
|
||||||
player_name: string;
|
|
||||||
protagonist: number;
|
|
||||||
vehicle_descr: number;
|
|
||||||
mastery_badge: number;
|
|
||||||
exp_base: number;
|
|
||||||
enemies_spotted: number;
|
|
||||||
enemies_destroyed: number;
|
|
||||||
damage_assisted: number;
|
|
||||||
damage_made: number;
|
|
||||||
details_url: string;
|
|
||||||
download_url: string;
|
|
||||||
game_version: {
|
|
||||||
name: string;
|
|
||||||
package: string;
|
|
||||||
};
|
|
||||||
arena_unique_id: string;
|
|
||||||
download_count: number;
|
|
||||||
data_version: number;
|
|
||||||
private: boolean;
|
|
||||||
private_clan: boolean;
|
|
||||||
battle_start_time: Date;
|
|
||||||
upload_time: Date;
|
|
||||||
allies: number[];
|
|
||||||
enemies: number[];
|
|
||||||
protagonist_clan: number;
|
|
||||||
protagonist_team: number;
|
|
||||||
battle_result: number;
|
|
||||||
credits_base: number;
|
|
||||||
tags: number[];
|
|
||||||
battle_type: number;
|
|
||||||
room_type: number;
|
|
||||||
last_accessed_time: Date;
|
|
||||||
winner_team: number;
|
|
||||||
finish_reason: number;
|
|
||||||
players_data: WotInspectorReplayPlayerData[];
|
|
||||||
exp_total: number;
|
|
||||||
credits_total: number;
|
|
||||||
repair_cost: number;
|
|
||||||
exp_free: number;
|
|
||||||
exp_free_base: number;
|
|
||||||
exp_penalty: number;
|
|
||||||
credits_penalty: number;
|
|
||||||
credits_contribution_in: number;
|
|
||||||
credits_contribution_out: number;
|
|
||||||
camouflage_id: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface WotInspectorReplayPlayerData {
|
|
||||||
team: number;
|
|
||||||
name: string;
|
|
||||||
entity_id: number;
|
|
||||||
dbid: number;
|
|
||||||
clanid: number | null;
|
|
||||||
clan_tag: null | string;
|
|
||||||
hitpoints_left: number;
|
|
||||||
credits: number;
|
|
||||||
exp: number;
|
|
||||||
shots_made: number;
|
|
||||||
shots_hit: number;
|
|
||||||
shots_splash: number;
|
|
||||||
shots_pen: number;
|
|
||||||
damage_made: number;
|
|
||||||
damage_received: number;
|
|
||||||
damage_assisted: number;
|
|
||||||
damage_assisted_track: number;
|
|
||||||
hits_received: number;
|
|
||||||
hits_bounced: number;
|
|
||||||
hits_splash: number;
|
|
||||||
hits_pen: number;
|
|
||||||
enemies_spotted: number;
|
|
||||||
enemies_damaged: number;
|
|
||||||
enemies_destroyed: number;
|
|
||||||
time_alive: number;
|
|
||||||
distance_travelled: number;
|
|
||||||
killed_by: number;
|
|
||||||
base_capture_points: number;
|
|
||||||
base_defend_points: number;
|
|
||||||
exp_for_damage: number;
|
|
||||||
exp_for_assist: number;
|
|
||||||
exp_team_bonus: number;
|
|
||||||
wp_points_earned: number;
|
|
||||||
wp_points_stolen: number;
|
|
||||||
hero_bonus_credits: number;
|
|
||||||
hero_bonus_exp: number;
|
|
||||||
death_reason: number;
|
|
||||||
achievements: any[];
|
|
||||||
vehicle_descr: number;
|
|
||||||
turret_id: number;
|
|
||||||
gun_id: number;
|
|
||||||
chassis_id: number;
|
|
||||||
squad_index: number;
|
|
||||||
damage_blocked: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
function stat(value: string | number, flex = 2) {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
flex,
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span style={{ fontSize: 16 }}>{value}</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function playerListing(
|
|
||||||
locale: Locale,
|
|
||||||
player: WotInspectorReplayPlayerData,
|
|
||||||
protagonistTeam: boolean,
|
|
||||||
winningTeam: number,
|
|
||||||
recordingPlayer = false,
|
|
||||||
) {
|
|
||||||
const { unwrap } = translator(locale);
|
|
||||||
const awaitedTankAverages = await averageDefinitions;
|
|
||||||
const awaitedTankDefinitions = await tankDefinitions;
|
|
||||||
const tank = awaitedTankDefinitions.tanks[player.vehicle_descr];
|
|
||||||
const blockAccent = recordingPlayer ? "_amber" : "";
|
|
||||||
const healthAccent = protagonistTeam
|
|
||||||
? recordingPlayer
|
|
||||||
? "_amber"
|
|
||||||
: "_green"
|
|
||||||
: "_red";
|
|
||||||
|
|
||||||
// our turret ids are always off by 1 or 2 lol so imma just grab the closest
|
|
||||||
// TODO: 💀
|
|
||||||
const turret = tank.turrets.sort(
|
|
||||||
(a, b) =>
|
|
||||||
Math.abs(a.id - player.turret_id) - Math.abs(b.id - player.turret_id),
|
|
||||||
)[0];
|
|
||||||
const totalHealth = turret.health + tank.health;
|
|
||||||
const healthLeft = clamp(player.hitpoints_left / totalHealth, 0, 1);
|
|
||||||
const tankAveragesEntry = awaitedTankAverages.averages[player.vehicle_descr];
|
|
||||||
const wn8 =
|
|
||||||
tankAveragesEntry === undefined
|
|
||||||
? -1
|
|
||||||
: calculateWN8(tankAveragesEntry.mu, {
|
|
||||||
battles: 1,
|
|
||||||
damage_dealt: player.damage_made,
|
|
||||||
dropped_capture_points: player.base_defend_points,
|
|
||||||
frags: player.enemies_destroyed,
|
|
||||||
spotted: player.enemies_spotted,
|
|
||||||
wins: winningTeam === player.team ? 1 : 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
key={player.entity_id}
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
gap: 8,
|
|
||||||
backgroundColor: theme.colors[`appBackground2${blockAccent}`],
|
|
||||||
padding: 8,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
gap: 8,
|
|
||||||
flex: 1,
|
|
||||||
overflow: "hidden",
|
|
||||||
alignItems: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
alt={unwrap(tank.name)}
|
|
||||||
src={await iconPng(tankIcon(tank.id))}
|
|
||||||
style={{
|
|
||||||
width: 32,
|
|
||||||
height: 32,
|
|
||||||
objectFit: "contain",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
// align
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
gap: 4,
|
|
||||||
alignItems: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color: theme.colors[`textLowContrast${blockAccent}`],
|
|
||||||
fontSize: 12,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{TIER_ROMAN_NUMERALS[tank.tier]}
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color: theme.colors[`textHighContrast${blockAccent}`],
|
|
||||||
fontSize: 16,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{unwrap(tank.name)}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 16,
|
|
||||||
color: theme.colors[`textLowContrast${blockAccent}`],
|
|
||||||
whiteSpace: "nowrap",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{player.name}
|
|
||||||
{player.clan_tag ? ` [${player.clan_tag}]` : ""}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flex: 1,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{stat(player.damage_made.toLocaleString())}
|
|
||||||
{stat(wn8 === -1 ? "--" : Math.round(wn8).toLocaleString())}
|
|
||||||
{stat(player.exp.toLocaleString())}
|
|
||||||
{stat(player.enemies_destroyed, 1)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
borderRadius: 2,
|
|
||||||
backgroundColor: theme.colors[`componentInteractive${healthAccent}`],
|
|
||||||
display: "flex",
|
|
||||||
width: 4,
|
|
||||||
height: "100%",
|
|
||||||
transform: "scaleY(-1)",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
width: "100%",
|
|
||||||
height: `${healthLeft * 100}%`,
|
|
||||||
borderRadius: 2,
|
|
||||||
backgroundColor: theme.colors[`solidBackground${healthAccent}`],
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function Header() {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
padding: 8,
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
gap: 8,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div style={{ flex: 1 }} />
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flex: 1,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
flex: 2,
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 16,
|
|
||||||
color: theme.colors.textLowContrast,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Damage
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
flex: 2,
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 16,
|
|
||||||
color: theme.colors.textLowContrast,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
WN8
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
flex: 2,
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 16,
|
|
||||||
color: theme.colors.textLowContrast,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
XP
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
flex: 1,
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 16,
|
|
||||||
color: theme.colors.textLowContrast,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Kills
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const replayCommand = new Promise<CommandRegistry>((resolve) => {
|
|
||||||
const { strings } = translator(Locale.EnglishUS);
|
|
||||||
|
|
||||||
resolve({
|
|
||||||
command: createLocalizedCommand("replay").addAttachmentOption((option) =>
|
|
||||||
option
|
|
||||||
.setName(strings.bot.commands.replay.options.file.name)
|
|
||||||
.setNameLocalizations(
|
|
||||||
localizationObject(
|
|
||||||
(strings) => strings.bot.commands.replay.options.file.name,
|
|
||||||
undefined,
|
|
||||||
true,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.setDescription(strings.bot.commands.replay.options.file.description)
|
|
||||||
.setDescriptionLocalizations(
|
|
||||||
localizationObject(
|
|
||||||
(strings) => strings.bot.commands.replay.options.file.description,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.setRequired(true),
|
|
||||||
),
|
|
||||||
|
|
||||||
async handler(interaction) {
|
|
||||||
const awaitedMapDefinitions = await mapDefinitions;
|
|
||||||
const file = interaction.options.getAttachment("file")!;
|
|
||||||
const submissionData = (await fetch(
|
|
||||||
`https://wotinspector.com/api/replay/upload/?url=${encodeURIComponent(
|
|
||||||
file.url,
|
|
||||||
)}`,
|
|
||||||
).then((response) => response.json())) as WotInspectorReplaySubmission;
|
|
||||||
|
|
||||||
if (submissionData.status === "error") {
|
|
||||||
return `# Uh oh! WoT Inspector didn't like that.\n\nThere was an error processing your replay. Get help on [the official Discord server](https://discord.gg/nDt7AjGJQH).`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const replayId = submissionData.data.download_url.split("/").at(-1)!;
|
|
||||||
const replayData = (await fetch(
|
|
||||||
`https://api.wotinspector.com/v2/blitz/replays/${replayId}/`,
|
|
||||||
).then((response) => response.json())) as WotInspectorReplay;
|
|
||||||
const antagonistTeamId = 3 - replayData.protagonist_team;
|
|
||||||
const players = replayData.players_data.sort(
|
|
||||||
(a, b) => b.damage_made - a.damage_made,
|
|
||||||
);
|
|
||||||
const clan = (
|
|
||||||
await getClanAccountInfo(
|
|
||||||
idToRegion(replayData.protagonist),
|
|
||||||
replayData.protagonist,
|
|
||||||
["clan"],
|
|
||||||
)
|
|
||||||
)?.clan;
|
|
||||||
const clanImage = clan ? emblemURL(clan.emblem_set_id) : undefined;
|
|
||||||
|
|
||||||
return [
|
|
||||||
new RenderConfiguration({ width: 960 }),
|
|
||||||
<CommandWrapper>
|
|
||||||
<TitleBar
|
|
||||||
title={replayData.player_name}
|
|
||||||
image={clanImage}
|
|
||||||
description={`${
|
|
||||||
replayData.protagonist_team === replayData.winner_team
|
|
||||||
? "Victory"
|
|
||||||
: "Defeat"
|
|
||||||
} • ${awaitedMapDefinitions.maps[replayData.map_id].name}`}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
gap: 8,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
flex: 1,
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
gap: 4,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Header />
|
|
||||||
|
|
||||||
{await Promise.all(
|
|
||||||
players
|
|
||||||
.filter(
|
|
||||||
(player) => player.team === replayData.protagonist_team,
|
|
||||||
)
|
|
||||||
.map((player) =>
|
|
||||||
playerListing(
|
|
||||||
interaction.locale,
|
|
||||||
player,
|
|
||||||
true,
|
|
||||||
replayData.winner_team,
|
|
||||||
player.dbid === replayData.protagonist,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
flex: 1,
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
gap: 4,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Header />
|
|
||||||
|
|
||||||
{await Promise.all(
|
|
||||||
players
|
|
||||||
.filter((player) => player.team === antagonistTeamId)
|
|
||||||
.map((player) =>
|
|
||||||
playerListing(
|
|
||||||
interaction.locale,
|
|
||||||
player,
|
|
||||||
false,
|
|
||||||
replayData.winner_team,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</CommandWrapper>,
|
|
||||||
buttonLink(submissionData.data.view_url, "WoT Inspector"),
|
|
||||||
buttonLink(submissionData.data.download_url, "Download"),
|
|
||||||
];
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,626 +0,0 @@
|
|||||||
import {
|
|
||||||
asset,
|
|
||||||
emblemURL,
|
|
||||||
equipmentPriceMatrix,
|
|
||||||
getAccountInfo,
|
|
||||||
getClanAccountInfo,
|
|
||||||
getTankStats,
|
|
||||||
TANK_ICONS,
|
|
||||||
TankType,
|
|
||||||
TIER_ROMAN_NUMERALS,
|
|
||||||
} from "@blitzkit/core";
|
|
||||||
import { literals } from "@blitzkit/i18n";
|
|
||||||
import { escapeMarkdown, Locale } from "discord.js";
|
|
||||||
import { CommandWrapper } from "../components/CommandWrapper";
|
|
||||||
import { TitleBar } from "../components/TitleBar";
|
|
||||||
import { resolveTankId } from "../core/blitz/resolveTankId";
|
|
||||||
import { buildTechTreeLine } from "../core/blitzkit/buildTechTreeLine";
|
|
||||||
import { iconPng } from "../core/blitzkit/iconPng";
|
|
||||||
import { tankDefinitions } from "../core/blitzkit/nonBlockingPromises";
|
|
||||||
import { resolveAncestry } from "../core/blitzkit/resolveAncestry";
|
|
||||||
import { tankIconPng } from "../core/blitzkit/tankIconPng";
|
|
||||||
import { addUsernameChoices } from "../core/discord/addUsernameChoices";
|
|
||||||
import { autocompleteTanks } from "../core/discord/autocompleteTanks";
|
|
||||||
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
|
|
||||||
import { localizationObject } from "../core/discord/localizationObject";
|
|
||||||
import { resolvePlayerFromCommand } from "../core/discord/resolvePlayerFromCommand";
|
|
||||||
import { translator } from "../core/localization/translator";
|
|
||||||
import { type CommandRegistry } from "../events/interactionCreate";
|
|
||||||
import { theme } from "../stitches.config";
|
|
||||||
|
|
||||||
export const researchCommand = new Promise<CommandRegistry>((resolve) => {
|
|
||||||
const { strings } = translator(Locale.EnglishUS);
|
|
||||||
|
|
||||||
resolve({
|
|
||||||
command: createLocalizedCommand("research")
|
|
||||||
.addStringOption((option) =>
|
|
||||||
option
|
|
||||||
.setName(strings.bot.commands.research.options.target_tank.name)
|
|
||||||
.setNameLocalizations(
|
|
||||||
localizationObject(
|
|
||||||
(strings) =>
|
|
||||||
strings.bot.commands.research.options.target_tank.name,
|
|
||||||
undefined,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.setDescription(
|
|
||||||
strings.bot.commands.research.options.target_tank.description
|
|
||||||
)
|
|
||||||
.setDescriptionLocalizations(
|
|
||||||
localizationObject(
|
|
||||||
(strings) =>
|
|
||||||
strings.bot.commands.research.options.target_tank.description
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.setAutocomplete(true)
|
|
||||||
.setRequired(true)
|
|
||||||
)
|
|
||||||
.addStringOption((option) =>
|
|
||||||
option
|
|
||||||
.setName(strings.bot.commands.research.options.starting_tank.name)
|
|
||||||
.setNameLocalizations(
|
|
||||||
localizationObject(
|
|
||||||
(strings) =>
|
|
||||||
strings.bot.commands.research.options.starting_tank.name,
|
|
||||||
undefined,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.setDescription(
|
|
||||||
strings.bot.commands.research.options.starting_tank.description
|
|
||||||
)
|
|
||||||
.setDescriptionLocalizations(
|
|
||||||
localizationObject(
|
|
||||||
(strings) =>
|
|
||||||
strings.bot.commands.research.options.starting_tank.description
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.setAutocomplete(true)
|
|
||||||
.setRequired(false)
|
|
||||||
)
|
|
||||||
.addStringOption(addUsernameChoices),
|
|
||||||
|
|
||||||
async handler(interaction) {
|
|
||||||
const { strings, unwrap } = translator(interaction.locale);
|
|
||||||
const awaitedTankDefinitions = await tankDefinitions;
|
|
||||||
const targetTankId = await resolveTankId(
|
|
||||||
interaction.options.getString("target-tank", true),
|
|
||||||
interaction.locale,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
const startingTankRaw = interaction.options.getString("starting-tank");
|
|
||||||
const targetTank = awaitedTankDefinitions.tanks[targetTankId];
|
|
||||||
const { id, region } = await resolvePlayerFromCommand(interaction);
|
|
||||||
let startingTankId: number;
|
|
||||||
const targetTankAncestry = await resolveAncestry(targetTankId);
|
|
||||||
|
|
||||||
if (startingTankRaw) {
|
|
||||||
startingTankId = await resolveTankId(
|
|
||||||
startingTankRaw,
|
|
||||||
interaction.locale,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
if (targetTankId === startingTankId) {
|
|
||||||
return literals(
|
|
||||||
strings.bot.commands.research.errors.start_end_equal,
|
|
||||||
{ tank: escapeMarkdown(unwrap(targetTank.name)) }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const startingTank = awaitedTankDefinitions.tanks[startingTankId];
|
|
||||||
|
|
||||||
if (startingTank.tier > targetTank.tier) {
|
|
||||||
return literals(strings.bot.commands.research.errors.unordered, {
|
|
||||||
tank_1: escapeMarkdown(unwrap(startingTank.name)),
|
|
||||||
tank_2: escapeMarkdown(unwrap(targetTank.name)),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!targetTankAncestry.includes(startingTankId)) {
|
|
||||||
return literals(
|
|
||||||
strings.bot.commands.research.errors.tanks_not_on_line,
|
|
||||||
{
|
|
||||||
tank_1: escapeMarkdown(unwrap(targetTank.name)),
|
|
||||||
tank_2: escapeMarkdown(unwrap(startingTank.name)),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (targetTank.type !== TankType.RESEARCHABLE) {
|
|
||||||
return literals(strings.bot.commands.research.errors.non_tech_tree, {
|
|
||||||
tank: escapeMarkdown(unwrap(targetTank.name)),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (targetTank.tier === 1) {
|
|
||||||
return literals(strings.bot.commands.research.errors.tier_1, {
|
|
||||||
tank: escapeMarkdown(unwrap(targetTank.name)),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const tankStats = await getTankStats(region, id);
|
|
||||||
|
|
||||||
if (tankStats === null) {
|
|
||||||
return strings.bot.common.errors.no_tank_stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tankStats.some(({ tank_id }) => tank_id === targetTankId)) {
|
|
||||||
return literals(
|
|
||||||
strings.bot.commands.research.errors.already_researched,
|
|
||||||
{ tank: escapeMarkdown(unwrap(targetTank.name)) }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const foundAncestor = targetTankAncestry.find(
|
|
||||||
(id) =>
|
|
||||||
awaitedTankDefinitions.tanks[id].tier === 1 ||
|
|
||||||
tankStats.some(({ tank_id }) => tank_id === id)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (foundAncestor === undefined) {
|
|
||||||
throw new Error("No first owned tech tree found.");
|
|
||||||
}
|
|
||||||
|
|
||||||
startingTankId = foundAncestor;
|
|
||||||
}
|
|
||||||
|
|
||||||
const techTreeLine = await buildTechTreeLine(
|
|
||||||
startingTankId,
|
|
||||||
targetTankId
|
|
||||||
);
|
|
||||||
|
|
||||||
const line = [...techTreeLine, startingTankId].reverse();
|
|
||||||
const { nickname } = await getAccountInfo(region, id);
|
|
||||||
const clan = (await getClanAccountInfo(region, id, ["clan"]))?.clan;
|
|
||||||
const clanImage = clan ? emblemURL(clan.emblem_set_id) : undefined;
|
|
||||||
const costs = await Promise.all(
|
|
||||||
line.map(async (id) => {
|
|
||||||
const tank = awaitedTankDefinitions.tanks[id];
|
|
||||||
const turretXps = new Map<number, number>();
|
|
||||||
const gunXps = new Map<number, number>();
|
|
||||||
const engineXps = new Map<number, number>();
|
|
||||||
const trackXps = new Map<number, number>();
|
|
||||||
|
|
||||||
tank.turrets.forEach((turret) => {
|
|
||||||
if (
|
|
||||||
turret.research_cost !== undefined &&
|
|
||||||
typeof turret.research_cost.research_cost_type!.value === "number"
|
|
||||||
) {
|
|
||||||
turretXps.set(
|
|
||||||
turret.id,
|
|
||||||
turret.research_cost.research_cost_type!.value
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
turret.guns.forEach((gun) => {
|
|
||||||
if (
|
|
||||||
gun.research_cost !== undefined &&
|
|
||||||
typeof gun.research_cost.research_cost_type!.value === "number"
|
|
||||||
) {
|
|
||||||
gunXps.set(gun.id, gun.research_cost.research_cost_type!.value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
tank.engines.forEach((engine) => {
|
|
||||||
if (
|
|
||||||
engine.research_cost !== undefined &&
|
|
||||||
typeof engine.research_cost.research_cost_type!.value === "number"
|
|
||||||
) {
|
|
||||||
engineXps.set(
|
|
||||||
engine.id,
|
|
||||||
engine.research_cost.research_cost_type!.value
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
tank.tracks.forEach((track) => {
|
|
||||||
if (
|
|
||||||
track.research_cost !== undefined &&
|
|
||||||
typeof track.research_cost.research_cost_type!.value === "number"
|
|
||||||
) {
|
|
||||||
trackXps.set(
|
|
||||||
track.id,
|
|
||||||
track.research_cost.research_cost_type!.value
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let moduleXp = 0;
|
|
||||||
turretXps.forEach((value) => {
|
|
||||||
moduleXp += value;
|
|
||||||
});
|
|
||||||
gunXps.forEach((value) => {
|
|
||||||
moduleXp += value;
|
|
||||||
});
|
|
||||||
engineXps.forEach((value) => {
|
|
||||||
moduleXp += value;
|
|
||||||
});
|
|
||||||
trackXps.forEach((value) => {
|
|
||||||
moduleXp += value;
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
research: tank.research_cost!.research_cost_type!.value as number,
|
|
||||||
upgrades: moduleXp,
|
|
||||||
purchase: tank.price.value,
|
|
||||||
equipment: equipmentPriceMatrix[tank.tier].reduce(
|
|
||||||
(a, b) => a + 3 * b,
|
|
||||||
0
|
|
||||||
),
|
|
||||||
};
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
const image = (
|
|
||||||
<CommandWrapper>
|
|
||||||
<TitleBar
|
|
||||||
title={nickname}
|
|
||||||
image={clanImage}
|
|
||||||
description={`${strings.bot.commands.research.body.subtitle} • ${
|
|
||||||
targetTank.name
|
|
||||||
}`}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
gap: 8,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
borderRadius: 4,
|
|
||||||
backgroundColor: theme.colors.appBackground2,
|
|
||||||
border: theme.borderStyles.subtle,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div style={{ width: 48 }}></div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
flex: 1,
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
position: "relative",
|
|
||||||
right: 24,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color: theme.colors.textHighContrast,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{strings.bot.commands.research.body.total}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
flex: 1,
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
justifyContent: "center",
|
|
||||||
gap: 8,
|
|
||||||
padding: "16px 0",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
gap: 4,
|
|
||||||
alignItems: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
alt="XP icon"
|
|
||||||
src={await iconPng(asset("icons/currencies/xp.webp"))}
|
|
||||||
width={16}
|
|
||||||
height={16}
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 16,
|
|
||||||
color: theme.colors.textHighContrast,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Experience:{" "}
|
|
||||||
{costs
|
|
||||||
.reduce((a, b) => a + (b.research ?? 0) + b.upgrades, 0)
|
|
||||||
.toLocaleString(interaction.locale)}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
gap: 4,
|
|
||||||
alignItems: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
alt="Silver icon"
|
|
||||||
src={await iconPng(asset("icons/currencies/silver.webp"))}
|
|
||||||
width={16}
|
|
||||||
height={16}
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 16,
|
|
||||||
color: theme.colors.textHighContrast,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Purchase:{" "}
|
|
||||||
{costs
|
|
||||||
.reduce((a, b) => a + b.purchase, 0)
|
|
||||||
.toLocaleString(interaction.locale)}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
gap: 4,
|
|
||||||
alignItems: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
alt="Silver icon"
|
|
||||||
src={await iconPng(asset("icons/currencies/silver.webp"))}
|
|
||||||
width={16}
|
|
||||||
height={16}
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 16,
|
|
||||||
color: theme.colors.textHighContrast,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Equipment:{" "}
|
|
||||||
{costs
|
|
||||||
.reduce((a, b) => a + b.equipment, 0)
|
|
||||||
.toLocaleString(interaction.locale)}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{await Promise.all(
|
|
||||||
line.map(async (id, index) => {
|
|
||||||
const tank = awaitedTankDefinitions.tanks[id];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
key={id}
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
borderRadius: 4,
|
|
||||||
backgroundColor: theme.colors.appBackground2,
|
|
||||||
border: theme.borderStyles.subtle,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
width: 48,
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color: theme.colors.textLowContrast,
|
|
||||||
fontSize: 16,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{TIER_ROMAN_NUMERALS[tank.tier]}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
flex: 1,
|
|
||||||
display: "flex",
|
|
||||||
position: "relative",
|
|
||||||
right: "5%",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
alt="Tank icon"
|
|
||||||
src={await tankIconPng(id)}
|
|
||||||
style={{
|
|
||||||
height: 100,
|
|
||||||
width: 100,
|
|
||||||
objectFit: "contain",
|
|
||||||
position: "absolute",
|
|
||||||
left: "25%",
|
|
||||||
top: 0,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
gap: 4,
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
position: "absolute",
|
|
||||||
bottom: 8,
|
|
||||||
left: "50%",
|
|
||||||
transform: "translateX(-50%)",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
alt={unwrap(tank.name)}
|
|
||||||
src={TANK_ICONS[tank.class]}
|
|
||||||
width={16}
|
|
||||||
height={16}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color: theme.colors.textHighContrast,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{unwrap(tank.name)}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
flex: 1,
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
justifyContent: "center",
|
|
||||||
gap: 8,
|
|
||||||
padding: "16px 0",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
gap: 4,
|
|
||||||
alignItems: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
alt="XP icon"
|
|
||||||
src={await iconPng(asset("icons/currencies/xp.webp"))}
|
|
||||||
width={16}
|
|
||||||
height={16}
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 16,
|
|
||||||
color: theme.colors.textHighContrast,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{literals(
|
|
||||||
strings.bot.commands.research.body.research,
|
|
||||||
{
|
|
||||||
cost: costs[index].research?.toLocaleString(
|
|
||||||
interaction.locale
|
|
||||||
),
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{costs[index].upgrades > 0 && (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
gap: 4,
|
|
||||||
alignItems: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
alt="Free XP icon"
|
|
||||||
src={await iconPng(
|
|
||||||
asset("icons/currencies/free-xp.webp")
|
|
||||||
)}
|
|
||||||
width={16}
|
|
||||||
height={16}
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 16,
|
|
||||||
color: theme.colors.textHighContrast,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{literals(
|
|
||||||
strings.bot.commands.research.body.upgrades,
|
|
||||||
{ cost: costs[index].upgrades.toLocaleString() }
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
gap: 4,
|
|
||||||
alignItems: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
alt="Silver icon"
|
|
||||||
src={await iconPng(
|
|
||||||
asset("icons/currencies/silver.webp")
|
|
||||||
)}
|
|
||||||
width={16}
|
|
||||||
height={16}
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 16,
|
|
||||||
color: theme.colors.textHighContrast,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{literals(
|
|
||||||
strings.bot.commands.research.body.purchase,
|
|
||||||
{
|
|
||||||
cost: costs[index].purchase.toLocaleString(
|
|
||||||
interaction.locale
|
|
||||||
),
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
gap: 4,
|
|
||||||
alignItems: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
alt="Silver icon"
|
|
||||||
src={await iconPng(
|
|
||||||
asset("icons/currencies/silver.webp")
|
|
||||||
)}
|
|
||||||
width={16}
|
|
||||||
height={16}
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 16,
|
|
||||||
color: theme.colors.textHighContrast,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{literals(
|
|
||||||
strings.bot.commands.research.body.equipment,
|
|
||||||
{
|
|
||||||
cost: costs[index].equipment.toLocaleString(
|
|
||||||
interaction.locale
|
|
||||||
),
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</CommandWrapper>
|
|
||||||
);
|
|
||||||
|
|
||||||
return startingTankRaw
|
|
||||||
? image
|
|
||||||
: [strings.bot.commands.research.body.estimation, image];
|
|
||||||
},
|
|
||||||
|
|
||||||
autocomplete(interaction) {
|
|
||||||
autocompleteTanks(interaction, true, ["target-tank", "starting-tank"]);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
import { type ClanList, fetchBlitz, type Region } from "@blitzkit/core";
|
|
||||||
import { literals } from "@blitzkit/i18n";
|
|
||||||
import { Locale } from "discord.js";
|
|
||||||
import markdownEscape from "markdown-escape";
|
|
||||||
import { addClanChoices } from "../core/discord/addClanChoices";
|
|
||||||
import { addRegionChoices } from "../core/discord/addRegionChoices";
|
|
||||||
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
|
|
||||||
import { embedInfo } from "../core/discord/embedInfo";
|
|
||||||
import { localizationObject } from "../core/discord/localizationObject";
|
|
||||||
import { translator } from "../core/localization/translator";
|
|
||||||
import type { CommandRegistry } from "../events/interactionCreate";
|
|
||||||
|
|
||||||
const DEFAULT_LIMIT = 25;
|
|
||||||
|
|
||||||
export const searchClansCommand = new Promise<CommandRegistry>((resolve) => {
|
|
||||||
resolve({
|
|
||||||
command: createLocalizedCommand("search-clans")
|
|
||||||
.addStringOption(addRegionChoices)
|
|
||||||
.addStringOption((option) =>
|
|
||||||
addClanChoices(option).setAutocomplete(false)
|
|
||||||
)
|
|
||||||
.addIntegerOption((option) => {
|
|
||||||
const { strings } = translator(Locale.EnglishUS);
|
|
||||||
|
|
||||||
return option
|
|
||||||
.setName(strings.bot.commands.search_clans.options.limit.name)
|
|
||||||
.setNameLocalizations(
|
|
||||||
localizationObject(
|
|
||||||
(strings) => strings.bot.commands.search_clans.options.limit.name,
|
|
||||||
undefined,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.setDescription(
|
|
||||||
literals(
|
|
||||||
strings.bot.commands.search_clans.options.limit.description,
|
|
||||||
{ limit: DEFAULT_LIMIT }
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.setDescriptionLocalizations(
|
|
||||||
localizationObject(
|
|
||||||
(strings) =>
|
|
||||||
strings.bot.commands.search_clans.options.limit.description,
|
|
||||||
{ limit: DEFAULT_LIMIT }
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.setMinValue(1)
|
|
||||||
.setMaxValue(100);
|
|
||||||
}),
|
|
||||||
|
|
||||||
async handler(interaction) {
|
|
||||||
const { strings } = translator(interaction.locale);
|
|
||||||
const region = interaction.options.getString("region") as Region;
|
|
||||||
const clan = interaction.options.getString("clan")!;
|
|
||||||
const limit = interaction.options.getInteger("limit") ?? DEFAULT_LIMIT;
|
|
||||||
const clanList = await fetchBlitz<ClanList>(region, "clans/list", {
|
|
||||||
search: clan,
|
|
||||||
limit,
|
|
||||||
});
|
|
||||||
|
|
||||||
return embedInfo(
|
|
||||||
literals(strings.bot.commands.search_clans.body.title, {
|
|
||||||
search: markdownEscape(clan),
|
|
||||||
region: strings.common.regions.normal[region],
|
|
||||||
}),
|
|
||||||
clanList.length === 0
|
|
||||||
? strings.bot.commands.search_clans.body.no_results
|
|
||||||
: `\`\`\`\n${clanList
|
|
||||||
.map((clan) => `${clan.name} [${clan.tag}]`)
|
|
||||||
.join("\n")}\n\`\`\``
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
import {
|
|
||||||
type AccountList,
|
|
||||||
fetchBlitz,
|
|
||||||
type Region,
|
|
||||||
usernamePattern,
|
|
||||||
} from "@blitzkit/core";
|
|
||||||
import { literals } from "@blitzkit/i18n";
|
|
||||||
import { Locale } from "discord.js";
|
|
||||||
import markdownEscape from "markdown-escape";
|
|
||||||
import { addRegionChoices } from "../core/discord/addRegionChoices";
|
|
||||||
import { addUsernameChoices } from "../core/discord/addUsernameChoices";
|
|
||||||
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
|
|
||||||
import { embedInfo } from "../core/discord/embedInfo";
|
|
||||||
import { localizationObject } from "../core/discord/localizationObject";
|
|
||||||
import { translator } from "../core/localization/translator";
|
|
||||||
import type { CommandRegistry } from "../events/interactionCreate";
|
|
||||||
|
|
||||||
const DEFAULT_LIMIT = 25;
|
|
||||||
|
|
||||||
export const searchPlayersCommand = new Promise<CommandRegistry>((resolve) => {
|
|
||||||
const { strings } = translator(Locale.EnglishUS);
|
|
||||||
|
|
||||||
resolve({
|
|
||||||
command: createLocalizedCommand("search-players")
|
|
||||||
.addStringOption(addRegionChoices)
|
|
||||||
.addStringOption((option) =>
|
|
||||||
addUsernameChoices(option).setAutocomplete(false).setRequired(true)
|
|
||||||
)
|
|
||||||
.addIntegerOption((option) =>
|
|
||||||
option
|
|
||||||
.setName(strings.bot.commands.search_players.options.limit.name)
|
|
||||||
.setNameLocalizations(
|
|
||||||
localizationObject(
|
|
||||||
(strings) =>
|
|
||||||
strings.bot.commands.search_players.options.limit.name,
|
|
||||||
undefined,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.setDescription(
|
|
||||||
literals(
|
|
||||||
strings.bot.commands.search_players.options.limit.description,
|
|
||||||
{ limit: DEFAULT_LIMIT }
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.setDescriptionLocalizations(
|
|
||||||
localizationObject(
|
|
||||||
(strings) =>
|
|
||||||
strings.bot.commands.search_players.options.limit.description,
|
|
||||||
{ limit: DEFAULT_LIMIT }
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.setMinValue(1)
|
|
||||||
.setMaxValue(100)
|
|
||||||
),
|
|
||||||
|
|
||||||
async handler(interaction) {
|
|
||||||
const { strings } = translator(interaction.locale);
|
|
||||||
const region = interaction.options.getString("region") as Region;
|
|
||||||
const name = interaction.options.getString("username")!;
|
|
||||||
const limit = interaction.options.getInteger("limit") ?? 25;
|
|
||||||
const trimmedSearch = name.trim();
|
|
||||||
const players = usernamePattern.test(trimmedSearch)
|
|
||||||
? await fetchBlitz<AccountList>(region, "account/list", {
|
|
||||||
search: trimmedSearch,
|
|
||||||
limit,
|
|
||||||
})
|
|
||||||
: [];
|
|
||||||
|
|
||||||
return embedInfo(
|
|
||||||
literals(strings.bot.commands.search_players.body.title, {
|
|
||||||
search: markdownEscape(trimmedSearch),
|
|
||||||
region: strings.common.regions.normal[region],
|
|
||||||
}),
|
|
||||||
`\`\`\`${
|
|
||||||
players.length === 0
|
|
||||||
? strings.bot.commands.search_players.body.no_results
|
|
||||||
: players.map((player) => player.nickname).join("\n")
|
|
||||||
}\`\`\``
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
import { emblemURL, getAccountInfo, getClanAccountInfo } from "@blitzkit/core";
|
|
||||||
import { Locale } from "discord.js";
|
|
||||||
import { AllStatsOverview } from "../components/AllStatsOverview";
|
|
||||||
import { CommandWrapper } from "../components/CommandWrapper";
|
|
||||||
import { NoData } from "../components/NoData";
|
|
||||||
import { TitleBar } from "../components/TitleBar";
|
|
||||||
import { filtersToDescription } from "../core/blitzkit/filtersToDescription";
|
|
||||||
import { filterStats, type StatFilters } from "../core/blitzstars/filterStats";
|
|
||||||
import { getStatsInPeriod } from "../core/blitzstars/getStatsInPeriod";
|
|
||||||
import { addPeriodicFilterOptions } from "../core/discord/addPeriodicFilterOptions";
|
|
||||||
import { addUsernameChoices } from "../core/discord/addUsernameChoices";
|
|
||||||
import { autocompleteTanks } from "../core/discord/autocompleteTanks";
|
|
||||||
import { autocompleteUsername } from "../core/discord/autocompleteUsername";
|
|
||||||
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
|
|
||||||
import { getFiltersFromButton } from "../core/discord/getFiltersFromButton";
|
|
||||||
import { resolvePeriodFromButton } from "../core/discord/resolvePeriodFromButton";
|
|
||||||
import { type ResolvedPeriod } from "../core/discord/resolvePeriodFromCommand";
|
|
||||||
import { resolvePlayerFromButton } from "../core/discord/resolvePlayerFromButton";
|
|
||||||
import { type ResolvedPlayer } from "../core/discord/resolvePlayerFromCommand";
|
|
||||||
import { translator } from "../core/localization/translator";
|
|
||||||
import type { CommandRegistry } from "../events/interactionCreate";
|
|
||||||
|
|
||||||
async function render(
|
|
||||||
{ region, id }: ResolvedPlayer,
|
|
||||||
{ start, end, name }: ResolvedPeriod,
|
|
||||||
filters: StatFilters,
|
|
||||||
locale: Locale,
|
|
||||||
) {
|
|
||||||
const { nickname } = await getAccountInfo(region, id);
|
|
||||||
const clan = (await getClanAccountInfo(region, id, ["clan"]))?.clan;
|
|
||||||
const clanImage = clan ? emblemURL(clan.emblem_set_id) : undefined;
|
|
||||||
const diffedTankStats = await getStatsInPeriod(
|
|
||||||
region,
|
|
||||||
id,
|
|
||||||
start,
|
|
||||||
end,
|
|
||||||
locale,
|
|
||||||
);
|
|
||||||
const { stats, supplementary } = await filterStats(diffedTankStats, filters);
|
|
||||||
const filterDescriptions = await filtersToDescription(filters, locale);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<CommandWrapper>
|
|
||||||
<TitleBar
|
|
||||||
title={nickname}
|
|
||||||
image={clanImage}
|
|
||||||
description={`${name} • ${filterDescriptions}`}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{!stats.battles && <NoData type="battles_in_period" locale={locale} />}
|
|
||||||
{stats.battles > 0 && (
|
|
||||||
<AllStatsOverview
|
|
||||||
locale={locale}
|
|
||||||
stats={stats}
|
|
||||||
supplementaryStats={supplementary}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</CommandWrapper>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const statsCommand = new Promise<CommandRegistry>(async (resolve) => {
|
|
||||||
resolve({
|
|
||||||
command: await addPeriodicFilterOptions(
|
|
||||||
createLocalizedCommand("stats"),
|
|
||||||
(option) => option.addStringOption(addUsernameChoices),
|
|
||||||
),
|
|
||||||
|
|
||||||
async handler(interaction) {
|
|
||||||
const { strings } = translator(interaction.locale);
|
|
||||||
return strings.bot.commands.dead;
|
|
||||||
|
|
||||||
// const player = await resolvePlayerFromCommand(interaction);
|
|
||||||
// const period = resolvePeriodFromCommand(player.region, interaction);
|
|
||||||
// const filters = await getFiltersFromCommand(interaction);
|
|
||||||
// const path = commandToURL(interaction, {
|
|
||||||
// ...player,
|
|
||||||
// ...getCustomPeriodParams(interaction),
|
|
||||||
// ...filters,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// return Promise.all([
|
|
||||||
// render(player, period, filters, interaction.locale),
|
|
||||||
// buttonRefresh(interaction, path),
|
|
||||||
// getBlitzStarsLinkButton(player.region, player.id),
|
|
||||||
// ]);
|
|
||||||
},
|
|
||||||
|
|
||||||
autocomplete: (interaction) => {
|
|
||||||
autocompleteUsername(interaction);
|
|
||||||
autocompleteTanks(interaction);
|
|
||||||
},
|
|
||||||
|
|
||||||
async button(interaction) {
|
|
||||||
const player = await resolvePlayerFromButton(interaction);
|
|
||||||
const period = resolvePeriodFromButton(player.region, interaction);
|
|
||||||
const filters = getFiltersFromButton(interaction);
|
|
||||||
|
|
||||||
return await render(player, period, filters, interaction.locale);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
import { gameDefinitions } from "../core/blitzkit/nonBlockingPromises";
|
|
||||||
import { addFilterOptions } from "../core/discord/addFilterOptions";
|
|
||||||
import { addUsernameChoices } from "../core/discord/addUsernameChoices";
|
|
||||||
import { autocompleteTanks } from "../core/discord/autocompleteTanks";
|
|
||||||
import { autocompleteUsername } from "../core/discord/autocompleteUsername";
|
|
||||||
import { createLocalizedCommand } from "../core/discord/createLocalizedCommand";
|
|
||||||
import { getFiltersFromButton } from "../core/discord/getFiltersFromButton";
|
|
||||||
import { resolvePeriodFromButton } from "../core/discord/resolvePeriodFromButton";
|
|
||||||
import { resolvePlayerFromButton } from "../core/discord/resolvePlayerFromButton";
|
|
||||||
import { translator } from "../core/localization/translator";
|
|
||||||
import { type CommandRegistry } from "../events/interactionCreate";
|
|
||||||
import { renderBreakdown } from "./breakdown/render";
|
|
||||||
|
|
||||||
export const todayCommand = new Promise<CommandRegistry>(async (resolve) => {
|
|
||||||
const awaitedGameDefinitions = await gameDefinitions;
|
|
||||||
|
|
||||||
resolve({
|
|
||||||
command: addFilterOptions(
|
|
||||||
createLocalizedCommand("today"),
|
|
||||||
awaitedGameDefinitions.nations,
|
|
||||||
).addStringOption(addUsernameChoices),
|
|
||||||
|
|
||||||
async handler(interaction) {
|
|
||||||
const { strings } = translator(interaction.locale);
|
|
||||||
return strings.bot.commands.dead;
|
|
||||||
|
|
||||||
// const player = await resolvePlayerFromCommand(interaction);
|
|
||||||
// const period = resolvePeriodFromCommand(
|
|
||||||
// player.region,
|
|
||||||
// interaction,
|
|
||||||
// 'today',
|
|
||||||
// );
|
|
||||||
// const filters = await getFiltersFromCommand(interaction);
|
|
||||||
// const path = commandToURL(interaction, {
|
|
||||||
// ...player,
|
|
||||||
// ...getCustomPeriodParams(interaction, true),
|
|
||||||
// ...filters,
|
|
||||||
// });
|
|
||||||
|
|
||||||
// return [
|
|
||||||
// ...(await renderBreakdown(player, period, filters, interaction.locale)),
|
|
||||||
// buttonRefresh(interaction, path),
|
|
||||||
// await getBlitzStarsLinkButton(player.region, player.id),
|
|
||||||
// ];
|
|
||||||
},
|
|
||||||
|
|
||||||
autocomplete: (interaction) => {
|
|
||||||
autocompleteUsername(interaction);
|
|
||||||
autocompleteTanks(interaction);
|
|
||||||
},
|
|
||||||
|
|
||||||
async button(interaction) {
|
|
||||||
const player = await resolvePlayerFromButton(interaction);
|
|
||||||
const period = resolvePeriodFromButton(player.region, interaction);
|
|
||||||
const filters = getFiltersFromButton(interaction);
|
|
||||||
|
|
||||||
return await renderBreakdown(player, period, filters, interaction.locale);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
import { type ComponentProps } from "react";
|
|
||||||
|
|
||||||
export interface GlowProps extends ComponentProps<"div"> {
|
|
||||||
color: string;
|
|
||||||
direction?: "default" | "reverse";
|
|
||||||
rotation?: number;
|
|
||||||
startOpacity?: number;
|
|
||||||
endOpacity?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
const width = 16;
|
|
||||||
|
|
||||||
export function Glow({
|
|
||||||
color,
|
|
||||||
direction = "default",
|
|
||||||
rotation = 0,
|
|
||||||
style,
|
|
||||||
startOpacity = 0,
|
|
||||||
endOpacity = 1,
|
|
||||||
...props
|
|
||||||
}: GlowProps) {
|
|
||||||
const color1 = `${color}${Math.round(endOpacity * 255)
|
|
||||||
.toString(16)
|
|
||||||
.padStart(2, "0")}`;
|
|
||||||
const color2 = `${color}${Math.round(startOpacity * 255)
|
|
||||||
.toString(16)
|
|
||||||
.padStart(2, "0")}`;
|
|
||||||
const background = `linear-gradient(${
|
|
||||||
direction === "default" ? 0 : 180
|
|
||||||
}deg, ${color1} 0%, ${color2} 100%)`;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: direction === "default" ? "flex-end" : "flex-start",
|
|
||||||
justifyContent: "center",
|
|
||||||
transform: `rotate(${rotation}deg)`,
|
|
||||||
...style,
|
|
||||||
}}
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
<div style={{ height: 54, width, background }} />
|
|
||||||
<div style={{ height: 72, width, background }} />
|
|
||||||
<div style={{ height: 80, width, background }} />
|
|
||||||
<div style={{ height: 72, width, background }} />
|
|
||||||
<div style={{ height: 54, width, background }} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
import { theme } from '../../../../stitches.config';
|
|
||||||
import { Glow } from './components/Glow';
|
|
||||||
|
|
||||||
export interface WN8DisplayProps {
|
|
||||||
subtitle: string;
|
|
||||||
color: string;
|
|
||||||
value: string | number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function HeroStat({ color, subtitle, value }: WN8DisplayProps) {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
width: 128 * 2, // idk why twice the width turns into the correct width
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Glow color={color} style={{ marginBottom: -16 }} />
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
width: 128,
|
|
||||||
height: 80,
|
|
||||||
backgroundColor: color,
|
|
||||||
borderRadius: 40,
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
gap: 2,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
display: 'block',
|
|
||||||
fontWeight: 900,
|
|
||||||
fontSize: 32,
|
|
||||||
color: theme.colors.textHighContrast,
|
|
||||||
lineHeight: '26px',
|
|
||||||
letterSpacing: '-0.03em',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{value}
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
display: 'block',
|
|
||||||
fontSize: 16,
|
|
||||||
lineHeight: '16px',
|
|
||||||
color: theme.colors.textHighContrast,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{subtitle}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Glow color={color} direction="reverse" style={{ marginTop: -16 }} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
import { theme } from '../../../stitches.config';
|
|
||||||
|
|
||||||
export enum WN8SurroundingStatAlign {
|
|
||||||
Left,
|
|
||||||
Right,
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface WN8SurroundingStatProps {
|
|
||||||
label: string;
|
|
||||||
value: string | number;
|
|
||||||
align?: WN8SurroundingStatAlign;
|
|
||||||
padded?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function WN8SurroundingStat({
|
|
||||||
label,
|
|
||||||
value,
|
|
||||||
align = WN8SurroundingStatAlign.Left,
|
|
||||||
padded = false,
|
|
||||||
}: WN8SurroundingStatProps) {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
alignItems:
|
|
||||||
align === WN8SurroundingStatAlign.Left ? 'flex-start' : 'flex-end',
|
|
||||||
paddingLeft: padded && align === WN8SurroundingStatAlign.Left ? 32 : 0,
|
|
||||||
paddingRight:
|
|
||||||
padded && align === WN8SurroundingStatAlign.Right ? 32 : 0,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color: theme.colors.textHighContrast,
|
|
||||||
fontSize: 24,
|
|
||||||
fontWeight: 700,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{value}
|
|
||||||
</span>
|
|
||||||
<span style={{ color: theme.colors.textLowContrast, fontSize: 16 }}>
|
|
||||||
{label}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,130 +0,0 @@
|
|||||||
import {
|
|
||||||
getWN8Percentile,
|
|
||||||
Percentile,
|
|
||||||
type SupplementaryStats,
|
|
||||||
} from '@blitzkit/core';
|
|
||||||
import { Locale } from 'discord.js';
|
|
||||||
import { translator } from '../../core/localization/translator';
|
|
||||||
import { PERCENTILE_COLORS } from '../PercentileIndicator/constants';
|
|
||||||
import { HeroStat } from './components/HeroStat';
|
|
||||||
import {
|
|
||||||
WN8SurroundingStat,
|
|
||||||
WN8SurroundingStatAlign,
|
|
||||||
} from './components/WN8SurroundingStat';
|
|
||||||
|
|
||||||
export interface AllStatsOverviewProps {
|
|
||||||
stats: {
|
|
||||||
battles: number;
|
|
||||||
wins: number;
|
|
||||||
damage_dealt: number;
|
|
||||||
damage_received: number;
|
|
||||||
survived_battles: number;
|
|
||||||
hits: number;
|
|
||||||
shots: number;
|
|
||||||
frags: number;
|
|
||||||
};
|
|
||||||
supplementaryStats: SupplementaryStats;
|
|
||||||
locale: Locale;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function AllStatsOverview({
|
|
||||||
stats,
|
|
||||||
locale,
|
|
||||||
supplementaryStats,
|
|
||||||
}: AllStatsOverviewProps) {
|
|
||||||
const { strings } = translator(locale);
|
|
||||||
const percentile =
|
|
||||||
typeof supplementaryStats.WN8 === 'number'
|
|
||||||
? getWN8Percentile(supplementaryStats.WN8)
|
|
||||||
: Percentile.VeryBad;
|
|
||||||
const color = PERCENTILE_COLORS[percentile];
|
|
||||||
|
|
||||||
const heroStat =
|
|
||||||
typeof supplementaryStats.WN8 === 'number'
|
|
||||||
? supplementaryStats.WN8.toFixed(0)
|
|
||||||
: '--';
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
gap: -64,
|
|
||||||
width: '100%',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
gap: 8,
|
|
||||||
alignItems: 'flex-end',
|
|
||||||
flex: 1,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<WN8SurroundingStat
|
|
||||||
label={strings.bot.common.hero_stats.battles}
|
|
||||||
value={stats.battles.toLocaleString()}
|
|
||||||
align={WN8SurroundingStatAlign.Right}
|
|
||||||
/>
|
|
||||||
<WN8SurroundingStat
|
|
||||||
label={strings.bot.common.hero_stats.winrate}
|
|
||||||
value={`${(100 * (stats.wins / stats.battles)).toFixed(2)}%`}
|
|
||||||
align={WN8SurroundingStatAlign.Right}
|
|
||||||
padded
|
|
||||||
/>
|
|
||||||
<WN8SurroundingStat
|
|
||||||
label={strings.bot.common.hero_stats.damage}
|
|
||||||
value={Math.round(
|
|
||||||
stats.damage_dealt / stats.battles,
|
|
||||||
).toLocaleString()}
|
|
||||||
align={WN8SurroundingStatAlign.Right}
|
|
||||||
padded
|
|
||||||
/>
|
|
||||||
<WN8SurroundingStat
|
|
||||||
label={strings.bot.common.hero_stats.damage_ratio}
|
|
||||||
value={(stats.damage_dealt / stats.damage_received).toFixed(2)}
|
|
||||||
align={WN8SurroundingStatAlign.Right}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<HeroStat
|
|
||||||
value={heroStat}
|
|
||||||
subtitle={strings.common.wn8_percentile[percentile]}
|
|
||||||
color={color}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
gap: 8,
|
|
||||||
flex: 1,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<WN8SurroundingStat
|
|
||||||
label={strings.bot.common.hero_stats.tier}
|
|
||||||
value={
|
|
||||||
supplementaryStats.tier ? supplementaryStats.tier.toFixed(2) : '--'
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<WN8SurroundingStat
|
|
||||||
label={strings.bot.common.hero_stats.survival}
|
|
||||||
value={`${(100 * (stats.survived_battles / stats.battles)).toFixed(
|
|
||||||
2,
|
|
||||||
)}%`}
|
|
||||||
padded
|
|
||||||
/>
|
|
||||||
<WN8SurroundingStat
|
|
||||||
label={strings.bot.common.hero_stats.accuracy}
|
|
||||||
value={`${(100 * (stats.hits / stats.shots)).toFixed(2)}%`}
|
|
||||||
padded
|
|
||||||
/>
|
|
||||||
<WN8SurroundingStat
|
|
||||||
label={strings.bot.common.hero_stats.kills}
|
|
||||||
value={(stats.frags / stats.battles).toFixed(2)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import { type ReactNode } from "react";
|
|
||||||
|
|
||||||
interface RootProps {
|
|
||||||
children: ReactNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Root({ children }: RootProps) {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className="session-tracker-root"
|
|
||||||
style={{ display: "flex", flexDirection: "column", gap: 8 }}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
import {
|
|
||||||
Percentile,
|
|
||||||
TankClass,
|
|
||||||
TankType,
|
|
||||||
TREE_TYPE_ICONS,
|
|
||||||
} from '@blitzkit/core';
|
|
||||||
import { createColors } from 'bepaint';
|
|
||||||
import {
|
|
||||||
type AccentColor,
|
|
||||||
type GrayColor,
|
|
||||||
PALETTES,
|
|
||||||
} from '../../../core/radix/radixColors';
|
|
||||||
import { RowStat } from './RowStat';
|
|
||||||
|
|
||||||
export interface RowStatItem {
|
|
||||||
title: string;
|
|
||||||
current?: number | string;
|
|
||||||
career?: number | string;
|
|
||||||
delta?: number;
|
|
||||||
percentile?: Percentile;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface RowProps {
|
|
||||||
displayType?: 'tank' | 'summary';
|
|
||||||
naked?: boolean;
|
|
||||||
title: string;
|
|
||||||
minimized?: boolean;
|
|
||||||
type?: TankType;
|
|
||||||
class?: TankClass;
|
|
||||||
color?: AccentColor | GrayColor;
|
|
||||||
stats: (RowStatItem | undefined)[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Row({
|
|
||||||
color = 'slate',
|
|
||||||
stats,
|
|
||||||
title,
|
|
||||||
minimized,
|
|
||||||
class: tankClass,
|
|
||||||
type,
|
|
||||||
naked = false,
|
|
||||||
displayType,
|
|
||||||
}: RowProps) {
|
|
||||||
const palette = PALETTES[`${color}Dark`];
|
|
||||||
const theme = createColors(palette);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className="session-tracker-row"
|
|
||||||
style={{
|
|
||||||
maxWidth: naked ? 600 : Infinity,
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
borderRadius: 4,
|
|
||||||
backgroundColor: naked
|
|
||||||
? `${theme.appBackground2}c0`
|
|
||||||
: theme.appBackground2,
|
|
||||||
overflow: 'hidden',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
padding: 8,
|
|
||||||
gap: 4,
|
|
||||||
backgroundColor: naked
|
|
||||||
? `${theme.componentInteractive}c0`
|
|
||||||
: theme.componentInteractive,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{displayType === 'tank' && tankClass !== undefined && (
|
|
||||||
<img
|
|
||||||
alt={TankClass[tankClass]}
|
|
||||||
src={TREE_TYPE_ICONS[type ?? TankType.RESEARCHABLE][tankClass]}
|
|
||||||
style={{ width: 16, height: 16 }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color:
|
|
||||||
displayType === 'tank'
|
|
||||||
? type === TankType.COLLECTOR
|
|
||||||
? theme.textLowContrast_blue
|
|
||||||
: type === TankType.PREMIUM
|
|
||||||
? theme.textLowContrast_amber
|
|
||||||
: theme.textHighContrast
|
|
||||||
: theme.textLowContrast,
|
|
||||||
fontWeight: 900,
|
|
||||||
fontSize: 16,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{title}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
paddingTop: 8,
|
|
||||||
paddingBottom: 8,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{stats.map(
|
|
||||||
(row, index) =>
|
|
||||||
row && (
|
|
||||||
<RowStat
|
|
||||||
minimized={minimized}
|
|
||||||
key={index}
|
|
||||||
name={`${row.title} • ${row.career ?? '--'}`}
|
|
||||||
value={row.current ?? '--'}
|
|
||||||
delta={row.delta}
|
|
||||||
percentile={row.percentile}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
import { Percentile } from "@blitzkit/core";
|
|
||||||
import { createColors } from "bepaint";
|
|
||||||
import {
|
|
||||||
type AccentColor,
|
|
||||||
type GrayColor,
|
|
||||||
PALETTES,
|
|
||||||
} from "../../../core/radix/radixColors";
|
|
||||||
import { PercentileIndicator } from "../../PercentileIndicator";
|
|
||||||
|
|
||||||
interface RowStatProps {
|
|
||||||
name: string;
|
|
||||||
value?: string | number;
|
|
||||||
delta?: number;
|
|
||||||
percentile?: Percentile;
|
|
||||||
minimized?: boolean;
|
|
||||||
color?: AccentColor | GrayColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function RowStat({
|
|
||||||
name,
|
|
||||||
value,
|
|
||||||
delta,
|
|
||||||
percentile,
|
|
||||||
minimized = false,
|
|
||||||
color = "slate",
|
|
||||||
}: RowStatProps) {
|
|
||||||
const theme = createColors(PALETTES[`${color}Dark`]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className="session-tracker-row-stat"
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
gap: 4,
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
flex: 1,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
gap: 4,
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{percentile === undefined && delta !== undefined && delta !== 0 && (
|
|
||||||
<img
|
|
||||||
alt={delta > 0 ? "Increase" : "Decrease"}
|
|
||||||
src={
|
|
||||||
(delta ?? 0) > 0
|
|
||||||
? "https://i.imgur.com/qbjiXa1.png"
|
|
||||||
: "https://i.imgur.com/3uyNhun.png"
|
|
||||||
}
|
|
||||||
style={{ width: 12, height: 12 }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{percentile !== undefined && (
|
|
||||||
<PercentileIndicator percentile={percentile} />
|
|
||||||
)}
|
|
||||||
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color: theme.textHighContrast,
|
|
||||||
fontWeight: 700,
|
|
||||||
fontSize: 16,
|
|
||||||
textAlign: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{value}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{!minimized && (
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color: theme.textLowContrast,
|
|
||||||
textAlign: "center",
|
|
||||||
fontSize: 12,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{name}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
export * from './components/Root';
|
|
||||||
export * from './components/Row';
|
|
||||||
export * from './components/RowStat';
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
import { type ReactNode } from "react";
|
|
||||||
import { theme } from "../stitches.config";
|
|
||||||
|
|
||||||
interface CommandWrapperProps {
|
|
||||||
children: ReactNode;
|
|
||||||
fat?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function CommandWrapper({ children, fat }: CommandWrapperProps) {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
padding: `16px ${fat ? 0 : 16}px`,
|
|
||||||
gap: 16,
|
|
||||||
width: "100%",
|
|
||||||
color: theme.colors.textHighContrast,
|
|
||||||
backgroundColor: theme.colors.appBackground1,
|
|
||||||
position: "relative",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
interface DeltaCaretProps {
|
|
||||||
delta: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function DeltaCaret({ delta }: DeltaCaretProps) {
|
|
||||||
return (
|
|
||||||
<img
|
|
||||||
alt={delta > 0 ? 'Increase' : 'Decrease'}
|
|
||||||
style={{
|
|
||||||
width: 16,
|
|
||||||
height: 16,
|
|
||||||
objectFit: 'contain',
|
|
||||||
}}
|
|
||||||
src={
|
|
||||||
delta > 0
|
|
||||||
? 'https://i.imgur.com/gjI4a5f.png'
|
|
||||||
: 'https://i.imgur.com/lLGZygN.png'
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
import { asset } from '@blitzkit/core';
|
|
||||||
|
|
||||||
interface FlagProps {
|
|
||||||
nation: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Flag({ nation }: FlagProps) {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
width: 22,
|
|
||||||
height: 22,
|
|
||||||
overflow: 'hidden',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img alt={nation} src={asset(`flags/circle/${nation}.webp`)} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
import { Percentile } from '@blitzkit/core';
|
|
||||||
import { theme } from '../../../stitches.config';
|
|
||||||
import { PercentileIndicator } from '../../PercentileIndicator';
|
|
||||||
|
|
||||||
interface CardItem {
|
|
||||||
label: string;
|
|
||||||
value: string | number | undefined;
|
|
||||||
percentile?: Percentile;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface CardProps {
|
|
||||||
items: CardItem[];
|
|
||||||
title: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Card({ items, title }: CardProps) {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
gap: 16,
|
|
||||||
flex: 1,
|
|
||||||
borderRadius: 4,
|
|
||||||
backgroundColor: theme.colors.componentInteractive,
|
|
||||||
padding: 8,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color: theme.colors.textHighContrast,
|
|
||||||
fontSize: 24,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{title}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
gap: 8,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{items.map((item) => (
|
|
||||||
<div
|
|
||||||
key={item.label}
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
gap: 8,
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span style={{ fontSize: 16, color: theme.colors.textLowContrast }}>
|
|
||||||
{item.label}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
flex: 1,
|
|
||||||
height: 1,
|
|
||||||
borderRadius: 0.5,
|
|
||||||
backgroundColor: theme.colors.borderNonInteractive,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
gap: 4,
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{item.percentile !== undefined && (
|
|
||||||
<PercentileIndicator percentile={item.percentile} />
|
|
||||||
)}
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
fontSize: 16,
|
|
||||||
color: theme.colors.textHighContrast,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{item.value === undefined || Number.isNaN(item.value)
|
|
||||||
? '--'
|
|
||||||
: item.value}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
interface RootProps {
|
|
||||||
children: React.ReactNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Root({ children }: RootProps) {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
gap: 8,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
interface RowProps {
|
|
||||||
children: React.ReactNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Row({ children }: RowProps) {
|
|
||||||
return <div style={{ display: 'flex', gap: 8 }}>{children}</div>;
|
|
||||||
}
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
import {
|
|
||||||
type BlitzStats,
|
|
||||||
getWN8Percentile,
|
|
||||||
isNumber,
|
|
||||||
type SupplementaryStats,
|
|
||||||
} from '@blitzkit/core';
|
|
||||||
import { Locale } from 'discord.js';
|
|
||||||
import { translator } from '../../core/localization/translator';
|
|
||||||
import { Card } from './components/Card';
|
|
||||||
import { Root } from './components/Root';
|
|
||||||
import { Row } from './components/Row';
|
|
||||||
|
|
||||||
interface GenericAllStatsProps {
|
|
||||||
stats: BlitzStats;
|
|
||||||
supplementaryStats?: SupplementaryStats;
|
|
||||||
locale: Locale;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function GenericAllStats({
|
|
||||||
stats,
|
|
||||||
supplementaryStats,
|
|
||||||
locale,
|
|
||||||
}: GenericAllStatsProps) {
|
|
||||||
const { strings } = translator(locale);
|
|
||||||
const damageRatio = stats.damage_dealt / stats.damage_received;
|
|
||||||
const killsToDeathRatio =
|
|
||||||
stats.frags / (stats.battles - stats.survived_battles);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Root>
|
|
||||||
<Row>
|
|
||||||
<Card
|
|
||||||
title={strings.bot.commands.full_stats.body.cards.games.title}
|
|
||||||
items={[
|
|
||||||
{
|
|
||||||
label: strings.bot.commands.full_stats.body.cards.games.winrate,
|
|
||||||
value: `${(100 * (stats.wins / stats.battles)).toFixed(2)}%`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: strings.bot.commands.full_stats.body.cards.games.battles,
|
|
||||||
value: stats.battles,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label:
|
|
||||||
strings.bot.commands.full_stats.body.cards.games.wins_losses,
|
|
||||||
value: `${stats.wins} / ${stats.losses}`,
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
<Card
|
|
||||||
title={strings.bot.commands.full_stats.body.cards.efficiency.title}
|
|
||||||
items={[
|
|
||||||
{
|
|
||||||
label: strings.bot.commands.full_stats.body.cards.efficiency.wn8,
|
|
||||||
value:
|
|
||||||
supplementaryStats && isNumber(supplementaryStats.WN8)
|
|
||||||
? supplementaryStats.WN8!.toFixed(0)
|
|
||||||
: undefined,
|
|
||||||
percentile: isNumber(supplementaryStats?.WN8)
|
|
||||||
? getWN8Percentile(supplementaryStats!.WN8!)
|
|
||||||
: undefined,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label:
|
|
||||||
strings.bot.commands.full_stats.body.cards.efficiency.survival,
|
|
||||||
value: `${(
|
|
||||||
100 *
|
|
||||||
(stats.survived_battles / stats.battles)
|
|
||||||
).toFixed(2)}%`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label:
|
|
||||||
strings.bot.commands.full_stats.body.cards.efficiency.accuracy,
|
|
||||||
value: `${((stats.hits / stats.shots) * 100).toFixed(2)}%`,
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
</Row>
|
|
||||||
<Row>
|
|
||||||
<Card
|
|
||||||
title={strings.bot.commands.full_stats.body.cards.lethality.title}
|
|
||||||
items={[
|
|
||||||
{
|
|
||||||
label:
|
|
||||||
strings.bot.commands.full_stats.body.cards.lethality
|
|
||||||
.average_damage,
|
|
||||||
value: (stats.damage_dealt / stats.battles).toFixed(0),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label:
|
|
||||||
strings.bot.commands.full_stats.body.cards.lethality
|
|
||||||
.damage_per_tier,
|
|
||||||
value: supplementaryStats?.tier
|
|
||||||
? (
|
|
||||||
stats.damage_dealt /
|
|
||||||
stats.battles /
|
|
||||||
supplementaryStats.tier
|
|
||||||
).toFixed(0)
|
|
||||||
: undefined,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label:
|
|
||||||
strings.bot.commands.full_stats.body.cards.lethality
|
|
||||||
.damage_ratio,
|
|
||||||
value: isFinite(damageRatio) ? damageRatio.toFixed(2) : undefined,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label:
|
|
||||||
strings.bot.commands.full_stats.body.cards.lethality
|
|
||||||
.average_kills,
|
|
||||||
value: (stats.frags / stats.battles).toFixed(0),
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
<Card
|
|
||||||
title={strings.bot.commands.full_stats.body.cards.miscellaneous.title}
|
|
||||||
items={[
|
|
||||||
{
|
|
||||||
label:
|
|
||||||
strings.bot.commands.full_stats.body.cards.miscellaneous
|
|
||||||
.average_tier,
|
|
||||||
value: supplementaryStats?.tier?.toFixed(2),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label:
|
|
||||||
strings.bot.commands.full_stats.body.cards.miscellaneous
|
|
||||||
.average_spots,
|
|
||||||
value: (stats.spotted / stats.battles).toFixed(2),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label:
|
|
||||||
strings.bot.commands.full_stats.body.cards.miscellaneous
|
|
||||||
.average_xp,
|
|
||||||
value: (stats.xp / stats.battles).toFixed(0),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label:
|
|
||||||
strings.bot.commands.full_stats.body.cards.miscellaneous
|
|
||||||
.kills_to_death_ratio,
|
|
||||||
value: isFinite(killsToDeathRatio)
|
|
||||||
? killsToDeathRatio.toFixed(2)
|
|
||||||
: undefined,
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
</Row>
|
|
||||||
</Root>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import { type GenericStat } from "..";
|
|
||||||
import { GenericStatsRow } from "./GenericStatsRow";
|
|
||||||
|
|
||||||
interface GenericStatsColumnProps {
|
|
||||||
stats: GenericStat[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function GenericStatsColumn({ stats }: GenericStatsColumnProps) {
|
|
||||||
return (
|
|
||||||
<div style={{ flex: 1, display: "flex", flexDirection: "column", gap: 8 }}>
|
|
||||||
{stats.map((stat) => (
|
|
||||||
<GenericStatsRow key={stat[0]} stat={stat} />
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
import { type GenericStat } from "..";
|
|
||||||
import { theme } from "../../../stitches.config";
|
|
||||||
import { PercentileIndicator } from "../../PercentileIndicator";
|
|
||||||
|
|
||||||
interface GenericStatsRowProps {
|
|
||||||
stat: GenericStat;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function GenericStatsRow({ stat }: GenericStatsRowProps) {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
alignItems: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color: theme.colors.textLowContrast,
|
|
||||||
fontSize: 16,
|
|
||||||
whiteSpace: "nowrap",
|
|
||||||
maxWidth: 128,
|
|
||||||
overflow: "hidden",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{stat[0]}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color: theme.colors.textHighContrast,
|
|
||||||
fontWeight: 700,
|
|
||||||
fontSize: 16,
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
gap: 4,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{stat[2] !== undefined && <PercentileIndicator percentile={stat[2]} />}
|
|
||||||
{stat[1]}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
import { Percentile } from '@blitzkit/core';
|
|
||||||
import { GenericStatsColumn } from './components/GenericStatsColumn';
|
|
||||||
|
|
||||||
export type GenericStat =
|
|
||||||
| [string, string | number | undefined]
|
|
||||||
| [string, string | number | undefined, Percentile | undefined];
|
|
||||||
|
|
||||||
export interface GenericStatsProps {
|
|
||||||
stats: GenericStat[];
|
|
||||||
columnCount?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function GenericStats({ stats, columnCount = 2 }: GenericStatsProps) {
|
|
||||||
const filteredStats = stats.filter(([, value]) => value !== undefined);
|
|
||||||
const itemsPerRow = Math.ceil(filteredStats.length / columnCount);
|
|
||||||
const columns: GenericStat[][] = [];
|
|
||||||
|
|
||||||
filteredStats.forEach((stat, index) => {
|
|
||||||
const column = Math.floor(index / itemsPerRow);
|
|
||||||
if (!columns[column]) columns[column] = [];
|
|
||||||
columns[column].push(stat);
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div style={{ display: 'flex', gap: 32 }}>
|
|
||||||
{columns.map((stats) => (
|
|
||||||
<GenericStatsColumn
|
|
||||||
key={stats.map((stat) => stat[0]).join('-')}
|
|
||||||
stats={stats}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
export enum LineColor {
|
|
||||||
Red,
|
|
||||||
Green,
|
|
||||||
Blue,
|
|
||||||
White,
|
|
||||||
}
|
|
||||||
export enum LineStyle {
|
|
||||||
Solid,
|
|
||||||
Dashes,
|
|
||||||
DashesAndDots,
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
import { blue, green, red, slateDark } from '@radix-ui/colors';
|
|
||||||
import { GRAPH_HEIGHT, GRAPH_WIDTH } from '../Root/constants';
|
|
||||||
import { LineColor, LineStyle } from './constants';
|
|
||||||
|
|
||||||
const LINE_COLORS = {
|
|
||||||
[LineColor.Red]: red.red9,
|
|
||||||
[LineColor.Green]: green.green9,
|
|
||||||
[LineColor.Blue]: blue.blue9,
|
|
||||||
[LineColor.White]: slateDark.slate11,
|
|
||||||
};
|
|
||||||
|
|
||||||
const LINE_STYLES = {
|
|
||||||
[LineStyle.Solid]: undefined,
|
|
||||||
[LineStyle.Dashes]: '8, 8',
|
|
||||||
[LineStyle.DashesAndDots]: '1, 4, 8, 4',
|
|
||||||
};
|
|
||||||
|
|
||||||
export type PlotItem = [number, number];
|
|
||||||
type Plot = PlotItem[];
|
|
||||||
|
|
||||||
interface LineProps {
|
|
||||||
plot: Plot;
|
|
||||||
minY?: number;
|
|
||||||
maxY?: number;
|
|
||||||
color?: LineColor;
|
|
||||||
style?: LineStyle;
|
|
||||||
lineWidth?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Line({
|
|
||||||
plot,
|
|
||||||
minY: providedMinY,
|
|
||||||
maxY: providedMaxY,
|
|
||||||
color = LineColor.Red,
|
|
||||||
style = LineStyle.Solid,
|
|
||||||
lineWidth = 2,
|
|
||||||
}: LineProps) {
|
|
||||||
const xs = plot.map(([x]) => x);
|
|
||||||
const minX = Math.min(...xs);
|
|
||||||
const maxX = Math.max(...xs);
|
|
||||||
const ys = plot.map(([, y]) => y);
|
|
||||||
const minY = providedMinY ?? Math.min(...ys);
|
|
||||||
const maxY = providedMaxY ?? Math.max(...ys);
|
|
||||||
const rangeX = maxX - minX;
|
|
||||||
const rangeY = maxY - minY;
|
|
||||||
const points = plot
|
|
||||||
.map(
|
|
||||||
([x, y]) =>
|
|
||||||
`${(x - minX) * (GRAPH_WIDTH / rangeX)},${
|
|
||||||
GRAPH_HEIGHT - (y - minY) * (GRAPH_HEIGHT / rangeY)
|
|
||||||
}`,
|
|
||||||
)
|
|
||||||
.join(' ');
|
|
||||||
|
|
||||||
return (
|
|
||||||
<polyline
|
|
||||||
vector-effect="non-scaling-stroke"
|
|
||||||
fill="none"
|
|
||||||
stroke={LINE_COLORS[color]}
|
|
||||||
strokeWidth={lineWidth}
|
|
||||||
stroke-dasharray={LINE_STYLES[style]}
|
|
||||||
points={points}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
export enum MarginOrientation {
|
|
||||||
Vertical,
|
|
||||||
Horizontal,
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
import { times } from 'lodash-es';
|
|
||||||
import { theme } from '../../../../stitches.config';
|
|
||||||
import { type MarginInputProps } from '../Root';
|
|
||||||
import { MarginOrientation } from './constants';
|
|
||||||
|
|
||||||
interface MarginProps extends MarginInputProps {
|
|
||||||
verticalSeparations: number;
|
|
||||||
orientation?: MarginOrientation;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Margin({
|
|
||||||
verticalSeparations,
|
|
||||||
max,
|
|
||||||
min,
|
|
||||||
suffix,
|
|
||||||
precision = 0,
|
|
||||||
orientation = MarginOrientation.Vertical,
|
|
||||||
}: MarginProps) {
|
|
||||||
const isVertical = orientation === MarginOrientation.Vertical;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
paddingLeft: isVertical ? 0 : 64,
|
|
||||||
width: isVertical ? 48 : '100%',
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: isVertical ? 'column' : 'row-reverse',
|
|
||||||
justifyContent: 'space-between',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{times(verticalSeparations, (index) => (
|
|
||||||
<span
|
|
||||||
key={index}
|
|
||||||
style={{
|
|
||||||
fontSize: 16,
|
|
||||||
color: theme.colors.textHighContrast,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{`${(
|
|
||||||
(max - min) *
|
|
||||||
((verticalSeparations - (index + 1)) /
|
|
||||||
(verticalSeparations - 1)) +
|
|
||||||
min
|
|
||||||
).toFixed(precision)}${suffix ?? ''}`}
|
|
||||||
</span>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
export const GRAPH_WIDTH = 384;
|
|
||||||
export const GRAPH_HEIGHT = 320;
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
import { times } from "lodash-es";
|
|
||||||
import { type ReactNode } from "react";
|
|
||||||
import { theme } from "../../../../stitches.config";
|
|
||||||
import { Margin } from "../Margin";
|
|
||||||
import { MarginOrientation } from "../Margin/constants";
|
|
||||||
import { GRAPH_HEIGHT, GRAPH_WIDTH } from "./constants";
|
|
||||||
|
|
||||||
export interface MarginInputProps {
|
|
||||||
min: number;
|
|
||||||
max: number;
|
|
||||||
suffix?: string;
|
|
||||||
precision?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface RootProps {
|
|
||||||
children: ReactNode;
|
|
||||||
verticalMargin?: MarginInputProps;
|
|
||||||
horizontalMargin?: MarginInputProps;
|
|
||||||
separations?: number;
|
|
||||||
xMinLabel: string;
|
|
||||||
xMaxLabel: string;
|
|
||||||
xTitle?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Root({
|
|
||||||
children,
|
|
||||||
verticalMargin,
|
|
||||||
horizontalMargin,
|
|
||||||
separations = 5,
|
|
||||||
xMinLabel,
|
|
||||||
xMaxLabel,
|
|
||||||
xTitle,
|
|
||||||
}: RootProps) {
|
|
||||||
return (
|
|
||||||
<div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
paddingLeft: 64,
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span style={{ fontSize: 16, color: theme.colors.textHighContrast }}>
|
|
||||||
{xMinLabel}
|
|
||||||
</span>
|
|
||||||
<span style={{ fontSize: 16, color: theme.colors.textHighContrast }}>
|
|
||||||
{xMaxLabel}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style={{ display: "flex", gap: 16 }}>
|
|
||||||
{verticalMargin && (
|
|
||||||
<Margin {...verticalMargin} verticalSeparations={separations} />
|
|
||||||
)}
|
|
||||||
|
|
||||||
<svg
|
|
||||||
viewBox={`0 0 ${GRAPH_WIDTH} ${GRAPH_HEIGHT}`}
|
|
||||||
preserveAspectRatio="none"
|
|
||||||
style={{
|
|
||||||
flex: 1,
|
|
||||||
backgroundColor: theme.colors.appBackground2,
|
|
||||||
borderRadius: 4,
|
|
||||||
border: theme.borderStyles.nonInteractive,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{times(separations - 2, (index) => {
|
|
||||||
const y = GRAPH_HEIGHT * ((index + 1) / (separations - 1));
|
|
||||||
|
|
||||||
return (
|
|
||||||
<polyline
|
|
||||||
key={index}
|
|
||||||
vector-effect="non-scaling-stroke"
|
|
||||||
fill="none"
|
|
||||||
stroke={theme.colors.borderNonInteractive}
|
|
||||||
strokeWidth="2"
|
|
||||||
points={`0,${y}, ${GRAPH_WIDTH},${y}`}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
|
|
||||||
{children}
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{horizontalMargin && (
|
|
||||||
<Margin
|
|
||||||
{...horizontalMargin}
|
|
||||||
verticalSeparations={separations}
|
|
||||||
orientation={MarginOrientation.Horizontal}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{xTitle !== undefined && (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
paddingLeft: 64,
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span style={{ fontSize: 16, color: theme.colors.textLowContrast }}>
|
|
||||||
{xTitle}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
export * from './components/Line';
|
|
||||||
export * from './components/Margin';
|
|
||||||
export * from './components/Root';
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
import { theme } from '../../../stitches.config';
|
|
||||||
|
|
||||||
interface GapProps {
|
|
||||||
message: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Gap({ message: number }: GapProps) {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
padding: 8,
|
|
||||||
backgroundColor: theme.colors.componentNonInteractive,
|
|
||||||
borderRadius: 4,
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color: theme.colors.textLowContrast,
|
|
||||||
fontSize: 16,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{number.toLocaleString()}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,171 +0,0 @@
|
|||||||
import { type ComponentProps } from "react";
|
|
||||||
import { theme } from "../../../stitches.config";
|
|
||||||
|
|
||||||
interface ItemProps extends ComponentProps<"div"> {
|
|
||||||
position: number;
|
|
||||||
deltaPosition?: number;
|
|
||||||
score?: number;
|
|
||||||
deltaScore?: number;
|
|
||||||
nickname: string;
|
|
||||||
clan?: string;
|
|
||||||
highlight?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Item({
|
|
||||||
position,
|
|
||||||
deltaPosition,
|
|
||||||
score,
|
|
||||||
deltaScore,
|
|
||||||
nickname,
|
|
||||||
clan,
|
|
||||||
highlight,
|
|
||||||
...props
|
|
||||||
}: ItemProps) {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
{...props}
|
|
||||||
style={{
|
|
||||||
cursor: "pointer",
|
|
||||||
display: "flex",
|
|
||||||
padding: 8,
|
|
||||||
backgroundColor: highlight
|
|
||||||
? theme.colors.componentInteractive_blue
|
|
||||||
: theme.colors.componentInteractive,
|
|
||||||
borderRadius: 4,
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
gap: 8,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color: highlight
|
|
||||||
? theme.colors.textLowContrast_blue
|
|
||||||
: theme.colors.textLowContrast,
|
|
||||||
fontSize: 16,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{position.toLocaleString()}.
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
gap: 4,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color: highlight
|
|
||||||
? theme.colors.textHighContrast_blue
|
|
||||||
: theme.colors.textHighContrast,
|
|
||||||
fontSize: 16,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{nickname}
|
|
||||||
</span>
|
|
||||||
{clan && (
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color: highlight
|
|
||||||
? theme.colors.textLowContrast_blue
|
|
||||||
: theme.colors.textLowContrast,
|
|
||||||
fontSize: 16,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
[{clan}]
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{deltaPosition !== undefined && deltaPosition !== 0 && (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
gap: 4,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
alt={deltaPosition > 0 ? "Increase" : "Decrease"}
|
|
||||||
style={{
|
|
||||||
width: 8,
|
|
||||||
height: 8,
|
|
||||||
}}
|
|
||||||
src={
|
|
||||||
deltaPosition > 0
|
|
||||||
? "https://i.imgur.com/qbjiXa1.png"
|
|
||||||
: "https://i.imgur.com/3uyNhun.png"
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color: highlight
|
|
||||||
? theme.colors.textLowContrast_blue
|
|
||||||
: theme.colors.textLowContrast,
|
|
||||||
fontSize: 16,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{Math.abs(deltaPosition).toLocaleString()}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* TODO: lol remove this spacer div for a better solution */}
|
|
||||||
<div style={{ flex: 1 }} />
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
gap: 4,
|
|
||||||
alignItems: "center",
|
|
||||||
width: 96,
|
|
||||||
justifyContent: "flex-end",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{deltaScore !== 0 && deltaScore !== undefined && (
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color: highlight
|
|
||||||
? theme.colors.textLowContrast_blue
|
|
||||||
: theme.colors.textLowContrast,
|
|
||||||
fontSize: 16,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{Math.abs(deltaScore).toLocaleString()}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
{deltaScore !== 0 && deltaScore !== undefined && (
|
|
||||||
<img
|
|
||||||
alt={deltaScore > 0 ? "Increase" : "Decrease"}
|
|
||||||
style={{
|
|
||||||
width: 8,
|
|
||||||
height: 8,
|
|
||||||
}}
|
|
||||||
src={
|
|
||||||
deltaScore > 0
|
|
||||||
? "https://i.imgur.com/qbjiXa1.png"
|
|
||||||
: "https://i.imgur.com/3uyNhun.png"
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{score !== undefined && (
|
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color: highlight
|
|
||||||
? theme.colors.textHighContrast_blue
|
|
||||||
: theme.colors.textHighContrast,
|
|
||||||
fontSize: 16,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{score.toLocaleString()}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import { type ReactNode } from 'react';
|
|
||||||
|
|
||||||
interface RootProps {
|
|
||||||
children: ReactNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Root({ children }: RootProps) {
|
|
||||||
return (
|
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
export * from './components/Gap';
|
|
||||||
export * from './components/Item';
|
|
||||||
export * from './components/Root';
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
export enum NoDataType {
|
|
||||||
BattlesInPeriod,
|
|
||||||
PlayersInPeriod,
|
|
||||||
TanksFound,
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
import { Locale } from 'discord.js';
|
|
||||||
import { translator } from '../../core/localization/translator';
|
|
||||||
import { theme } from '../../stitches.config';
|
|
||||||
|
|
||||||
interface NoDataProps {
|
|
||||||
type:
|
|
||||||
| 'battles_in_period'
|
|
||||||
| 'players_in_period'
|
|
||||||
| 'tanks_found'
|
|
||||||
| 'battles_in_season';
|
|
||||||
locale: Locale;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function NoData({ type, locale }: NoDataProps) {
|
|
||||||
const { strings } = translator(locale);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span style={{ fontSize: 16, color: theme.colors.textLowContrast }}>
|
|
||||||
{strings.bot.common.no_data[type]}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Loaded 100 of 628 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user