Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ee371998a
|
||
|
|
5733c21fbb
|
||
|
|
61b9d07fc6
|
||
|
|
59cd625238
|
||
|
|
6bf2733cec
|
||
|
|
60f9f95be4
|
||
|
|
ea1c05d2d9
|
||
|
|
49c03e82b1
|
||
|
|
0c52169533
|
||
|
|
bf6da20fd8
|
||
|
|
c1f87580c7
|
||
|
|
dd7d2b96e3
|
||
|
|
874f0627f7
|
||
|
|
e8dec1a1b2
|
||
|
|
e1f0ce1290
|
||
|
|
bc5ea81170
|
||
|
|
71b998f4bc
|
||
|
|
cbac50753f
|
||
|
|
fb65348ba3
|
||
|
|
f23d1025d2
|
||
|
|
a8573c4b6a
|
||
|
|
4054fdd06b
|
||
|
|
0b4e639630
|
||
|
|
c65fb5e1a5
|
||
|
|
6486498c74
|
||
|
|
cf72d143f3
|
||
|
|
ee7c50c6f5
|
||
|
|
f7317c8232
|
||
|
|
9856cf2426
|
||
|
|
f46d9c67b8
|
||
|
|
132616dc29
|
||
|
|
8b22fdb648
|
||
|
|
dc55c7549d
|
||
|
|
9d9c6147c5
|
||
|
|
48c8365b7c
|
||
|
|
8884d08c7c
|
||
|
|
b516a9cc43
|
||
|
|
6b7b2b198a
|
||
|
|
fbf87dceba
|
||
|
|
9ae28690a7
|
||
|
|
f83cc118fe
|
||
|
|
19788a8a3c
|
||
|
|
e066dd0681
|
||
|
|
29b3c3c58b
|
||
|
|
a8390216d0
|
||
|
|
513f1a0c16
|
||
|
|
e7e624f042
|
||
|
|
654405e016
|
||
|
|
c461a0a459
|
||
|
|
16ce04ba7a
|
||
|
|
1700d127c3
|
||
|
|
7c47b32c68
|
||
|
|
56781b5d1a
|
||
|
|
6ce7c2a8ae
|
||
|
|
15dd9ad013
|
||
|
|
217222a22b
|
||
|
|
39da88a856
|
||
|
|
29c90d2f06
|
||
|
|
467dd1b0a1
|
||
|
|
a1a69c9ac5
|
||
|
|
0163e09b02
|
||
|
|
fbb4b15971
|
||
|
|
77933a2298
|
||
|
|
7209a36752
|
||
|
|
f00b78996a
|
||
|
|
38779c1715
|
||
|
|
fa67d26fe9
|
||
|
|
81d47ea71d
|
||
|
|
70433b76ab
|
||
|
|
105913503c
|
||
|
|
2ad54f976b
|
||
|
|
d8d59febbb
|
||
|
|
a618c76292
|
||
|
|
118fad49d8
|
||
|
|
62c0f84d14
|
||
|
|
4a96911885
|
||
|
|
51cd3c3620
|
||
|
|
dfbfac33d3
|
||
|
|
03ec5a220a
|
||
|
|
abebc0bb08
|
||
|
|
3c7487f20f
|
||
|
|
97231c6b38
|
||
|
|
a93e4ab521
|
||
|
|
e7c48b182f
|
||
|
|
16dd3fd613
|
||
|
|
c91303d194
|
||
|
|
a76e81789b
|
||
|
|
c909973aab
|
||
|
|
28f694e4e7
|
||
|
|
508e4d1640
|
||
|
|
41a66eaf86
|
||
|
|
ac4b76fa46
|
||
|
|
2e02275c29
|
||
|
|
dbaac6a6a6
|
||
|
|
68525f161e
|
||
|
|
d386454e91
|
||
|
|
6e05aac871
|
||
|
|
fbe3feec9d
|
||
|
|
1c540ad35b
|
||
|
|
4ec597967a
|
||
|
|
be4b8fc3ee
|
||
|
|
d9fa967ade
|
||
|
|
0f4ee9f78c
|
||
|
|
cc5d814740
|
||
|
|
53ecbbd07f
|
||
|
|
d0810ae80e
|
||
|
|
d688e5181f
|
||
|
|
1d7f888563
|
||
|
|
482708038e
|
||
|
|
ce3830ba2e
|
||
|
|
0acf23b2f6
|
||
|
|
31adc14156
|
||
|
|
bd9209359e
|
||
|
|
803cfb8742
|
||
|
|
f3fdf76817
|
||
|
|
2777e6dac0
|
||
|
|
a551d5fb52
|
||
|
|
08915ad2ae
|
||
|
|
1dd75f8ccf
|
||
|
|
3dc24ab3d7
|
||
|
|
a3e9067ba0
|
||
|
|
a0a763ae57
|
||
|
|
c56a903d55
|
||
|
|
c07828f244
|
||
|
|
cf4f1c15ea
|
||
|
|
76797c6120
|
||
|
|
36ed3e0095
|
||
|
|
e0ba25da77
|
||
|
|
e89b0fac8a
|
||
|
|
fa256dd004
|
||
|
|
b5c6598722
|
||
|
|
db111aaa2e
|
||
|
|
c1ac567204
|
||
|
|
1e11525c8e
|
||
|
|
b46c52e042
|
||
|
|
848511769e
|
||
|
|
376078d7f4
|
||
|
|
cb630a9d57
|
||
|
|
6ec7e8df82
|
||
|
|
1e93ef4d07
|
||
|
|
af4d634ed9
|
||
|
|
caf8d7fc7e
|
||
|
|
319d736274
|
||
|
|
426d507ec2
|
||
|
|
e5d9226233
|
||
|
|
bc1ca2a2b1
|
||
|
|
2e1cd07b99
|
||
|
|
370fa2b85d
|
||
|
|
7dedd4f91d
|
||
|
|
663b75e5ee
|
||
|
|
19c1d0b214
|
||
|
|
cc79eb6d4a
|
||
|
|
50d64b2905
|
||
|
|
cb10fbd991
|
||
|
|
ad6efdbbbe
|
||
|
|
2e71aea355
|
||
|
|
d2eb41f564
|
||
|
|
4fc8517123
|
||
|
|
34971787d0
|
||
|
|
9753483409
|
||
|
|
efad434211
|
||
|
|
0122652c25
|
||
|
|
f0d635ebe6
|
||
|
|
847c8d2a3e
|
||
|
|
f30e2d0ca5
|
||
|
|
3b7a9b2d66
|
||
|
|
3d848ce380
|
||
|
|
0b2e26470d
|
||
|
|
129259cb74
|
||
|
|
1dfeb0be93
|
||
|
|
6677e22ab6
|
||
|
|
8c00a3e553
|
||
|
|
818c2ddc20
|
||
|
|
a971616858
|
||
|
|
242a130957
|
||
|
|
9f4f3a8556
|
||
|
|
59c308e7dd
|
||
|
|
ceb1a5ee47
|
||
|
|
7d5a3177e4
|
||
|
|
6005fa9348
|
||
|
|
6734b47d71
|
||
|
|
fdcaf6a137
|
||
|
|
a3aa1915d4
|
||
|
|
2d764448af
|
||
|
|
3c05196dda
|
No files matched your search
@@ -0,0 +1 @@
|
|||||||
|
NEXT_PUBLIC_PUBLIC_SIGNING_KEY=LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUNvd0JRWURLMlZ3QXlFQVJiK1N5c0VQemRYaGN4OWtyMy9rY3NNNURheDZRS1Q0VXZ3bW9PbWd2UHc9Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo=
|
||||||
@@ -30,9 +30,6 @@ yarn-debug.log*
|
|||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
.pnpm-debug.log*
|
.pnpm-debug.log*
|
||||||
|
|
||||||
# env files (can opt-in for committing if needed)
|
|
||||||
.env*
|
|
||||||
|
|
||||||
# vercel
|
# vercel
|
||||||
.vercel
|
.vercel
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
# Berry Dash Launcher
|
|
||||||
|
|
||||||
The version launcher for Berry Dash users
|
|
||||||
@@ -1,37 +1,40 @@
|
|||||||
{
|
{
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
|
"configVersion": 1,
|
||||||
"workspaces": {
|
"workspaces": {
|
||||||
"": {
|
"": {
|
||||||
"name": "lncvrt-games-launcher",
|
"name": "lncvrt-games-launcher",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-svg-core": "7.1.0",
|
"@fortawesome/fontawesome-svg-core": "7.2.0",
|
||||||
"@fortawesome/free-brands-svg-icons": "7.1.0",
|
"@fortawesome/free-brands-svg-icons": "7.2.0",
|
||||||
"@fortawesome/free-solid-svg-icons": "7.1.0",
|
"@fortawesome/free-solid-svg-icons": "7.2.0",
|
||||||
"@fortawesome/react-fontawesome": "3.1.0",
|
"@fortawesome/react-fontawesome": "3.3.0",
|
||||||
"@tauri-apps/api": "2.9.0",
|
"@tauri-apps/api": "2.10.1",
|
||||||
"@tauri-apps/plugin-dialog": "2.4.2",
|
"@tauri-apps/plugin-clipboard-manager": "2.3.2",
|
||||||
"@tauri-apps/plugin-fs": "2.4.4",
|
"@tauri-apps/plugin-dialog": "2.6.0",
|
||||||
|
"@tauri-apps/plugin-fs": "2.4.5",
|
||||||
|
"@tauri-apps/plugin-http": "2.5.7",
|
||||||
"@tauri-apps/plugin-notification": "2.3.3",
|
"@tauri-apps/plugin-notification": "2.3.3",
|
||||||
"@tauri-apps/plugin-opener": "2.5.2",
|
"@tauri-apps/plugin-opener": "2.5.3",
|
||||||
"@tauri-apps/plugin-os": "2.3.2",
|
"@tauri-apps/plugin-os": "2.3.2",
|
||||||
"axios": "1.13.1",
|
"@tauri-apps/plugin-window-state": "2.4.1",
|
||||||
"date-fns": "4.1.0",
|
"next": "16.2.1",
|
||||||
"next": "16.0.1",
|
"pretty-bytes": "7.1.0",
|
||||||
"react": "19.2.0",
|
"react": "19.2.4",
|
||||||
"react-dom": "19.2.0",
|
"react-dom": "19.2.4",
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/eslintrc": "3.3.1",
|
"@eslint/eslintrc": "3.3.5",
|
||||||
"@tailwindcss/postcss": "4.1.16",
|
"@tailwindcss/postcss": "4.2.2",
|
||||||
"@tauri-apps/cli": "2.9.2",
|
"@tauri-apps/cli": "2.10.1",
|
||||||
"@types/crypto-js": "4.2.2",
|
"@types/crypto-js": "4.2.2",
|
||||||
"@types/node": "24.9.2",
|
"@types/node": "25.5.0",
|
||||||
"@types/react": "19.2.2",
|
"@types/react": "19.2.14",
|
||||||
"@types/react-dom": "19.2.2",
|
"@types/react-dom": "19.2.3",
|
||||||
"crypto-js": "4.2.0",
|
"crypto-js": "4.2.0",
|
||||||
"eslint": "9.39.0",
|
"eslint": "9.39.4",
|
||||||
"eslint-config-next": "16.0.1",
|
"eslint-config-next": "16.2.1",
|
||||||
"tailwindcss": "4.1.16",
|
"tailwindcss": "4.2.2",
|
||||||
"typescript": "5.9.3",
|
"typescript": "5.9.3",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -39,21 +42,21 @@
|
|||||||
"packages": {
|
"packages": {
|
||||||
"@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="],
|
"@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="],
|
||||||
|
|
||||||
"@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
|
"@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="],
|
||||||
|
|
||||||
"@babel/compat-data": ["@babel/compat-data@7.28.5", "", {}, "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA=="],
|
"@babel/compat-data": ["@babel/compat-data@7.29.0", "", {}, "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg=="],
|
||||||
|
|
||||||
"@babel/core": ["@babel/core@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.28.3", "@babel/helpers": "^7.28.4", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw=="],
|
"@babel/core": ["@babel/core@7.29.0", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-module-transforms": "^7.28.6", "@babel/helpers": "^7.28.6", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/traverse": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA=="],
|
||||||
|
|
||||||
"@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="],
|
"@babel/generator": ["@babel/generator@7.29.1", "", { "dependencies": { "@babel/parser": "^7.29.0", "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw=="],
|
||||||
|
|
||||||
"@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.27.2", "", { "dependencies": { "@babel/compat-data": "^7.27.2", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ=="],
|
"@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.28.6", "", { "dependencies": { "@babel/compat-data": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA=="],
|
||||||
|
|
||||||
"@babel/helper-globals": ["@babel/helper-globals@7.28.0", "", {}, "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw=="],
|
"@babel/helper-globals": ["@babel/helper-globals@7.28.0", "", {}, "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw=="],
|
||||||
|
|
||||||
"@babel/helper-module-imports": ["@babel/helper-module-imports@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w=="],
|
"@babel/helper-module-imports": ["@babel/helper-module-imports@7.28.6", "", { "dependencies": { "@babel/traverse": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw=="],
|
||||||
|
|
||||||
"@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.3", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw=="],
|
"@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.6", "", { "dependencies": { "@babel/helper-module-imports": "^7.28.6", "@babel/helper-validator-identifier": "^7.28.5", "@babel/traverse": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA=="],
|
||||||
|
|
||||||
"@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="],
|
"@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="],
|
||||||
|
|
||||||
@@ -61,49 +64,49 @@
|
|||||||
|
|
||||||
"@babel/helper-validator-option": ["@babel/helper-validator-option@7.27.1", "", {}, "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg=="],
|
"@babel/helper-validator-option": ["@babel/helper-validator-option@7.27.1", "", {}, "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg=="],
|
||||||
|
|
||||||
"@babel/helpers": ["@babel/helpers@7.28.4", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/types": "^7.28.4" } }, "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w=="],
|
"@babel/helpers": ["@babel/helpers@7.29.2", "", { "dependencies": { "@babel/template": "^7.28.6", "@babel/types": "^7.29.0" } }, "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw=="],
|
||||||
|
|
||||||
"@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": "./bin/babel-parser.js" }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="],
|
"@babel/parser": ["@babel/parser@7.29.2", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA=="],
|
||||||
|
|
||||||
"@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
|
"@babel/template": ["@babel/template@7.28.6", "", { "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/parser": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ=="],
|
||||||
|
|
||||||
"@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="],
|
"@babel/traverse": ["@babel/traverse@7.29.0", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/types": "^7.29.0", "debug": "^4.3.1" } }, "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA=="],
|
||||||
|
|
||||||
"@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="],
|
"@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="],
|
||||||
|
|
||||||
"@emnapi/core": ["@emnapi/core@1.6.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" } }, "sha512-zq/ay+9fNIJJtJiZxdTnXS20PllcYMX3OE23ESc4HK/bdYu3cOWYVhsOhVnXALfU/uqJIxn5NBPd9z4v+SfoSg=="],
|
"@emnapi/core": ["@emnapi/core@1.9.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.0", "tslib": "^2.4.0" } }, "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA=="],
|
||||||
|
|
||||||
"@emnapi/runtime": ["@emnapi/runtime@1.6.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-obtUmAHTMjll499P+D9A3axeJFlhdjOWdKUNs/U6QIGT7V5RjcUW1xToAzjvmgTSQhDbYn/NwfTRoJcQ2rNBxA=="],
|
"@emnapi/runtime": ["@emnapi/runtime@1.9.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA=="],
|
||||||
|
|
||||||
"@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="],
|
"@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg=="],
|
||||||
|
|
||||||
"@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g=="],
|
"@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ=="],
|
||||||
|
|
||||||
"@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.2", "", {}, "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew=="],
|
"@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.2", "", {}, "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew=="],
|
||||||
|
|
||||||
"@eslint/config-array": ["@eslint/config-array@0.21.1", "", { "dependencies": { "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA=="],
|
"@eslint/config-array": ["@eslint/config-array@0.21.2", "", { "dependencies": { "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", "minimatch": "^3.1.5" } }, "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw=="],
|
||||||
|
|
||||||
"@eslint/config-helpers": ["@eslint/config-helpers@0.4.2", "", { "dependencies": { "@eslint/core": "^0.17.0" } }, "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw=="],
|
"@eslint/config-helpers": ["@eslint/config-helpers@0.4.2", "", { "dependencies": { "@eslint/core": "^0.17.0" } }, "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw=="],
|
||||||
|
|
||||||
"@eslint/core": ["@eslint/core@0.17.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ=="],
|
"@eslint/core": ["@eslint/core@0.17.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ=="],
|
||||||
|
|
||||||
"@eslint/eslintrc": ["@eslint/eslintrc@3.3.1", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ=="],
|
"@eslint/eslintrc": ["@eslint/eslintrc@3.3.5", "", { "dependencies": { "ajv": "^6.14.0", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.1", "minimatch": "^3.1.5", "strip-json-comments": "^3.1.1" } }, "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg=="],
|
||||||
|
|
||||||
"@eslint/js": ["@eslint/js@9.39.0", "", {}, "sha512-BIhe0sW91JGPiaF1mOuPy5v8NflqfjIcDNpC+LbW9f609WVRX1rArrhi6Z2ymvrAry9jw+5POTj4t2t62o8Bmw=="],
|
"@eslint/js": ["@eslint/js@9.39.4", "", {}, "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw=="],
|
||||||
|
|
||||||
"@eslint/object-schema": ["@eslint/object-schema@2.1.7", "", {}, "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA=="],
|
"@eslint/object-schema": ["@eslint/object-schema@2.1.7", "", {}, "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA=="],
|
||||||
|
|
||||||
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.4.1", "", { "dependencies": { "@eslint/core": "^0.17.0", "levn": "^0.4.1" } }, "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA=="],
|
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.4.1", "", { "dependencies": { "@eslint/core": "^0.17.0", "levn": "^0.4.1" } }, "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA=="],
|
||||||
|
|
||||||
"@fortawesome/fontawesome-common-types": ["@fortawesome/fontawesome-common-types@7.1.0", "", {}, "sha512-l/BQM7fYntsCI//du+6sEnHOP6a74UixFyOYUyz2DLMXKx+6DEhfR3F2NYGE45XH1JJuIamacb4IZs9S0ZOWLA=="],
|
"@fortawesome/fontawesome-common-types": ["@fortawesome/fontawesome-common-types@7.2.0", "", {}, "sha512-IpR0bER9FY25p+e7BmFH25MZKEwFHTfRAfhOyJubgiDnoJNsSvJ7nigLraHtp4VOG/cy8D7uiV0dLkHOne5Fhw=="],
|
||||||
|
|
||||||
"@fortawesome/fontawesome-svg-core": ["@fortawesome/fontawesome-svg-core@7.1.0", "", { "dependencies": { "@fortawesome/fontawesome-common-types": "7.1.0" } }, "sha512-fNxRUk1KhjSbnbuBxlWSnBLKLBNun52ZBTcs22H/xEEzM6Ap81ZFTQ4bZBxVQGQgVY0xugKGoRcCbaKjLQ3XZA=="],
|
"@fortawesome/fontawesome-svg-core": ["@fortawesome/fontawesome-svg-core@7.2.0", "", { "dependencies": { "@fortawesome/fontawesome-common-types": "7.2.0" } }, "sha512-6639htZMjEkwskf3J+e6/iar+4cTNM9qhoWuRfj9F3eJD6r7iCzV1SWnQr2Mdv0QT0suuqU8BoJCZUyCtP9R4Q=="],
|
||||||
|
|
||||||
"@fortawesome/free-brands-svg-icons": ["@fortawesome/free-brands-svg-icons@7.1.0", "", { "dependencies": { "@fortawesome/fontawesome-common-types": "7.1.0" } }, "sha512-9byUd9bgNfthsZAjBl6GxOu1VPHgBuRUP9juI7ZoM98h8xNPTCTagfwUFyYscdZq4Hr7gD1azMfM9s5tIWKZZA=="],
|
"@fortawesome/free-brands-svg-icons": ["@fortawesome/free-brands-svg-icons@7.2.0", "", { "dependencies": { "@fortawesome/fontawesome-common-types": "7.2.0" } }, "sha512-VNG8xqOip1JuJcC3zsVsKRQ60oXG9+oYNDCosjoU/H9pgYmLTEwWw8pE0jhPz/JWdHeUuK6+NQ3qsM4gIbdbYQ=="],
|
||||||
|
|
||||||
"@fortawesome/free-solid-svg-icons": ["@fortawesome/free-solid-svg-icons@7.1.0", "", { "dependencies": { "@fortawesome/fontawesome-common-types": "7.1.0" } }, "sha512-Udu3K7SzAo9N013qt7qmm22/wo2hADdheXtBfxFTecp+ogsc0caQNRKEb7pkvvagUGOpG9wJC1ViH6WXs8oXIA=="],
|
"@fortawesome/free-solid-svg-icons": ["@fortawesome/free-solid-svg-icons@7.2.0", "", { "dependencies": { "@fortawesome/fontawesome-common-types": "7.2.0" } }, "sha512-YTVITFGN0/24PxzXrwqCgnyd7njDuzp5ZvaCx5nq/jg55kUYd94Nj8UTchBdBofi/L0nwRfjGOg0E41d2u9T1w=="],
|
||||||
|
|
||||||
"@fortawesome/react-fontawesome": ["@fortawesome/react-fontawesome@3.1.0", "", { "peerDependencies": { "@fortawesome/fontawesome-svg-core": "~6 || ~7", "react": "^18.0.0 || ^19.0.0" } }, "sha512-5OUQH9aDH/xHJwnpD4J7oEdGvFGJgYnGe0UebaPIdMW9UxYC/f5jv2VjVEgnikdJN0HL8yQxp9Nq+7gqGZpIIA=="],
|
"@fortawesome/react-fontawesome": ["@fortawesome/react-fontawesome@3.3.0", "", { "peerDependencies": { "@fortawesome/fontawesome-svg-core": "~6 || ~7", "react": "^18.0.0 || ^19.0.0" } }, "sha512-EHmHeTf8WgO29sdY3iX/7ekE3gNUdlc2RW6mm/FzELlHFKfTrA9S4MlyquRR+RRCRCn8+jXfLFpLGB2l7wCWyw=="],
|
||||||
|
|
||||||
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
|
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
|
||||||
|
|
||||||
@@ -113,51 +116,55 @@
|
|||||||
|
|
||||||
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="],
|
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="],
|
||||||
|
|
||||||
"@img/colour": ["@img/colour@1.0.0", "", {}, "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw=="],
|
"@img/colour": ["@img/colour@1.1.0", "", {}, "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ=="],
|
||||||
|
|
||||||
"@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.3" }, "os": "darwin", "cpu": "arm64" }, "sha512-sitdlPzDVyvmINUdJle3TNHl+AG9QcwiAMsXmccqsCOMZNIdW2/7S26w0LyU8euiLVzFBL3dXPwVCq/ODnf2vA=="],
|
"@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w=="],
|
||||||
|
|
||||||
"@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.3" }, "os": "darwin", "cpu": "x64" }, "sha512-rZheupWIoa3+SOdF/IcUe1ah4ZDpKBGWcsPX6MT0lYniH9micvIU7HQkYTfrx5Xi8u+YqwLtxC/3vl8TQN6rMg=="],
|
"@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.4" }, "os": "darwin", "cpu": "x64" }, "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw=="],
|
||||||
|
|
||||||
"@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-QzWAKo7kpHxbuHqUC28DZ9pIKpSi2ts2OJnoIGI26+HMgq92ZZ4vk8iJd4XsxN+tYfNJxzH6W62X5eTcsBymHw=="],
|
"@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g=="],
|
||||||
|
|
||||||
"@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-Ju+g2xn1E2AKO6YBhxjj+ACcsPQRHT0bhpglxcEf+3uyPY+/gL8veniKoo96335ZaPo03bdDXMv0t+BBFAbmRA=="],
|
"@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg=="],
|
||||||
|
|
||||||
"@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.3", "", { "os": "linux", "cpu": "arm" }, "sha512-x1uE93lyP6wEwGvgAIV0gP6zmaL/a0tGzJs/BIDDG0zeBhMnuUPm7ptxGhUbcGs4okDJrk4nxgrmxpib9g6HpA=="],
|
"@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.4", "", { "os": "linux", "cpu": "arm" }, "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A=="],
|
||||||
|
|
||||||
"@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-I4RxkXU90cpufazhGPyVujYwfIm9Nk1QDEmiIsaPwdnm013F7RIceaCc87kAH+oUB1ezqEvC6ga4m7MSlqsJvQ=="],
|
"@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw=="],
|
||||||
|
|
||||||
"@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-Y2T7IsQvJLMCBM+pmPbM3bKT/yYJvVtLJGfCs4Sp95SjvnFIjynbjzsa7dY1fRJX45FTSfDksbTp6AGWudiyCg=="],
|
"@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA=="],
|
||||||
|
|
||||||
"@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-RgWrs/gVU7f+K7P+KeHFaBAJlNkD1nIZuVXdQv6S+fNA6syCcoboNjsV2Pou7zNlVdNQoQUpQTk8SWDHUA3y/w=="],
|
"@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.2.4", "", { "os": "linux", "cpu": "none" }, "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA=="],
|
||||||
|
|
||||||
"@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.3", "", { "os": "linux", "cpu": "x64" }, "sha512-3JU7LmR85K6bBiRzSUc/Ff9JBVIFVvq6bomKE0e63UXGeRw2HPVEjoJke1Yx+iU4rL7/7kUjES4dZ/81Qjhyxg=="],
|
"@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ=="],
|
||||||
|
|
||||||
"@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-F9q83RZ8yaCwENw1GieztSfj5msz7GGykG/BA+MOUefvER69K/ubgFHNeSyUu64amHIYKGDs4sRCMzXVj8sEyw=="],
|
"@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw=="],
|
||||||
|
|
||||||
"@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.3", "", { "os": "linux", "cpu": "x64" }, "sha512-U5PUY5jbc45ANM6tSJpsgqmBF/VsL6LnxJmIf11kB7J5DctHgqm0SkuXzVWtIY90GnJxKnC/JT251TDnk1fu/g=="],
|
"@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw=="],
|
||||||
|
|
||||||
"@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.3" }, "os": "linux", "cpu": "arm" }, "sha512-Xyam4mlqM0KkTHYVSuc6wXRmM7LGN0P12li03jAnZ3EJWZqj83+hi8Y9UxZUbxsgsK1qOEwg7O0Bc0LjqQVtxA=="],
|
"@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg=="],
|
||||||
|
|
||||||
"@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.3" }, "os": "linux", "cpu": "arm64" }, "sha512-YXU1F/mN/Wu786tl72CyJjP/Ngl8mGHN1hST4BGl+hiW5jhCnV2uRVTNOcaYPs73NeT/H8Upm3y9582JVuZHrQ=="],
|
"@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.4" }, "os": "linux", "cpu": "arm" }, "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw=="],
|
||||||
|
|
||||||
"@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.3" }, "os": "linux", "cpu": "ppc64" }, "sha512-F4PDtF4Cy8L8hXA2p3TO6s4aDt93v+LKmpcYFLAVdkkD3hSxZzee0rh6/+94FpAynsuMpLX5h+LRsSG3rIciUQ=="],
|
"@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg=="],
|
||||||
|
|
||||||
"@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.3" }, "os": "linux", "cpu": "s390x" }, "sha512-qVrZKE9Bsnzy+myf7lFKvng6bQzhNUAYcVORq2P7bDlvmF6u2sCmK2KyEQEBdYk+u3T01pVsPrkj943T1aJAsw=="],
|
"@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.4" }, "os": "linux", "cpu": "ppc64" }, "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA=="],
|
||||||
|
|
||||||
"@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.3" }, "os": "linux", "cpu": "x64" }, "sha512-ZfGtcp2xS51iG79c6Vhw9CWqQC8l2Ot8dygxoDoIQPTat/Ov3qAa8qpxSrtAEAJW+UjTXc4yxCjNfxm4h6Xm2A=="],
|
"@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.2.4" }, "os": "linux", "cpu": "none" }, "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw=="],
|
||||||
|
|
||||||
"@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.3" }, "os": "linux", "cpu": "arm64" }, "sha512-8hDVvW9eu4yHWnjaOOR8kHVrew1iIX+MUgwxSuH2XyYeNRtLUe4VNioSqbNkB7ZYQJj9rUTT4PyRscyk2PXFKA=="],
|
"@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.4" }, "os": "linux", "cpu": "s390x" }, "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg=="],
|
||||||
|
|
||||||
"@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.4", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.3" }, "os": "linux", "cpu": "x64" }, "sha512-lU0aA5L8QTlfKjpDCEFOZsTYGn3AEiO6db8W5aQDxj0nQkVrZWmN3ZP9sYKWJdtq3PWPhUNlqehWyXpYDcI9Sg=="],
|
"@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ=="],
|
||||||
|
|
||||||
"@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.4", "", { "dependencies": { "@emnapi/runtime": "^1.5.0" }, "cpu": "none" }, "sha512-33QL6ZO/qpRyG7woB/HUALz28WnTMI2W1jgX3Nu2bypqLIKx/QKMILLJzJjI+SIbvXdG9fUnmrxR7vbi1sTBeA=="],
|
"@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg=="],
|
||||||
|
|
||||||
"@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-2Q250do/5WXTwxW3zjsEuMSv5sUU4Tq9VThWKlU2EYLm4MB7ZeMwF+SFJutldYODXF6jzc6YEOC+VfX0SZQPqA=="],
|
"@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q=="],
|
||||||
|
|
||||||
"@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.4", "", { "os": "win32", "cpu": "ia32" }, "sha512-3ZeLue5V82dT92CNL6rsal6I2weKw1cYu+rGKm8fOCCtJTR2gYeUfY3FqUnIJsMUPIH68oS5jmZ0NiJ508YpEw=="],
|
"@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.5", "", { "dependencies": { "@emnapi/runtime": "^1.7.0" }, "cpu": "none" }, "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw=="],
|
||||||
|
|
||||||
"@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.4", "", { "os": "win32", "cpu": "x64" }, "sha512-xIyj4wpYs8J18sVN3mSQjwrw7fKUqRw+Z5rnHNCy5fYTxigBz81u5mOMPmFumwjcn8+ld1ppptMBCLic1nz6ig=="],
|
"@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g=="],
|
||||||
|
|
||||||
|
"@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg=="],
|
||||||
|
|
||||||
|
"@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="],
|
||||||
|
|
||||||
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
|
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
|
||||||
|
|
||||||
@@ -171,25 +178,25 @@
|
|||||||
|
|
||||||
"@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.12", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.10.0" } }, "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ=="],
|
"@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.12", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.10.0" } }, "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ=="],
|
||||||
|
|
||||||
"@next/env": ["@next/env@16.0.1", "", {}, "sha512-LFvlK0TG2L3fEOX77OC35KowL8D7DlFF45C0OvKMC4hy8c/md1RC4UMNDlUGJqfCoCS2VWrZ4dSE6OjaX5+8mw=="],
|
"@next/env": ["@next/env@16.2.1", "", {}, "sha512-n8P/HCkIWW+gVal2Z8XqXJ6aB3J0tuM29OcHpCsobWlChH/SITBs1DFBk/HajgrwDkqqBXPbuUuzgDvUekREPg=="],
|
||||||
|
|
||||||
"@next/eslint-plugin-next": ["@next/eslint-plugin-next@16.0.1", "", { "dependencies": { "fast-glob": "3.3.1" } }, "sha512-g4Cqmv/gyFEXNeVB2HkqDlYKfy+YrlM2k8AVIO/YQVEPfhVruH1VA99uT1zELLnPLIeOnx8IZ6Ddso0asfTIdw=="],
|
"@next/eslint-plugin-next": ["@next/eslint-plugin-next@16.2.1", "", { "dependencies": { "fast-glob": "3.3.1" } }, "sha512-r0epZGo24eT4g08jJlg2OEryBphXqO8aL18oajoTKLzHJ6jVr6P6FI58DLMug04MwD3j8Fj0YK0slyzneKVyzA=="],
|
||||||
|
|
||||||
"@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.0.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-R0YxRp6/4W7yG1nKbfu41bp3d96a0EalonQXiMe+1H9GTHfKxGNCGFNWUho18avRBPsO8T3RmdWuzmfurlQPbg=="],
|
"@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.2.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-BwZ8w8YTaSEr2HIuXLMLxIdElNMPvY9fLqb20LX9A9OMGtJilhHLbCL3ggyd0TwjmMcTxi0XXt+ur1vWUoxj2Q=="],
|
||||||
|
|
||||||
"@next/swc-darwin-x64": ["@next/swc-darwin-x64@16.0.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-kETZBocRux3xITiZtOtVoVvXyQLB7VBxN7L6EPqgI5paZiUlnsgYv4q8diTNYeHmF9EiehydOBo20lTttCbHAg=="],
|
"@next/swc-darwin-x64": ["@next/swc-darwin-x64@16.2.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-/vrcE6iQSJq3uL3VGVHiXeaKbn8Es10DGTGRJnRZlkNQQk3kaNtAJg8Y6xuAlrx/6INKVjkfi5rY0iEXorZ6uA=="],
|
||||||
|
|
||||||
"@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@16.0.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-hWg3BtsxQuSKhfe0LunJoqxjO4NEpBmKkE+P2Sroos7yB//OOX3jD5ISP2wv8QdUwtRehMdwYz6VB50mY6hqAg=="],
|
"@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@16.2.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-uLn+0BK+C31LTVbQ/QU+UaVrV0rRSJQ8RfniQAHPghDdgE+SlroYqcmFnO5iNjNfVWCyKZHYrs3Nl0mUzWxbBw=="],
|
||||||
|
|
||||||
"@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@16.0.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-UPnOvYg+fjAhP3b1iQStcYPWeBFRLrugEyK/lDKGk7kLNua8t5/DvDbAEFotfV1YfcOY6bru76qN9qnjLoyHCQ=="],
|
"@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@16.2.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-ssKq6iMRnHdnycGp9hCuGnXJZ0YPr4/wNwrfE5DbmvEcgl9+yv97/Kq3TPVDfYome1SW5geciLB9aiEqKXQjlQ=="],
|
||||||
|
|
||||||
"@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@16.0.1", "", { "os": "linux", "cpu": "x64" }, "sha512-Et81SdWkcRqAJziIgFtsFyJizHoWne4fzJkvjd6V4wEkWTB4MX6J0uByUb0peiJQ4WeAt6GGmMszE5KrXK6WKg=="],
|
"@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@16.2.1", "", { "os": "linux", "cpu": "x64" }, "sha512-HQm7SrHRELJ30T1TSmT706IWovFFSRGxfgUkyWJZF/RKBMdbdRWJuFrcpDdE5vy9UXjFOx6L3mRdqH04Mmx0hg=="],
|
||||||
|
|
||||||
"@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@16.0.1", "", { "os": "linux", "cpu": "x64" }, "sha512-qBbgYEBRrC1egcG03FZaVfVxrJm8wBl7vr8UFKplnxNRprctdP26xEv9nJ07Ggq4y1adwa0nz2mz83CELY7N6Q=="],
|
"@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@16.2.1", "", { "os": "linux", "cpu": "x64" }, "sha512-aV2iUaC/5HGEpbBkE+4B8aHIudoOy5DYekAKOMSHoIYQ66y/wIVeaRx8MS2ZMdxe/HIXlMho4ubdZs/J8441Tg=="],
|
||||||
|
|
||||||
"@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@16.0.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-cPuBjYP6I699/RdbHJonb3BiRNEDm5CKEBuJ6SD8k3oLam2fDRMKAvmrli4QMDgT2ixyRJ0+DTkiODbIQhRkeQ=="],
|
"@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@16.2.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-IXdNgiDHaSk0ZUJ+xp0OQTdTgnpx1RCfRTalhn3cjOP+IddTMINwA7DXZrwTmGDO8SUr5q2hdP/du4DcrB1GxA=="],
|
||||||
|
|
||||||
"@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.0.1", "", { "os": "win32", "cpu": "x64" }, "sha512-XeEUJsE4JYtfrXe/LaJn3z1pD19fK0Q6Er8Qoufi+HqvdO4LEPyCxLUt4rxA+4RfYo6S9gMlmzCMU2F+AatFqQ=="],
|
"@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.2.1", "", { "os": "win32", "cpu": "x64" }, "sha512-qvU+3a39Hay+ieIztkGSbF7+mccbbg1Tk25hc4JDylf8IHjYmY/Zm64Qq1602yPyQqvie+vf5T/uPwNxDNIoeg=="],
|
||||||
|
|
||||||
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
|
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
|
||||||
|
|
||||||
@@ -203,72 +210,78 @@
|
|||||||
|
|
||||||
"@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="],
|
"@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="],
|
||||||
|
|
||||||
"@tailwindcss/node": ["@tailwindcss/node@4.1.16", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", "jiti": "^2.6.1", "lightningcss": "1.30.2", "magic-string": "^0.30.19", "source-map-js": "^1.2.1", "tailwindcss": "4.1.16" } }, "sha512-BX5iaSsloNuvKNHRN3k2RcCuTEgASTo77mofW0vmeHkfrDWaoFAFvNHpEgtu0eqyypcyiBkDWzSMxJhp3AUVcw=="],
|
"@tailwindcss/node": ["@tailwindcss/node@4.2.2", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "^5.19.0", "jiti": "^2.6.1", "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.2.2" } }, "sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.16", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.16", "@tailwindcss/oxide-darwin-arm64": "4.1.16", "@tailwindcss/oxide-darwin-x64": "4.1.16", "@tailwindcss/oxide-freebsd-x64": "4.1.16", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.16", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.16", "@tailwindcss/oxide-linux-arm64-musl": "4.1.16", "@tailwindcss/oxide-linux-x64-gnu": "4.1.16", "@tailwindcss/oxide-linux-x64-musl": "4.1.16", "@tailwindcss/oxide-wasm32-wasi": "4.1.16", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.16", "@tailwindcss/oxide-win32-x64-msvc": "4.1.16" } }, "sha512-2OSv52FRuhdlgyOQqgtQHuCgXnS8nFSYRp2tJ+4WZXKgTxqPy7SMSls8c3mPT5pkZ17SBToGM5LHEJBO7miEdg=="],
|
"@tailwindcss/oxide": ["@tailwindcss/oxide@4.2.2", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.2.2", "@tailwindcss/oxide-darwin-arm64": "4.2.2", "@tailwindcss/oxide-darwin-x64": "4.2.2", "@tailwindcss/oxide-freebsd-x64": "4.2.2", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.2", "@tailwindcss/oxide-linux-arm64-gnu": "4.2.2", "@tailwindcss/oxide-linux-arm64-musl": "4.2.2", "@tailwindcss/oxide-linux-x64-gnu": "4.2.2", "@tailwindcss/oxide-linux-x64-musl": "4.2.2", "@tailwindcss/oxide-wasm32-wasi": "4.2.2", "@tailwindcss/oxide-win32-arm64-msvc": "4.2.2", "@tailwindcss/oxide-win32-x64-msvc": "4.2.2" } }, "sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.16", "", { "os": "android", "cpu": "arm64" }, "sha512-8+ctzkjHgwDJ5caq9IqRSgsP70xhdhJvm+oueS/yhD5ixLhqTw9fSL1OurzMUhBwE5zK26FXLCz2f/RtkISqHA=="],
|
"@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.2.2", "", { "os": "android", "cpu": "arm64" }, "sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.16", "", { "os": "darwin", "cpu": "arm64" }, "sha512-C3oZy5042v2FOALBZtY0JTDnGNdS6w7DxL/odvSny17ORUnaRKhyTse8xYi3yKGyfnTUOdavRCdmc8QqJYwFKA=="],
|
"@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.2.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.16", "", { "os": "darwin", "cpu": "x64" }, "sha512-vjrl/1Ub9+JwU6BP0emgipGjowzYZMjbWCDqwA2Z4vCa+HBSpP4v6U2ddejcHsolsYxwL5r4bPNoamlV0xDdLg=="],
|
"@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.2.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.16", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TSMpPYpQLm+aR1wW5rKuUuEruc/oOX3C7H0BTnPDn7W/eMw8W+MRMpiypKMkXZfwH8wqPIRKppuZoedTtNj2tg=="],
|
"@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.2.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.16", "", { "os": "linux", "cpu": "arm" }, "sha512-p0GGfRg/w0sdsFKBjMYvvKIiKy/LNWLWgV/plR4lUgrsxFAoQBFrXkZ4C0w8IOXfslB9vHK/JGASWD2IefIpvw=="],
|
"@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2", "", { "os": "linux", "cpu": "arm" }, "sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.16", "", { "os": "linux", "cpu": "arm64" }, "sha512-DoixyMmTNO19rwRPdqviTrG1rYzpxgyYJl8RgQvdAQUzxC1ToLRqtNJpU/ATURSKgIg6uerPw2feW0aS8SNr/w=="],
|
"@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.2.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.16", "", { "os": "linux", "cpu": "arm64" }, "sha512-H81UXMa9hJhWhaAUca6bU2wm5RRFpuHImrwXBUvPbYb+3jo32I9VIwpOX6hms0fPmA6f2pGVlybO6qU8pF4fzQ=="],
|
"@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.2.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.16", "", { "os": "linux", "cpu": "x64" }, "sha512-ZGHQxDtFC2/ruo7t99Qo2TTIvOERULPl5l0K1g0oK6b5PGqjYMga+FcY1wIUnrUxY56h28FxybtDEla+ICOyew=="],
|
"@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.2.2", "", { "os": "linux", "cpu": "x64" }, "sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.16", "", { "os": "linux", "cpu": "x64" }, "sha512-Oi1tAaa0rcKf1Og9MzKeINZzMLPbhxvm7rno5/zuP1WYmpiG0bEHq4AcRUiG2165/WUzvxkW4XDYCscZWbTLZw=="],
|
"@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.2.2", "", { "os": "linux", "cpu": "x64" }, "sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.16", "", { "dependencies": { "@emnapi/core": "^1.5.0", "@emnapi/runtime": "^1.5.0", "@emnapi/wasi-threads": "^1.1.0", "@napi-rs/wasm-runtime": "^1.0.7", "@tybys/wasm-util": "^0.10.1", "tslib": "^2.4.0" }, "cpu": "none" }, "sha512-B01u/b8LteGRwucIBmCQ07FVXLzImWESAIMcUU6nvFt/tYsQ6IHz8DmZ5KtvmwxD+iTYBtM1xwoGXswnlu9v0Q=="],
|
"@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.2.2", "", { "dependencies": { "@emnapi/core": "^1.8.1", "@emnapi/runtime": "^1.8.1", "@emnapi/wasi-threads": "^1.1.0", "@napi-rs/wasm-runtime": "^1.1.1", "@tybys/wasm-util": "^0.10.1", "tslib": "^2.8.1" }, "cpu": "none" }, "sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.16", "", { "os": "win32", "cpu": "arm64" }, "sha512-zX+Q8sSkGj6HKRTMJXuPvOcP8XfYON24zJBRPlszcH1Np7xuHXhWn8qfFjIujVzvH3BHU+16jBXwgpl20i+v9A=="],
|
"@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.2.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.16", "", { "os": "win32", "cpu": "x64" }, "sha512-m5dDFJUEejbFqP+UXVstd4W/wnxA4F61q8SoL+mqTypId2T2ZpuxosNSgowiCnLp2+Z+rivdU0AqpfgiD7yCBg=="],
|
"@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.2.2", "", { "os": "win32", "cpu": "x64" }, "sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA=="],
|
||||||
|
|
||||||
"@tailwindcss/postcss": ["@tailwindcss/postcss@4.1.16", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.1.16", "@tailwindcss/oxide": "4.1.16", "postcss": "^8.4.41", "tailwindcss": "4.1.16" } }, "sha512-Qn3SFGPXYQMKR/UtqS+dqvPrzEeBZHrFA92maT4zijCVggdsXnDBMsPFJo1eArX3J+O+Gi+8pV4PkqjLCNBk3A=="],
|
"@tailwindcss/postcss": ["@tailwindcss/postcss@4.2.2", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.2.2", "@tailwindcss/oxide": "4.2.2", "postcss": "^8.5.6", "tailwindcss": "4.2.2" } }, "sha512-n4goKQbW8RVXIbNKRB/45LzyUqN451deQK0nzIeauVEqjlI49slUlgKYJM2QyUzap/PcpnS7kzSUmPb1sCRvYQ=="],
|
||||||
|
|
||||||
"@tauri-apps/api": ["@tauri-apps/api@2.9.0", "", {}, "sha512-qD5tMjh7utwBk9/5PrTA/aGr3i5QaJ/Mlt7p8NilQ45WgbifUNPyKWsA63iQ8YfQq6R8ajMapU+/Q8nMcPRLNw=="],
|
"@tauri-apps/api": ["@tauri-apps/api@2.10.1", "", {}, "sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw=="],
|
||||||
|
|
||||||
"@tauri-apps/cli": ["@tauri-apps/cli@2.9.2", "", { "optionalDependencies": { "@tauri-apps/cli-darwin-arm64": "2.9.2", "@tauri-apps/cli-darwin-x64": "2.9.2", "@tauri-apps/cli-linux-arm-gnueabihf": "2.9.2", "@tauri-apps/cli-linux-arm64-gnu": "2.9.2", "@tauri-apps/cli-linux-arm64-musl": "2.9.2", "@tauri-apps/cli-linux-riscv64-gnu": "2.9.2", "@tauri-apps/cli-linux-x64-gnu": "2.9.2", "@tauri-apps/cli-linux-x64-musl": "2.9.2", "@tauri-apps/cli-win32-arm64-msvc": "2.9.2", "@tauri-apps/cli-win32-ia32-msvc": "2.9.2", "@tauri-apps/cli-win32-x64-msvc": "2.9.2" }, "bin": { "tauri": "tauri.js" } }, "sha512-aGzdVgxQW6WQ7e5nydPZ/30u8HvltHjO3Ytzf1wOxX1N5Yj2TsjKWRb/AWJlB95Huml3k3c/b6s0ijAvlSo9xw=="],
|
"@tauri-apps/cli": ["@tauri-apps/cli@2.10.1", "", { "optionalDependencies": { "@tauri-apps/cli-darwin-arm64": "2.10.1", "@tauri-apps/cli-darwin-x64": "2.10.1", "@tauri-apps/cli-linux-arm-gnueabihf": "2.10.1", "@tauri-apps/cli-linux-arm64-gnu": "2.10.1", "@tauri-apps/cli-linux-arm64-musl": "2.10.1", "@tauri-apps/cli-linux-riscv64-gnu": "2.10.1", "@tauri-apps/cli-linux-x64-gnu": "2.10.1", "@tauri-apps/cli-linux-x64-musl": "2.10.1", "@tauri-apps/cli-win32-arm64-msvc": "2.10.1", "@tauri-apps/cli-win32-ia32-msvc": "2.10.1", "@tauri-apps/cli-win32-x64-msvc": "2.10.1" }, "bin": { "tauri": "tauri.js" } }, "sha512-jQNGF/5quwORdZSSLtTluyKQ+o6SMa/AUICfhf4egCGFdMHqWssApVgYSbg+jmrZoc8e1DscNvjTnXtlHLS11g=="],
|
||||||
|
|
||||||
"@tauri-apps/cli-darwin-arm64": ["@tauri-apps/cli-darwin-arm64@2.9.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-g1OtCXydOZFYRUEAyGYdJ2lLaE3l5jk8o+Bro8y2WOLwBLtbWjBoJIVobOKFanfjG/Xr8H/UA+umEVILPhMc2A=="],
|
"@tauri-apps/cli-darwin-arm64": ["@tauri-apps/cli-darwin-arm64@2.10.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Z2OjCXiZ+fbYZy7PmP3WRnOpM9+Fy+oonKDEmUE6MwN4IGaYqgceTjwHucc/kEEYZos5GICve35f7ZiizgqEnQ=="],
|
||||||
|
|
||||||
"@tauri-apps/cli-darwin-x64": ["@tauri-apps/cli-darwin-x64@2.9.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-nHHIY33noUmMOyFwAJz0xQyrYIXU+bae8MNos4TGsTo491YWAF2uzr6iW+Bq0N530xDcbe7EyRvDHgK43RmmVw=="],
|
"@tauri-apps/cli-darwin-x64": ["@tauri-apps/cli-darwin-x64@2.10.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-V/irQVvjPMGOTQqNj55PnQPVuH4VJP8vZCN7ajnj+ZS8Kom1tEM2hR3qbbIRoS3dBKs5mbG8yg1WC+97dq17Pw=="],
|
||||||
|
|
||||||
"@tauri-apps/cli-linux-arm-gnueabihf": ["@tauri-apps/cli-linux-arm-gnueabihf@2.9.2", "", { "os": "linux", "cpu": "arm" }, "sha512-Dq17LBdSuzf+fWOKMIyiSao+Fcq4FiQwYYlx3Nk8oafDINc8sVBjC5gv2xp18KzYhk9teSWfmDpD1sj+D3t7uw=="],
|
"@tauri-apps/cli-linux-arm-gnueabihf": ["@tauri-apps/cli-linux-arm-gnueabihf@2.10.1", "", { "os": "linux", "cpu": "arm" }, "sha512-Hyzwsb4VnCWKGfTw+wSt15Z2pLw2f0JdFBfq2vHBOBhvg7oi6uhKiF87hmbXOBXUZaGkyRDkCHsdzJcIfoJC2w=="],
|
||||||
|
|
||||||
"@tauri-apps/cli-linux-arm64-gnu": ["@tauri-apps/cli-linux-arm64-gnu@2.9.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-Pxj5k29Rxj9xEht4gdE744t5HLXTwBojkjYDXXyJ3mE+BEg9hFX5WkStg7OkyZwH60u8NSkDSMpo7MJTH9srmA=="],
|
"@tauri-apps/cli-linux-arm64-gnu": ["@tauri-apps/cli-linux-arm64-gnu@2.10.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-OyOYs2t5GkBIvyWjA1+h4CZxTcdz1OZPCWAPz5DYEfB0cnWHERTnQ/SLayQzncrT0kwRoSfSz9KxenkyJoTelA=="],
|
||||||
|
|
||||||
"@tauri-apps/cli-linux-arm64-musl": ["@tauri-apps/cli-linux-arm64-musl@2.9.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-mx82BuD4q3Yj5Zw+LXveZgPaDCnmH2At2LosX1siK77kaD5Ap5FF+FN0V4y+3cwq+Hcrk9AhEUPbHqoNOx1R2g=="],
|
"@tauri-apps/cli-linux-arm64-musl": ["@tauri-apps/cli-linux-arm64-musl@2.10.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-MIj78PDDGjkg3NqGptDOGgfXks7SYJwhiMh8SBoZS+vfdz7yP5jN18bNaLnDhsVIPARcAhE1TlsZe/8Yxo2zqg=="],
|
||||||
|
|
||||||
"@tauri-apps/cli-linux-riscv64-gnu": ["@tauri-apps/cli-linux-riscv64-gnu@2.9.2", "", { "os": "linux", "cpu": "none" }, "sha512-Ypm1nnr7k+ECC1+JfDcnxROHt6BX8t/4GplxBvdY68BDXtIcBbdhPWDos7MK+3bDmoaA0WSJbW+DUjpfSkyKgw=="],
|
"@tauri-apps/cli-linux-riscv64-gnu": ["@tauri-apps/cli-linux-riscv64-gnu@2.10.1", "", { "os": "linux", "cpu": "none" }, "sha512-X0lvOVUg8PCVaoEtEAnpxmnkwlE1gcMDTqfhbefICKDnOTJ5Est3qL0SrWxizDackIOKBcvtpejrSiVpuJI1kw=="],
|
||||||
|
|
||||||
"@tauri-apps/cli-linux-x64-gnu": ["@tauri-apps/cli-linux-x64-gnu@2.9.2", "", { "os": "linux", "cpu": "x64" }, "sha512-tg85cGIM9PWwsbQg8m3uah3SfoNapgUr4vhWtkqgeTDZOjQuQ2duTwCH4UiM7acBpbZHNzvRrxSFpv0U53TqQQ=="],
|
"@tauri-apps/cli-linux-x64-gnu": ["@tauri-apps/cli-linux-x64-gnu@2.10.1", "", { "os": "linux", "cpu": "x64" }, "sha512-2/12bEzsJS9fAKybxgicCDFxYD1WEI9kO+tlDwX5znWG2GwMBaiWcmhGlZ8fi+DMe9CXlcVarMTYc0L3REIRxw=="],
|
||||||
|
|
||||||
"@tauri-apps/cli-linux-x64-musl": ["@tauri-apps/cli-linux-x64-musl@2.9.2", "", { "os": "linux", "cpu": "x64" }, "sha512-xW8qaz9bcwR35W2gIg7fKG9e1Z34idOsGpD2zIPgxlJyF314B/1qie50hbOqt5AbbXHR4iRpxKE4kA2grqMmkg=="],
|
"@tauri-apps/cli-linux-x64-musl": ["@tauri-apps/cli-linux-x64-musl@2.10.1", "", { "os": "linux", "cpu": "x64" }, "sha512-Y8J0ZzswPz50UcGOFuXGEMrxbjwKSPgXftx5qnkuMs2rmwQB5ssvLb6tn54wDSYxe7S6vlLob9vt0VKuNOaCIQ=="],
|
||||||
|
|
||||||
"@tauri-apps/cli-win32-arm64-msvc": ["@tauri-apps/cli-win32-arm64-msvc@2.9.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-A1PshB8oHdY7zYOPlLD7Om7/aD9sOUVREd765ElIzYDtptWcALwOP9jb22Wi01vDTqxf98E4ZGIcG2gxr4FhiA=="],
|
"@tauri-apps/cli-win32-arm64-msvc": ["@tauri-apps/cli-win32-arm64-msvc@2.10.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-iSt5B86jHYAPJa/IlYw++SXtFPGnWtFJriHn7X0NFBVunF6zu9+/zOn8OgqIWSl8RgzhLGXQEEtGBdR4wzpVgg=="],
|
||||||
|
|
||||||
"@tauri-apps/cli-win32-ia32-msvc": ["@tauri-apps/cli-win32-ia32-msvc@2.9.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-AuCi0Vnc4qkXRLCC58das0u45SmXAjqcOjqF324CBKa1Z7jjNJESm0Sc2oc2G2q6f2eAbAfi34s2iJNaJU1hlQ=="],
|
"@tauri-apps/cli-win32-ia32-msvc": ["@tauri-apps/cli-win32-ia32-msvc@2.10.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-gXyxgEzsFegmnWywYU5pEBURkcFN/Oo45EAwvZrHMh+zUSEAvO5E8TXsgPADYm31d1u7OQU3O3HsYfVBf2moHw=="],
|
||||||
|
|
||||||
"@tauri-apps/cli-win32-x64-msvc": ["@tauri-apps/cli-win32-x64-msvc@2.9.2", "", { "os": "win32", "cpu": "x64" }, "sha512-kDoejyfvME/mLkR4VofQnmVPTt/smJvoXuE3xgTbUwcUQKqawM8EyQvxOHQosaJYfQphHi7G0ya8UZo3PlDZig=="],
|
"@tauri-apps/cli-win32-x64-msvc": ["@tauri-apps/cli-win32-x64-msvc@2.10.1", "", { "os": "win32", "cpu": "x64" }, "sha512-6Cn7YpPFwzChy0ERz6djKEmUehWrYlM+xTaNzGPgZocw3BD7OfwfWHKVWxXzdjEW2KfKkHddfdxK1XXTYqBRLg=="],
|
||||||
|
|
||||||
"@tauri-apps/plugin-dialog": ["@tauri-apps/plugin-dialog@2.4.2", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-lNIn5CZuw8WZOn8zHzmFmDSzg5zfohWoa3mdULP0YFh/VogVdMVWZPcWSHlydsiJhRQYaTNSYKN7RmZKE2lCYQ=="],
|
"@tauri-apps/plugin-clipboard-manager": ["@tauri-apps/plugin-clipboard-manager@2.3.2", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-CUlb5Hqi2oZbcZf4VUyUH53XWPPdtpw43EUpCza5HWZJwxEoDowFzNUDt1tRUXA8Uq+XPn17Ysfptip33sG4eQ=="],
|
||||||
|
|
||||||
"@tauri-apps/plugin-fs": ["@tauri-apps/plugin-fs@2.4.4", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-MTorXxIRmOnOPT1jZ3w96vjSuScER38ryXY88vl5F0uiKdnvTKKTtaEjTEo8uPbl4e3gnUtfsDVwC7h77GQLvQ=="],
|
"@tauri-apps/plugin-dialog": ["@tauri-apps/plugin-dialog@2.6.0", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-q4Uq3eY87TdcYzXACiYSPhmpBA76shgmQswGkSVio4C82Sz2W4iehe9TnKYwbq7weHiL88Yw19XZm7v28+Micg=="],
|
||||||
|
|
||||||
|
"@tauri-apps/plugin-fs": ["@tauri-apps/plugin-fs@2.4.5", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-dVxWWGE6VrOxC7/jlhyE+ON/Cc2REJlM35R3PJX3UvFw2XwYhLGQVAIyrehenDdKjotipjYEVc4YjOl3qq90fA=="],
|
||||||
|
|
||||||
|
"@tauri-apps/plugin-http": ["@tauri-apps/plugin-http@2.5.7", "", { "dependencies": { "@tauri-apps/api": "^2.10.1" } }, "sha512-+F2lEH/c9b0zSsOXKq+5hZNcd9F4IIKCK1T17RqMwpCmVnx2aoqY8yIBccCd25HTYUb3j6NPVbRax/m00hKG8A=="],
|
||||||
|
|
||||||
"@tauri-apps/plugin-notification": ["@tauri-apps/plugin-notification@2.3.3", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-Zw+ZH18RJb41G4NrfHgIuofJiymusqN+q8fGUIIV7vyCH+5sSn5coqRv/MWB9qETsUs97vmU045q7OyseCV3Qg=="],
|
"@tauri-apps/plugin-notification": ["@tauri-apps/plugin-notification@2.3.3", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-Zw+ZH18RJb41G4NrfHgIuofJiymusqN+q8fGUIIV7vyCH+5sSn5coqRv/MWB9qETsUs97vmU045q7OyseCV3Qg=="],
|
||||||
|
|
||||||
"@tauri-apps/plugin-opener": ["@tauri-apps/plugin-opener@2.5.2", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-ei/yRRoCklWHImwpCcDK3VhNXx+QXM9793aQ64YxpqVF0BDuuIlXhZgiAkc15wnPVav+IbkYhmDJIv5R326Mew=="],
|
"@tauri-apps/plugin-opener": ["@tauri-apps/plugin-opener@2.5.3", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-CCcUltXMOfUEArbf3db3kCE7Ggy1ExBEBl51Ko2ODJ6GDYHRp1nSNlQm5uNCFY5k7/ufaK5Ib3Du/Zir19IYQQ=="],
|
||||||
|
|
||||||
"@tauri-apps/plugin-os": ["@tauri-apps/plugin-os@2.3.2", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-n+nXWeuSeF9wcEsSPmRnBEGrRgOy6jjkSU+UVCOV8YUGKb2erhDOxis7IqRXiRVHhY8XMKks00BJ0OAdkpf6+A=="],
|
"@tauri-apps/plugin-os": ["@tauri-apps/plugin-os@2.3.2", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-n+nXWeuSeF9wcEsSPmRnBEGrRgOy6jjkSU+UVCOV8YUGKb2erhDOxis7IqRXiRVHhY8XMKks00BJ0OAdkpf6+A=="],
|
||||||
|
|
||||||
|
"@tauri-apps/plugin-window-state": ["@tauri-apps/plugin-window-state@2.4.1", "", { "dependencies": { "@tauri-apps/api": "^2.8.0" } }, "sha512-OuvdrzyY8Q5Dbzpj+GcrnV1iCeoZbcFdzMjanZMMcAEUNy/6PH5pxZPXpaZLOR7whlzXiuzx0L9EKZbH7zpdRw=="],
|
||||||
|
|
||||||
"@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
|
"@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
|
||||||
|
|
||||||
"@types/crypto-js": ["@types/crypto-js@4.2.2", "", {}, "sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ=="],
|
"@types/crypto-js": ["@types/crypto-js@4.2.2", "", {}, "sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ=="],
|
||||||
@@ -279,31 +292,31 @@
|
|||||||
|
|
||||||
"@types/json5": ["@types/json5@0.0.29", "", {}, "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="],
|
"@types/json5": ["@types/json5@0.0.29", "", {}, "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="],
|
||||||
|
|
||||||
"@types/node": ["@types/node@24.9.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-uWN8YqxXxqFMX2RqGOrumsKeti4LlmIMIyV0lgut4jx7KQBcBiW6vkDtIBvHnHIquwNfJhk8v2OtmO8zXWHfPA=="],
|
"@types/node": ["@types/node@25.5.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw=="],
|
||||||
|
|
||||||
"@types/react": ["@types/react@19.2.2", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA=="],
|
"@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="],
|
||||||
|
|
||||||
"@types/react-dom": ["@types/react-dom@19.2.2", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw=="],
|
"@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="],
|
||||||
|
|
||||||
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.46.2", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.46.2", "@typescript-eslint/type-utils": "8.46.2", "@typescript-eslint/utils": "8.46.2", "@typescript-eslint/visitor-keys": "8.46.2", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.46.2", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-ZGBMToy857/NIPaaCucIUQgqueOiq7HeAKkhlvqVV4lm089zUFW6ikRySx2v+cAhKeUCPuWVHeimyk6Dw1iY3w=="],
|
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.57.2", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.57.2", "@typescript-eslint/type-utils": "8.57.2", "@typescript-eslint/utils": "8.57.2", "@typescript-eslint/visitor-keys": "8.57.2", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.57.2", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-NZZgp0Fm2IkD+La5PR81sd+g+8oS6JwJje+aRWsDocxHkjyRw0J5L5ZTlN3LI1LlOcGL7ph3eaIUmTXMIjLk0w=="],
|
||||||
|
|
||||||
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.46.2", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.46.2", "@typescript-eslint/types": "8.46.2", "@typescript-eslint/typescript-estree": "8.46.2", "@typescript-eslint/visitor-keys": "8.46.2", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g=="],
|
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.57.2", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.57.2", "@typescript-eslint/types": "8.57.2", "@typescript-eslint/typescript-estree": "8.57.2", "@typescript-eslint/visitor-keys": "8.57.2", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-30ScMRHIAD33JJQkgfGW1t8CURZtjc2JpTrq5n2HFhOefbAhb7ucc7xJwdWcrEtqUIYJ73Nybpsggii6GtAHjA=="],
|
||||||
|
|
||||||
"@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.46.2", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.46.2", "@typescript-eslint/types": "^8.46.2", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-PULOLZ9iqwI7hXcmL4fVfIsBi6AN9YxRc0frbvmg8f+4hQAjQ5GYNKK0DIArNo+rOKmR/iBYwkpBmnIwin4wBg=="],
|
"@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.57.2", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.57.2", "@typescript-eslint/types": "^8.57.2", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-FuH0wipFywXRTHf+bTTjNyuNQQsQC3qh/dYzaM4I4W0jrCqjCVuUh99+xd9KamUfmCGPvbO8NDngo/vsnNVqgw=="],
|
||||||
|
|
||||||
"@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.46.2", "", { "dependencies": { "@typescript-eslint/types": "8.46.2", "@typescript-eslint/visitor-keys": "8.46.2" } }, "sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA=="],
|
"@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.57.2", "", { "dependencies": { "@typescript-eslint/types": "8.57.2", "@typescript-eslint/visitor-keys": "8.57.2" } }, "sha512-snZKH+W4WbWkrBqj4gUNRIGb/jipDW3qMqVJ4C9rzdFc+wLwruxk+2a5D+uoFcKPAqyqEnSb4l2ULuZf95eSkw=="],
|
||||||
|
|
||||||
"@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.46.2", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-a7QH6fw4S57+F5y2FIxxSDyi5M4UfGF+Jl1bCGd7+L4KsaUY80GsiF/t0UoRFDHAguKlBaACWJRmdrc6Xfkkag=="],
|
"@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.57.2", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-3Lm5DSM+DCowsUOJC+YqHHnKEfFh5CoGkj5Z31NQSNF4l5wdOwqGn99wmwN/LImhfY3KJnmordBq/4+VDe2eKw=="],
|
||||||
|
|
||||||
"@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.46.2", "", { "dependencies": { "@typescript-eslint/types": "8.46.2", "@typescript-eslint/typescript-estree": "8.46.2", "@typescript-eslint/utils": "8.46.2", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-HbPM4LbaAAt/DjxXaG9yiS9brOOz6fabal4uvUmaUYe6l3K1phQDMQKBRUrr06BQkxkvIZVVHttqiybM9nJsLA=="],
|
"@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.57.2", "", { "dependencies": { "@typescript-eslint/types": "8.57.2", "@typescript-eslint/typescript-estree": "8.57.2", "@typescript-eslint/utils": "8.57.2", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-Co6ZCShm6kIbAM/s+oYVpKFfW7LBc6FXoPXjTRQ449PPNBY8U0KZXuevz5IFuuUj2H9ss40atTaf9dlGLzbWZg=="],
|
||||||
|
|
||||||
"@typescript-eslint/types": ["@typescript-eslint/types@8.46.2", "", {}, "sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ=="],
|
"@typescript-eslint/types": ["@typescript-eslint/types@8.57.2", "", {}, "sha512-/iZM6FnM4tnx9csuTxspMW4BOSegshwX5oBDznJ7S4WggL7Vczz5d2W11ecc4vRrQMQHXRSxzrCsyG5EsPPTbA=="],
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.46.2", "", { "dependencies": { "@typescript-eslint/project-service": "8.46.2", "@typescript-eslint/tsconfig-utils": "8.46.2", "@typescript-eslint/types": "8.46.2", "@typescript-eslint/visitor-keys": "8.46.2", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-f7rW7LJ2b7Uh2EiQ+7sza6RDZnajbNbemn54Ob6fRwQbgcIn+GWfyuHDHRYgRoZu1P4AayVScrRW+YfbTvPQoQ=="],
|
"@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.57.2", "", { "dependencies": { "@typescript-eslint/project-service": "8.57.2", "@typescript-eslint/tsconfig-utils": "8.57.2", "@typescript-eslint/types": "8.57.2", "@typescript-eslint/visitor-keys": "8.57.2", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-2MKM+I6g8tJxfSmFKOnHv2t8Sk3T6rF20A1Puk0svLK+uVapDZB/4pfAeB7nE83uAZrU6OxW+HmOd5wHVdXwXA=="],
|
||||||
|
|
||||||
"@typescript-eslint/utils": ["@typescript-eslint/utils@8.46.2", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.46.2", "@typescript-eslint/types": "8.46.2", "@typescript-eslint/typescript-estree": "8.46.2" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-sExxzucx0Tud5tE0XqR0lT0psBQvEpnpiul9XbGUB1QwpWJJAps1O/Z7hJxLGiZLBKMCutjTzDgmd1muEhBnVg=="],
|
"@typescript-eslint/utils": ["@typescript-eslint/utils@8.57.2", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.57.2", "@typescript-eslint/types": "8.57.2", "@typescript-eslint/typescript-estree": "8.57.2" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-krRIbvPK1ju1WBKIefiX+bngPs+odIQUtR7kymzPfo1POVw3jlF+nLkmexdSSd4UCbDcQn+wMBATOOmpBbqgKg=="],
|
||||||
|
|
||||||
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.46.2", "", { "dependencies": { "@typescript-eslint/types": "8.46.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w=="],
|
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.57.2", "", { "dependencies": { "@typescript-eslint/types": "8.57.2", "eslint-visitor-keys": "^5.0.0" } }, "sha512-zhahknjobV2FiD6Ee9iLbS7OV9zi10rG26odsQdfBO/hjSzUQbkIYgda+iNKK1zNiW2ey+Lf8MU5btN17V3dUw=="],
|
||||||
|
|
||||||
"@unrs/resolver-binding-android-arm-eabi": ["@unrs/resolver-binding-android-arm-eabi@1.11.1", "", { "os": "android", "cpu": "arm" }, "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw=="],
|
"@unrs/resolver-binding-android-arm-eabi": ["@unrs/resolver-binding-android-arm-eabi@1.11.1", "", { "os": "android", "cpu": "arm" }, "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw=="],
|
||||||
|
|
||||||
@@ -343,11 +356,11 @@
|
|||||||
|
|
||||||
"@unrs/resolver-binding-win32-x64-msvc": ["@unrs/resolver-binding-win32-x64-msvc@1.11.1", "", { "os": "win32", "cpu": "x64" }, "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g=="],
|
"@unrs/resolver-binding-win32-x64-msvc": ["@unrs/resolver-binding-win32-x64-msvc@1.11.1", "", { "os": "win32", "cpu": "x64" }, "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g=="],
|
||||||
|
|
||||||
"acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
|
"acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="],
|
||||||
|
|
||||||
"acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
|
"acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
|
||||||
|
|
||||||
"ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
|
"ajv": ["ajv@6.14.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw=="],
|
||||||
|
|
||||||
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
||||||
|
|
||||||
@@ -375,25 +388,21 @@
|
|||||||
|
|
||||||
"async-function": ["async-function@1.0.0", "", {}, "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA=="],
|
"async-function": ["async-function@1.0.0", "", {}, "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA=="],
|
||||||
|
|
||||||
"asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="],
|
|
||||||
|
|
||||||
"available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="],
|
"available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="],
|
||||||
|
|
||||||
"axe-core": ["axe-core@4.11.0", "", {}, "sha512-ilYanEU8vxxBexpJd8cWM4ElSQq4QctCLKih0TSfjIfCQTeyH/6zVrmIJfLPrKTKJRbiG+cfnZbQIjAlJmF1jQ=="],
|
"axe-core": ["axe-core@4.11.1", "", {}, "sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A=="],
|
||||||
|
|
||||||
"axios": ["axios@1.13.1", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-hU4EGxxt+j7TQijx1oYdAjw4xuIp1wRQSsbMFwSthCWeBQur1eF+qJ5iQ5sN3Tw8YRzQNKb8jszgBdMDVqwJcw=="],
|
|
||||||
|
|
||||||
"axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
|
"axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
|
||||||
|
|
||||||
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||||
|
|
||||||
"baseline-browser-mapping": ["baseline-browser-mapping@2.8.21", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-JU0h5APyQNsHOlAM7HnQnPToSDQoEBZqzu/YBlqDnEeymPnZDREeXJA3KBMQee+dKteAxZ2AtvQEvVYdZf241Q=="],
|
"baseline-browser-mapping": ["baseline-browser-mapping@2.10.10", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-sUoJ3IMxx4AyRqO4MLeHlnGDkyXRoUG0/AI9fjK+vS72ekpV0yWVY7O0BVjmBcRtkNcsAO2QDZ4tdKKGoI6YaQ=="],
|
||||||
|
|
||||||
"brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
|
"brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
|
||||||
|
|
||||||
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
|
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
|
||||||
|
|
||||||
"browserslist": ["browserslist@4.27.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.19", "caniuse-lite": "^1.0.30001751", "electron-to-chromium": "^1.5.238", "node-releases": "^2.0.26", "update-browserslist-db": "^1.1.4" }, "bin": { "browserslist": "cli.js" } }, "sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw=="],
|
"browserslist": ["browserslist@4.28.1", "", { "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" } }, "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA=="],
|
||||||
|
|
||||||
"call-bind": ["call-bind@1.0.8", "", { "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": ["call-bind@1.0.8", "", { "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=="],
|
||||||
|
|
||||||
@@ -403,7 +412,7 @@
|
|||||||
|
|
||||||
"callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
|
"callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
|
||||||
|
|
||||||
"caniuse-lite": ["caniuse-lite@1.0.30001751", "", {}, "sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw=="],
|
"caniuse-lite": ["caniuse-lite@1.0.30001781", "", {}, "sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw=="],
|
||||||
|
|
||||||
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
||||||
|
|
||||||
@@ -413,8 +422,6 @@
|
|||||||
|
|
||||||
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
||||||
|
|
||||||
"combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="],
|
|
||||||
|
|
||||||
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
|
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
|
||||||
|
|
||||||
"convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="],
|
"convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="],
|
||||||
@@ -423,7 +430,7 @@
|
|||||||
|
|
||||||
"crypto-js": ["crypto-js@4.2.0", "", {}, "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="],
|
"crypto-js": ["crypto-js@4.2.0", "", {}, "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="],
|
||||||
|
|
||||||
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
"csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
|
||||||
|
|
||||||
"damerau-levenshtein": ["damerau-levenshtein@1.0.8", "", {}, "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA=="],
|
"damerau-levenshtein": ["damerau-levenshtein@1.0.8", "", {}, "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA=="],
|
||||||
|
|
||||||
@@ -433,8 +440,6 @@
|
|||||||
|
|
||||||
"data-view-byte-offset": ["data-view-byte-offset@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-data-view": "^1.0.1" } }, "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ=="],
|
"data-view-byte-offset": ["data-view-byte-offset@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-data-view": "^1.0.1" } }, "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ=="],
|
||||||
|
|
||||||
"date-fns": ["date-fns@4.1.0", "", {}, "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg=="],
|
|
||||||
|
|
||||||
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
||||||
|
|
||||||
"deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
|
"deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
|
||||||
@@ -443,27 +448,25 @@
|
|||||||
|
|
||||||
"define-properties": ["define-properties@1.2.1", "", { "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg=="],
|
"define-properties": ["define-properties@1.2.1", "", { "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg=="],
|
||||||
|
|
||||||
"delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="],
|
|
||||||
|
|
||||||
"detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
|
"detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
|
||||||
|
|
||||||
"doctrine": ["doctrine@2.1.0", "", { "dependencies": { "esutils": "^2.0.2" } }, "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw=="],
|
"doctrine": ["doctrine@2.1.0", "", { "dependencies": { "esutils": "^2.0.2" } }, "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw=="],
|
||||||
|
|
||||||
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
|
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
|
||||||
|
|
||||||
"electron-to-chromium": ["electron-to-chromium@1.5.244", "", {}, "sha512-OszpBN7xZX4vWMPJwB9illkN/znA8M36GQqQxi6MNy9axWxhOfJyZZJtSLQCpEFLHP2xK33BiWx9aIuIEXVCcw=="],
|
"electron-to-chromium": ["electron-to-chromium@1.5.322", "", {}, "sha512-vFU34OcrvMcH66T+dYC3G4nURmgfDVewMIu6Q2urXpumAPSMmzvcn04KVVV8Opikq8Vs5nUbO/8laNhNRqSzYw=="],
|
||||||
|
|
||||||
"emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
|
"emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
|
||||||
|
|
||||||
"enhanced-resolve": ["enhanced-resolve@5.18.3", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww=="],
|
"enhanced-resolve": ["enhanced-resolve@5.20.1", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.0" } }, "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA=="],
|
||||||
|
|
||||||
"es-abstract": ["es-abstract@1.24.0", "", { "dependencies": { "array-buffer-byte-length": "^1.0.2", "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "data-view-buffer": "^1.0.2", "data-view-byte-length": "^1.0.2", "data-view-byte-offset": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "es-set-tostringtag": "^2.1.0", "es-to-primitive": "^1.3.0", "function.prototype.name": "^1.1.8", "get-intrinsic": "^1.3.0", "get-proto": "^1.0.1", "get-symbol-description": "^1.1.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "internal-slot": "^1.1.0", "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", "is-data-view": "^1.0.2", "is-negative-zero": "^2.0.3", "is-regex": "^1.2.1", "is-set": "^2.0.3", "is-shared-array-buffer": "^1.0.4", "is-string": "^1.1.1", "is-typed-array": "^1.1.15", "is-weakref": "^1.1.1", "math-intrinsics": "^1.1.0", "object-inspect": "^1.13.4", "object-keys": "^1.1.1", "object.assign": "^4.1.7", "own-keys": "^1.0.1", "regexp.prototype.flags": "^1.5.4", "safe-array-concat": "^1.1.3", "safe-push-apply": "^1.0.0", "safe-regex-test": "^1.1.0", "set-proto": "^1.0.0", "stop-iteration-iterator": "^1.1.0", "string.prototype.trim": "^1.2.10", "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", "typed-array-buffer": "^1.0.3", "typed-array-byte-length": "^1.0.3", "typed-array-byte-offset": "^1.0.4", "typed-array-length": "^1.0.7", "unbox-primitive": "^1.1.0", "which-typed-array": "^1.1.19" } }, "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg=="],
|
"es-abstract": ["es-abstract@1.24.1", "", { "dependencies": { "array-buffer-byte-length": "^1.0.2", "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "data-view-buffer": "^1.0.2", "data-view-byte-length": "^1.0.2", "data-view-byte-offset": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "es-set-tostringtag": "^2.1.0", "es-to-primitive": "^1.3.0", "function.prototype.name": "^1.1.8", "get-intrinsic": "^1.3.0", "get-proto": "^1.0.1", "get-symbol-description": "^1.1.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "internal-slot": "^1.1.0", "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", "is-data-view": "^1.0.2", "is-negative-zero": "^2.0.3", "is-regex": "^1.2.1", "is-set": "^2.0.3", "is-shared-array-buffer": "^1.0.4", "is-string": "^1.1.1", "is-typed-array": "^1.1.15", "is-weakref": "^1.1.1", "math-intrinsics": "^1.1.0", "object-inspect": "^1.13.4", "object-keys": "^1.1.1", "object.assign": "^4.1.7", "own-keys": "^1.0.1", "regexp.prototype.flags": "^1.5.4", "safe-array-concat": "^1.1.3", "safe-push-apply": "^1.0.0", "safe-regex-test": "^1.1.0", "set-proto": "^1.0.0", "stop-iteration-iterator": "^1.1.0", "string.prototype.trim": "^1.2.10", "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", "typed-array-buffer": "^1.0.3", "typed-array-byte-length": "^1.0.3", "typed-array-byte-offset": "^1.0.4", "typed-array-length": "^1.0.7", "unbox-primitive": "^1.1.0", "which-typed-array": "^1.1.19" } }, "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw=="],
|
||||||
|
|
||||||
"es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
|
"es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
|
||||||
|
|
||||||
"es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
|
"es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
|
||||||
|
|
||||||
"es-iterator-helpers": ["es-iterator-helpers@1.2.1", "", { "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-set-tostringtag": "^2.0.3", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.6", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "internal-slot": "^1.1.0", "iterator.prototype": "^1.1.4", "safe-array-concat": "^1.1.3" } }, "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w=="],
|
"es-iterator-helpers": ["es-iterator-helpers@1.3.1", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.4", "define-properties": "^1.2.1", "es-abstract": "^1.24.1", "es-errors": "^1.3.0", "es-set-tostringtag": "^2.1.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.3.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "internal-slot": "^1.1.0", "iterator.prototype": "^1.1.5", "math-intrinsics": "^1.1.0", "safe-array-concat": "^1.1.3" } }, "sha512-zWwRvqWiuBPr0muUG/78cW3aHROFCNIQ3zpmYDpwdbnt2m+xlNyRWpHBpa2lJjSBit7BQ+RXA1iwbSmu5yJ/EQ=="],
|
||||||
|
|
||||||
"es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
|
"es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
|
||||||
|
|
||||||
@@ -477,9 +480,9 @@
|
|||||||
|
|
||||||
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
|
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
|
||||||
|
|
||||||
"eslint": ["eslint@9.39.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.1", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.39.0", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-iy2GE3MHrYTL5lrCtMZ0X1KLEKKUjmK0kzwcnefhR66txcEmXZD2YWgR5GNdcEwkNx3a0siYkSvl0vIC+Svjmg=="],
|
"eslint": ["eslint@9.39.4", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.2", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.5", "@eslint/js": "9.39.4", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.14.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.5", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ=="],
|
||||||
|
|
||||||
"eslint-config-next": ["eslint-config-next@16.0.1", "", { "dependencies": { "@next/eslint-plugin-next": "16.0.1", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^3.5.2", "eslint-plugin-import": "^2.32.0", "eslint-plugin-jsx-a11y": "^6.10.0", "eslint-plugin-react": "^7.37.0", "eslint-plugin-react-hooks": "^7.0.0", "globals": "16.4.0", "typescript-eslint": "^8.46.0" }, "peerDependencies": { "eslint": ">=9.0.0", "typescript": ">=3.3.1" }, "optionalPeers": ["typescript"] }, "sha512-wNuHw5gNOxwLUvpg0cu6IL0crrVC9hAwdS/7UwleNkwyaMiWIOAwf8yzXVqBBzL3c9A7jVRngJxjoSpPP1aEhg=="],
|
"eslint-config-next": ["eslint-config-next@16.2.1", "", { "dependencies": { "@next/eslint-plugin-next": "16.2.1", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^3.5.2", "eslint-plugin-import": "^2.32.0", "eslint-plugin-jsx-a11y": "^6.10.0", "eslint-plugin-react": "^7.37.0", "eslint-plugin-react-hooks": "^7.0.0", "globals": "16.4.0", "typescript-eslint": "^8.46.0" }, "peerDependencies": { "eslint": ">=9.0.0", "typescript": ">=3.3.1" }, "optionalPeers": ["typescript"] }, "sha512-qhabwjQZ1Mk53XzXvmogf8KQ0tG0CQXF0CZ56+2/lVhmObgmaqj7x5A1DSrWdZd3kwI7GTPGUjFne+krRxYmFg=="],
|
||||||
|
|
||||||
"eslint-import-resolver-node": ["eslint-import-resolver-node@0.3.9", "", { "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", "resolve": "^1.22.4" } }, "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g=="],
|
"eslint-import-resolver-node": ["eslint-import-resolver-node@0.3.9", "", { "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", "resolve": "^1.22.4" } }, "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g=="],
|
||||||
|
|
||||||
@@ -501,7 +504,7 @@
|
|||||||
|
|
||||||
"espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="],
|
"espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="],
|
||||||
|
|
||||||
"esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="],
|
"esquery": ["esquery@1.7.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g=="],
|
||||||
|
|
||||||
"esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="],
|
"esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="],
|
||||||
|
|
||||||
@@ -517,7 +520,7 @@
|
|||||||
|
|
||||||
"fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="],
|
"fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="],
|
||||||
|
|
||||||
"fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="],
|
"fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="],
|
||||||
|
|
||||||
"fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
|
"fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
|
||||||
|
|
||||||
@@ -529,14 +532,10 @@
|
|||||||
|
|
||||||
"flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="],
|
"flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="],
|
||||||
|
|
||||||
"flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="],
|
"flatted": ["flatted@3.4.2", "", {}, "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA=="],
|
||||||
|
|
||||||
"follow-redirects": ["follow-redirects@1.15.11", "", {}, "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ=="],
|
|
||||||
|
|
||||||
"for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="],
|
"for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="],
|
||||||
|
|
||||||
"form-data": ["form-data@4.0.4", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow=="],
|
|
||||||
|
|
||||||
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
||||||
|
|
||||||
"function.prototype.name": ["function.prototype.name@1.1.8", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "functions-have-names": "^1.2.3", "hasown": "^2.0.2", "is-callable": "^1.2.7" } }, "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q=="],
|
"function.prototype.name": ["function.prototype.name@1.1.8", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "functions-have-names": "^1.2.3", "hasown": "^2.0.2", "is-callable": "^1.2.7" } }, "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q=="],
|
||||||
@@ -553,7 +552,7 @@
|
|||||||
|
|
||||||
"get-symbol-description": ["get-symbol-description@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6" } }, "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg=="],
|
"get-symbol-description": ["get-symbol-description@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6" } }, "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg=="],
|
||||||
|
|
||||||
"get-tsconfig": ["get-tsconfig@4.13.0", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ=="],
|
"get-tsconfig": ["get-tsconfig@4.13.7", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q=="],
|
||||||
|
|
||||||
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
|
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
|
||||||
|
|
||||||
@@ -565,8 +564,6 @@
|
|||||||
|
|
||||||
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
|
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
|
||||||
|
|
||||||
"graphemer": ["graphemer@1.4.0", "", {}, "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="],
|
|
||||||
|
|
||||||
"has-bigints": ["has-bigints@1.1.0", "", {}, "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg=="],
|
"has-bigints": ["has-bigints@1.1.0", "", {}, "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg=="],
|
||||||
|
|
||||||
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
|
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
|
||||||
@@ -655,7 +652,7 @@
|
|||||||
|
|
||||||
"js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
|
"js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
|
||||||
|
|
||||||
"js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="],
|
"js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="],
|
||||||
|
|
||||||
"jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="],
|
"jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="],
|
||||||
|
|
||||||
@@ -677,29 +674,29 @@
|
|||||||
|
|
||||||
"levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
|
"levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
|
||||||
|
|
||||||
"lightningcss": ["lightningcss@1.30.2", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.30.2", "lightningcss-darwin-arm64": "1.30.2", "lightningcss-darwin-x64": "1.30.2", "lightningcss-freebsd-x64": "1.30.2", "lightningcss-linux-arm-gnueabihf": "1.30.2", "lightningcss-linux-arm64-gnu": "1.30.2", "lightningcss-linux-arm64-musl": "1.30.2", "lightningcss-linux-x64-gnu": "1.30.2", "lightningcss-linux-x64-musl": "1.30.2", "lightningcss-win32-arm64-msvc": "1.30.2", "lightningcss-win32-x64-msvc": "1.30.2" } }, "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ=="],
|
"lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="],
|
||||||
|
|
||||||
"lightningcss-android-arm64": ["lightningcss-android-arm64@1.30.2", "", { "os": "android", "cpu": "arm64" }, "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A=="],
|
"lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="],
|
||||||
|
|
||||||
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA=="],
|
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="],
|
||||||
|
|
||||||
"lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ=="],
|
"lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.32.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w=="],
|
||||||
|
|
||||||
"lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA=="],
|
"lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.32.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig=="],
|
||||||
|
|
||||||
"lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.2", "", { "os": "linux", "cpu": "arm" }, "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA=="],
|
"lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.32.0", "", { "os": "linux", "cpu": "arm" }, "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw=="],
|
||||||
|
|
||||||
"lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A=="],
|
"lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ=="],
|
||||||
|
|
||||||
"lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA=="],
|
"lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg=="],
|
||||||
|
|
||||||
"lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w=="],
|
"lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA=="],
|
||||||
|
|
||||||
"lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA=="],
|
"lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg=="],
|
||||||
|
|
||||||
"lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ=="],
|
"lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.32.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw=="],
|
||||||
|
|
||||||
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.2", "", { "os": "win32", "cpu": "x64" }, "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw=="],
|
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="],
|
||||||
|
|
||||||
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
|
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
|
||||||
|
|
||||||
@@ -717,11 +714,7 @@
|
|||||||
|
|
||||||
"micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
|
"micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
|
||||||
|
|
||||||
"mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
|
"minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="],
|
||||||
|
|
||||||
"mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
|
|
||||||
|
|
||||||
"minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
|
|
||||||
|
|
||||||
"minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
|
"minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
|
||||||
|
|
||||||
@@ -733,9 +726,11 @@
|
|||||||
|
|
||||||
"natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
|
"natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
|
||||||
|
|
||||||
"next": ["next@16.0.1", "", { "dependencies": { "@next/env": "16.0.1", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.0.1", "@next/swc-darwin-x64": "16.0.1", "@next/swc-linux-arm64-gnu": "16.0.1", "@next/swc-linux-arm64-musl": "16.0.1", "@next/swc-linux-x64-gnu": "16.0.1", "@next/swc-linux-x64-musl": "16.0.1", "@next/swc-win32-arm64-msvc": "16.0.1", "@next/swc-win32-x64-msvc": "16.0.1", "sharp": "^0.34.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-e9RLSssZwd35p7/vOa+hoDFggUZIUbZhIUSLZuETCwrCVvxOs87NamoUzT+vbcNAL8Ld9GobBnWOA6SbV/arOw=="],
|
"next": ["next@16.2.1", "", { "dependencies": { "@next/env": "16.2.1", "@swc/helpers": "0.5.15", "baseline-browser-mapping": "^2.9.19", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.2.1", "@next/swc-darwin-x64": "16.2.1", "@next/swc-linux-arm64-gnu": "16.2.1", "@next/swc-linux-arm64-musl": "16.2.1", "@next/swc-linux-x64-gnu": "16.2.1", "@next/swc-linux-x64-musl": "16.2.1", "@next/swc-win32-arm64-msvc": "16.2.1", "@next/swc-win32-x64-msvc": "16.2.1", "sharp": "^0.34.5" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-VaChzNL7o9rbfdt60HUj8tev4m6d7iC1igAy157526+cJlXOQu5LzsBXNT+xaJnTP/k+utSX5vMv7m0G+zKH+Q=="],
|
||||||
|
|
||||||
"node-releases": ["node-releases@2.0.27", "", {}, "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="],
|
"node-exports-info": ["node-exports-info@1.6.0", "", { "dependencies": { "array.prototype.flatmap": "^1.3.3", "es-errors": "^1.3.0", "object.entries": "^1.1.9", "semver": "^6.3.1" } }, "sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw=="],
|
||||||
|
|
||||||
|
"node-releases": ["node-releases@2.0.36", "", {}, "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA=="],
|
||||||
|
|
||||||
"object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
|
"object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
|
||||||
|
|
||||||
@@ -771,25 +766,25 @@
|
|||||||
|
|
||||||
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
||||||
|
|
||||||
"picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
|
"picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="],
|
||||||
|
|
||||||
"possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="],
|
"possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="],
|
||||||
|
|
||||||
"postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
|
"postcss": ["postcss@8.5.8", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg=="],
|
||||||
|
|
||||||
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
|
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
|
||||||
|
|
||||||
"prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="],
|
"pretty-bytes": ["pretty-bytes@7.1.0", "", {}, "sha512-nODzvTiYVRGRqAOvE84Vk5JDPyyxsVk0/fbA/bq7RqlnhksGpset09XTxbpvLTIjoaF7K8Z8DG8yHtKGTPSYRw=="],
|
||||||
|
|
||||||
"proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="],
|
"prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="],
|
||||||
|
|
||||||
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
||||||
|
|
||||||
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
|
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
|
||||||
|
|
||||||
"react": ["react@19.2.0", "", {}, "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ=="],
|
"react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="],
|
||||||
|
|
||||||
"react-dom": ["react-dom@19.2.0", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.0" } }, "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ=="],
|
"react-dom": ["react-dom@19.2.4", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="],
|
||||||
|
|
||||||
"react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="],
|
"react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="],
|
||||||
|
|
||||||
@@ -823,7 +818,7 @@
|
|||||||
|
|
||||||
"set-proto": ["set-proto@1.0.0", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0" } }, "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw=="],
|
"set-proto": ["set-proto@1.0.0", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0" } }, "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw=="],
|
||||||
|
|
||||||
"sharp": ["sharp@0.34.4", "", { "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=="],
|
"sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="],
|
||||||
|
|
||||||
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
|
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
|
||||||
|
|
||||||
@@ -865,15 +860,15 @@
|
|||||||
|
|
||||||
"supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
|
"supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
|
||||||
|
|
||||||
"tailwindcss": ["tailwindcss@4.1.16", "", {}, "sha512-pONL5awpaQX4LN5eiv7moSiSPd/DLDzKVRJz8Q9PgzmAdd1R4307GQS2ZpfiN7ZmekdQrfhZZiSE5jkLR4WNaA=="],
|
"tailwindcss": ["tailwindcss@4.2.2", "", {}, "sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q=="],
|
||||||
|
|
||||||
"tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="],
|
"tapable": ["tapable@2.3.2", "", {}, "sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA=="],
|
||||||
|
|
||||||
"tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="],
|
"tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="],
|
||||||
|
|
||||||
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
|
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
|
||||||
|
|
||||||
"ts-api-utils": ["ts-api-utils@2.1.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ=="],
|
"ts-api-utils": ["ts-api-utils@2.5.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA=="],
|
||||||
|
|
||||||
"tsconfig-paths": ["tsconfig-paths@3.15.0", "", { "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg=="],
|
"tsconfig-paths": ["tsconfig-paths@3.15.0", "", { "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg=="],
|
||||||
|
|
||||||
@@ -891,15 +886,15 @@
|
|||||||
|
|
||||||
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
||||||
|
|
||||||
"typescript-eslint": ["typescript-eslint@8.46.2", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.46.2", "@typescript-eslint/parser": "8.46.2", "@typescript-eslint/typescript-estree": "8.46.2", "@typescript-eslint/utils": "8.46.2" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-vbw8bOmiuYNdzzV3lsiWv6sRwjyuKJMQqWulBOU7M0RrxedXledX8G8kBbQeiOYDnTfiXz0Y4081E1QMNB6iQg=="],
|
"typescript-eslint": ["typescript-eslint@8.57.2", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.57.2", "@typescript-eslint/parser": "8.57.2", "@typescript-eslint/typescript-estree": "8.57.2", "@typescript-eslint/utils": "8.57.2" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-VEPQ0iPgWO/sBaZOU1xo4nuNdODVOajPnTIbog2GKYr31nIlZ0fWPoCQgGfF3ETyBl1vn63F/p50Um9Z4J8O8A=="],
|
||||||
|
|
||||||
"unbox-primitive": ["unbox-primitive@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "has-bigints": "^1.0.2", "has-symbols": "^1.1.0", "which-boxed-primitive": "^1.1.1" } }, "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw=="],
|
"unbox-primitive": ["unbox-primitive@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "has-bigints": "^1.0.2", "has-symbols": "^1.1.0", "which-boxed-primitive": "^1.1.1" } }, "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw=="],
|
||||||
|
|
||||||
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
|
"undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="],
|
||||||
|
|
||||||
"unrs-resolver": ["unrs-resolver@1.11.1", "", { "dependencies": { "napi-postinstall": "^0.3.0" }, "optionalDependencies": { "@unrs/resolver-binding-android-arm-eabi": "1.11.1", "@unrs/resolver-binding-android-arm64": "1.11.1", "@unrs/resolver-binding-darwin-arm64": "1.11.1", "@unrs/resolver-binding-darwin-x64": "1.11.1", "@unrs/resolver-binding-freebsd-x64": "1.11.1", "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", "@unrs/resolver-binding-linux-x64-musl": "1.11.1", "@unrs/resolver-binding-wasm32-wasi": "1.11.1", "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" } }, "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg=="],
|
"unrs-resolver": ["unrs-resolver@1.11.1", "", { "dependencies": { "napi-postinstall": "^0.3.0" }, "optionalDependencies": { "@unrs/resolver-binding-android-arm-eabi": "1.11.1", "@unrs/resolver-binding-android-arm64": "1.11.1", "@unrs/resolver-binding-darwin-arm64": "1.11.1", "@unrs/resolver-binding-darwin-x64": "1.11.1", "@unrs/resolver-binding-freebsd-x64": "1.11.1", "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", "@unrs/resolver-binding-linux-x64-musl": "1.11.1", "@unrs/resolver-binding-wasm32-wasi": "1.11.1", "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" } }, "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg=="],
|
||||||
|
|
||||||
"update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
|
"update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="],
|
||||||
|
|
||||||
"uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
|
"uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
|
||||||
|
|
||||||
@@ -911,7 +906,7 @@
|
|||||||
|
|
||||||
"which-collection": ["which-collection@1.0.2", "", { "dependencies": { "is-map": "^2.0.3", "is-set": "^2.0.3", "is-weakmap": "^2.0.2", "is-weakset": "^2.0.3" } }, "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw=="],
|
"which-collection": ["which-collection@1.0.2", "", { "dependencies": { "is-map": "^2.0.3", "is-set": "^2.0.3", "is-weakmap": "^2.0.2", "is-weakset": "^2.0.3" } }, "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw=="],
|
||||||
|
|
||||||
"which-typed-array": ["which-typed-array@1.1.19", "", { "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "for-each": "^0.3.5", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" } }, "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw=="],
|
"which-typed-array": ["which-typed-array@1.1.20", "", { "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "for-each": "^0.3.5", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" } }, "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg=="],
|
||||||
|
|
||||||
"word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
|
"word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
|
||||||
|
|
||||||
@@ -919,7 +914,7 @@
|
|||||||
|
|
||||||
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
|
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
|
||||||
|
|
||||||
"zod": ["zod@4.1.12", "", {}, "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ=="],
|
"zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="],
|
||||||
|
|
||||||
"zod-validation-error": ["zod-validation-error@4.0.2", "", { "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" } }, "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ=="],
|
"zod-validation-error": ["zod-validation-error@4.0.2", "", { "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" } }, "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ=="],
|
||||||
|
|
||||||
@@ -927,13 +922,13 @@
|
|||||||
|
|
||||||
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
|
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.6.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-zq/ay+9fNIJJtJiZxdTnXS20PllcYMX3OE23ESc4HK/bdYu3cOWYVhsOhVnXALfU/uqJIxn5NBPd9z4v+SfoSg=="],
|
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.9.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.6.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-obtUmAHTMjll499P+D9A3axeJFlhdjOWdKUNs/U6QIGT7V5RjcUW1xToAzjvmgTSQhDbYn/NwfTRoJcQ2rNBxA=="],
|
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.9.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="],
|
"@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.0.7", "", { "dependencies": { "@emnapi/core": "^1.5.0", "@emnapi/runtime": "^1.5.0", "@tybys/wasm-util": "^0.10.1" }, "bundled": true }, "sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw=="],
|
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.1", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" }, "bundled": true }, "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A=="],
|
||||||
|
|
||||||
"@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
|
"@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
|
||||||
|
|
||||||
@@ -941,11 +936,11 @@
|
|||||||
|
|
||||||
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
|
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree/fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="],
|
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="],
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
"@typescript-eslint/typescript-estree/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
|
"@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="],
|
||||||
|
|
||||||
"eslint-config-next/globals": ["globals@16.4.0", "", {}, "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw=="],
|
"eslint-config-next/globals": ["globals@16.4.0", "", {}, "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw=="],
|
||||||
|
|
||||||
@@ -955,20 +950,20 @@
|
|||||||
|
|
||||||
"eslint-plugin-import/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
|
"eslint-plugin-import/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
|
||||||
|
|
||||||
"eslint-plugin-react/resolve": ["resolve@2.0.0-next.5", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA=="],
|
"eslint-plugin-react/resolve": ["resolve@2.0.0-next.6", "", { "dependencies": { "es-errors": "^1.3.0", "is-core-module": "^2.16.1", "node-exports-info": "^1.6.0", "object-keys": "^1.1.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA=="],
|
||||||
|
|
||||||
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
||||||
|
|
||||||
"is-bun-module/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
|
"is-bun-module/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
|
||||||
|
|
||||||
"micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
"micromatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="],
|
||||||
|
|
||||||
"next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
|
"next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
|
||||||
|
|
||||||
"sharp/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
|
"sharp/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree/fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@5.0.5", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ=="],
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
|
"@typescript-eslint/typescript-estree/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,7 +11,8 @@ const eslintConfig = defineConfig([
|
|||||||
'.next/**',
|
'.next/**',
|
||||||
'out/**',
|
'out/**',
|
||||||
'build/**',
|
'build/**',
|
||||||
'next-env.d.ts'
|
'next-env.d.ts',
|
||||||
|
'src-tauri/**'
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "lncvrt-games-launcher",
|
"name": "lncvrt-games-launcher",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.0.0",
|
"version": "1.8.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
@@ -11,34 +11,36 @@
|
|||||||
"tauri": "tauri"
|
"tauri": "tauri"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tauri-apps/api": "2.9.0",
|
"@fortawesome/fontawesome-svg-core": "7.2.0",
|
||||||
"@tauri-apps/plugin-dialog": "2.4.2",
|
"@fortawesome/free-brands-svg-icons": "7.2.0",
|
||||||
"@tauri-apps/plugin-fs": "2.4.4",
|
"@fortawesome/free-solid-svg-icons": "7.2.0",
|
||||||
|
"@fortawesome/react-fontawesome": "3.3.0",
|
||||||
|
"@tauri-apps/api": "2.10.1",
|
||||||
|
"@tauri-apps/plugin-clipboard-manager": "2.3.2",
|
||||||
|
"@tauri-apps/plugin-dialog": "2.6.0",
|
||||||
|
"@tauri-apps/plugin-fs": "2.4.5",
|
||||||
|
"@tauri-apps/plugin-http": "2.5.7",
|
||||||
"@tauri-apps/plugin-notification": "2.3.3",
|
"@tauri-apps/plugin-notification": "2.3.3",
|
||||||
"@tauri-apps/plugin-opener": "2.5.2",
|
"@tauri-apps/plugin-opener": "2.5.3",
|
||||||
"@tauri-apps/plugin-os": "2.3.2",
|
"@tauri-apps/plugin-os": "2.3.2",
|
||||||
"axios": "1.13.1",
|
"@tauri-apps/plugin-window-state": "2.4.1",
|
||||||
"date-fns": "4.1.0",
|
"next": "16.2.1",
|
||||||
"react": "19.2.0",
|
"pretty-bytes": "7.1.0",
|
||||||
"react-dom": "19.2.0",
|
"react": "19.2.4",
|
||||||
"next": "16.0.1",
|
"react-dom": "19.2.4"
|
||||||
"@fortawesome/fontawesome-svg-core": "7.1.0",
|
|
||||||
"@fortawesome/free-brands-svg-icons": "7.1.0",
|
|
||||||
"@fortawesome/free-solid-svg-icons": "7.1.0",
|
|
||||||
"@fortawesome/react-fontawesome": "3.1.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tailwindcss/postcss": "4.1.16",
|
"@eslint/eslintrc": "3.3.5",
|
||||||
"@tauri-apps/cli": "2.9.2",
|
"@tailwindcss/postcss": "4.2.2",
|
||||||
|
"@tauri-apps/cli": "2.10.1",
|
||||||
"@types/crypto-js": "4.2.2",
|
"@types/crypto-js": "4.2.2",
|
||||||
"@types/react": "19.2.2",
|
"@types/node": "25.5.0",
|
||||||
"@types/react-dom": "19.2.2",
|
"@types/react": "19.2.14",
|
||||||
|
"@types/react-dom": "19.2.3",
|
||||||
"crypto-js": "4.2.0",
|
"crypto-js": "4.2.0",
|
||||||
"@types/node": "24.9.2",
|
"eslint": "9.39.4",
|
||||||
"tailwindcss": "4.1.16",
|
"eslint-config-next": "16.2.1",
|
||||||
"typescript": "5.9.3",
|
"tailwindcss": "4.2.2",
|
||||||
"eslint": "9.39.0",
|
"typescript": "5.9.3"
|
||||||
"eslint-config-next": "16.0.1",
|
|
||||||
"@eslint/eslintrc": "3.3.1"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "lncvrt-games-launcher"
|
name = "lncvrt-games-launcher"
|
||||||
version = "1.1.0"
|
version = "1.8.0"
|
||||||
authors = ["Lncvrt"]
|
authors = ["Lncvrt"]
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
@@ -9,29 +9,34 @@ name = "lncvrt_games_launcher_lib"
|
|||||||
crate-type = ["staticlib", "cdylib", "rlib"]
|
crate-type = ["staticlib", "cdylib", "rlib"]
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
tauri-build = { version = "2.5.1", features = [] }
|
tauri-build = { version = "2.5.6", features = [] }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tauri = { version = "2.9.2", features = ["macos-private-api"] }
|
tauri = { version = "2.10.3", features = ["macos-private-api"] }
|
||||||
tauri-plugin-opener = "2.5.2"
|
tauri-plugin-opener = "2.5.3"
|
||||||
serde = { version = "1.0.228", features = ["derive"] }
|
serde = { version = "1.0.228", features = ["derive"] }
|
||||||
serde_json = "1.0.145"
|
serde_json = "1.0.149"
|
||||||
tauri-plugin-os = "2.3.2"
|
tauri-plugin-os = "2.3.2"
|
||||||
reqwest = { version = "0.12.24", default-features = false, features = ["stream", "rustls-tls"] }
|
reqwest = { version = "0.13.2", default-features = false, features = ["stream", "rustls"] }
|
||||||
tokio = "1.48.0"
|
tokio = "1.50.0"
|
||||||
futures-util = { version = "0.3.31", features = ["io"] }
|
futures-util = { version = "0.3.32", features = ["io"] }
|
||||||
tauri-plugin-decorum = "1.1.1"
|
tauri-plugin-decorum = "1.1.1"
|
||||||
tauri-plugin-fs = "2.4.4"
|
tauri-plugin-fs = "2.4.5"
|
||||||
zip = "6.0.0"
|
zip = "8.4.0"
|
||||||
libc = "0.2.177"
|
tauri-plugin-dialog = "2.6.0"
|
||||||
tauri-plugin-dialog = "2.4.2"
|
|
||||||
tauri-plugin-notification = "2.3.3"
|
tauri-plugin-notification = "2.3.3"
|
||||||
sysinfo = "0.37.2"
|
sysinfo = "0.38.4"
|
||||||
|
sha2 = "0.10.9"
|
||||||
[target.'cfg(target_os = "linux")'.dependencies]
|
tauri-plugin-clipboard-manager = "2.3.2"
|
||||||
shlex = "1.3.0"
|
tauri-plugin-prevent-default = "4.0.4"
|
||||||
|
openssl = { version = "0.10.76", features = ["v110", "vendored"] }
|
||||||
|
base64 = "0.22.1"
|
||||||
|
tauri-plugin-http = "2.5.7"
|
||||||
|
dashmap = "6.1.0"
|
||||||
|
|
||||||
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
||||||
tauri-plugin-single-instance = "2.3.6"
|
tauri-plugin-single-instance = "2.4.0"
|
||||||
|
tauri-plugin-window-state = "2.4.1"
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
|
tauri-plugin-decorum = "1.1.1"
|
||||||
@@ -19,11 +19,40 @@
|
|||||||
"core:window:allow-is-maximized",
|
"core:window:allow-is-maximized",
|
||||||
"core:window:allow-start-dragging",
|
"core:window:allow-start-dragging",
|
||||||
"core:window:allow-toggle-maximize",
|
"core:window:allow-toggle-maximize",
|
||||||
|
"core:window:allow-request-user-attention",
|
||||||
"decorum:allow-show-snap-overlay",
|
"decorum:allow-show-snap-overlay",
|
||||||
"fs:default",
|
"fs:default",
|
||||||
|
"dialog:default",
|
||||||
|
"notification:default",
|
||||||
|
"clipboard-manager:default",
|
||||||
|
"clipboard-manager:allow-write-text",
|
||||||
"fs:allow-applocaldata-read",
|
"fs:allow-applocaldata-read",
|
||||||
"fs:allow-applocaldata-write",
|
"fs:allow-applocaldata-write",
|
||||||
"dialog:default",
|
{
|
||||||
"notification:default"
|
"identifier": "fs:scope",
|
||||||
|
"allow": [
|
||||||
|
{ "path": "$APPLOCALDATA/game/**" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identifier": "opener:allow-open-path",
|
||||||
|
"allow": [
|
||||||
|
{ "path": "$APPLOCALDATA/game/**" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identifier": "http:default",
|
||||||
|
"allow": [
|
||||||
|
{ "url": "https://games.lncvrt.xyz/api/launcher/latest" },
|
||||||
|
{ "url": "https://games.lncvrt.xyz/api/launcher/versions" },
|
||||||
|
{ "url": "https://games.lncvrt.xyz/api/launcher/download" },
|
||||||
|
{ "url": "https://games.lncvrt.xyz/api/berrydash/account" },
|
||||||
|
{ "url": "https://games.lncvrt.xyz/api/berrydash/leaderboard/score" },
|
||||||
|
{ "url": "https://games.lncvrt.xyz/api/berrydash/leaderboard/berry" },
|
||||||
|
{ "url": "https://games.lncvrt.xyz/api/berrydash/leaderboard/coin" },
|
||||||
|
{ "url": "https://games.lncvrt.xyz/api/berrydash/leaderboard/legacy" },
|
||||||
|
{ "url": "https://games.lncvrt.xyz/api/berrydash/leaderboard/total" }
|
||||||
|
]
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"identifier": "desktop-capability",
|
||||||
|
"platforms": [
|
||||||
|
"macOS",
|
||||||
|
"windows",
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"windows": [
|
||||||
|
"main"
|
||||||
|
],
|
||||||
|
"permissions": [
|
||||||
|
"window-state:default"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 249 KiB After Width: | Height: | Size: 248 KiB |
@@ -1,4 +1,13 @@
|
|||||||
|
use base64::{Engine as _, engine::general_purpose};
|
||||||
|
use dashmap::DashMap;
|
||||||
use futures_util::stream::StreamExt;
|
use futures_util::stream::StreamExt;
|
||||||
|
use openssl::pkey::PKey;
|
||||||
|
use openssl::sign::Verifier;
|
||||||
|
use sha2::{Digest, Sha512};
|
||||||
|
use std::fs;
|
||||||
|
use std::path::Path;
|
||||||
|
use std::sync::OnceLock;
|
||||||
|
use std::time::Instant;
|
||||||
use std::{
|
use std::{
|
||||||
fs::{File, create_dir_all},
|
fs::{File, create_dir_all},
|
||||||
io::{BufReader, copy},
|
io::{BufReader, copy},
|
||||||
@@ -7,47 +16,90 @@ use std::{
|
|||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
use sysinfo::System;
|
use sysinfo::System;
|
||||||
|
use tauri::window::{ProgressBarState, ProgressBarStatus};
|
||||||
use tauri::{AppHandle, Emitter, Manager};
|
use tauri::{AppHandle, Emitter, Manager};
|
||||||
use tauri_plugin_dialog::{DialogExt, MessageDialogKind};
|
|
||||||
use tauri_plugin_opener::OpenerExt;
|
|
||||||
use tauri_plugin_os::platform;
|
use tauri_plugin_os::platform;
|
||||||
|
use tauri_plugin_prevent_default::Flags;
|
||||||
|
use tokio::io::AsyncReadExt;
|
||||||
use tokio::{io::AsyncWriteExt, time::timeout};
|
use tokio::{io::AsyncWriteExt, time::timeout};
|
||||||
use zip::ZipArchive;
|
use zip::ZipArchive;
|
||||||
|
use zip::result::ZipError;
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(unix)]
|
||||||
use std::{fs, os::unix::fs::PermissionsExt};
|
use std::os::unix::fs::PermissionsExt;
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
use tauri_plugin_decorum::WebviewWindowExt;
|
|
||||||
|
|
||||||
fn is_running_by_path(path: &PathBuf) -> bool {
|
static CANCEL_MAP: OnceLock<DashMap<String, bool>> = OnceLock::new();
|
||||||
|
|
||||||
|
fn cancel_map() -> &'static DashMap<String, bool> {
|
||||||
|
CANCEL_MAP.get_or_init(DashMap::new)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_cancelled(name: &str) -> bool {
|
||||||
|
cancel_map().get(name).map(|v| *v).unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_running_by_path(path: &Path) -> bool {
|
||||||
let sys = System::new_all();
|
let sys = System::new_all();
|
||||||
|
let target = match path.canonicalize() {
|
||||||
|
Ok(t) => t,
|
||||||
|
Err(_) => return false,
|
||||||
|
};
|
||||||
sys.processes().values().any(|proc| {
|
sys.processes().values().any(|proc| {
|
||||||
if let Some(exe) = proc.exe() {
|
proc.exe()
|
||||||
exe == path
|
.and_then(|exe| exe.canonicalize().ok())
|
||||||
} else {
|
.map_or(false, |exe| exe == target)
|
||||||
false
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn unzip_to_dir(zip_path: PathBuf, out_dir: PathBuf) -> String {
|
fn should_skip(name: &str) -> bool {
|
||||||
|
name.starts_with("__MACOSX/")
|
||||||
|
|| name == "__MACOSX"
|
||||||
|
|| name.ends_with("/.DS_Store")
|
||||||
|
|| name.ends_with(".DS_Store")
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn unzip_to_dir(app: AppHandle, zip_path: PathBuf, out_dir: PathBuf, name: String) -> String {
|
||||||
|
let _ = app.emit("unzip-start", format!("{}", name));
|
||||||
let res = tauri::async_runtime::spawn_blocking(move || {
|
let res = tauri::async_runtime::spawn_blocking(move || {
|
||||||
let file = File::open(zip_path)?;
|
let file = File::open(zip_path)?;
|
||||||
let mut archive = ZipArchive::new(BufReader::new(file))?;
|
let mut archive = ZipArchive::new(BufReader::new(file))?;
|
||||||
|
let total = archive.len();
|
||||||
|
|
||||||
for i in 0..archive.len() {
|
for i in 0..total {
|
||||||
let mut file = archive.by_index(i)?;
|
let mut entry = archive.by_index(i)?;
|
||||||
let outpath = out_dir.join(file.name());
|
let entry_name = entry.name();
|
||||||
|
|
||||||
if file.is_dir() {
|
if should_skip(entry_name) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let outpath = out_dir.join(entry_name);
|
||||||
|
if !outpath.starts_with(&out_dir) {
|
||||||
|
return Err(ZipError::InvalidArchive("Path traversal detected".into()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if entry.is_dir() {
|
||||||
create_dir_all(&outpath)?;
|
create_dir_all(&outpath)?;
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
if let Some(mode) = entry.unix_mode() {
|
||||||
|
std::fs::set_permissions(&outpath, std::fs::Permissions::from_mode(mode))?;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if let Some(parent) = outpath.parent() {
|
if let Some(parent) = outpath.parent() {
|
||||||
create_dir_all(parent)?;
|
create_dir_all(parent)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut outfile = File::create(&outpath)?;
|
let mut outfile = File::create(&outpath)?;
|
||||||
copy(&mut file, &mut outfile)?;
|
copy(&mut entry, &mut outfile)?;
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
if let Some(mode) = entry.unix_mode() {
|
||||||
|
std::fs::set_permissions(&outpath, std::fs::Permissions::from_mode(mode))?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let _ = app.emit("unzip-progress", format!("{}:{}:{}", name, i + 1, total));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok::<(), zip::result::ZipError>(())
|
Ok::<(), zip::result::ZipError>(())
|
||||||
@@ -60,233 +112,538 @@ async fn unzip_to_dir(zip_path: PathBuf, out_dir: PathBuf) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn download(app: AppHandle, url: String, name: String, executable: String) -> String {
|
fn folder_size(app: AppHandle, version: String) -> String {
|
||||||
let client = reqwest::Client::new();
|
let path = match app.path().app_local_data_dir() {
|
||||||
let resp = match client.get(&url).send().await {
|
Ok(p) => p.join("game").join(&version),
|
||||||
Ok(r) => r,
|
Err(_) => return "-1".to_string(),
|
||||||
Err(_) => {
|
};
|
||||||
|
fn inner(path: &Path) -> u64 {
|
||||||
|
let mut size = 0;
|
||||||
|
if let Ok(entries) = fs::read_dir(path) {
|
||||||
|
for entry in entries.flatten() {
|
||||||
|
if let Ok(metadata) = entry.metadata() {
|
||||||
|
if metadata.is_file() {
|
||||||
|
size += metadata.len();
|
||||||
|
} else if metadata.is_dir() {
|
||||||
|
size += inner(&entry.path());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size
|
||||||
|
}
|
||||||
|
|
||||||
|
let p = Path::new(&path);
|
||||||
|
if p.exists() && p.is_dir() {
|
||||||
|
inner(p).to_string()
|
||||||
|
} else {
|
||||||
|
"-1".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
async fn download(
|
||||||
|
app: AppHandle,
|
||||||
|
url: String,
|
||||||
|
name: String,
|
||||||
|
hash: String,
|
||||||
|
download_type: i8,
|
||||||
|
mod_id: String,
|
||||||
|
) -> String {
|
||||||
|
println!("[download] Starting download for '{}' from '{}'", name, url);
|
||||||
|
let _ = app.emit("download-start", format!("{}", name));
|
||||||
|
let window = app.get_webview_window("main").expect("main window missing");
|
||||||
|
|
||||||
|
let downloads_path = match app.path().app_local_data_dir() {
|
||||||
|
Ok(p) => p.join("downloads"),
|
||||||
|
Err(e) => {
|
||||||
|
println!(
|
||||||
|
"[download] ERROR: Failed to resolve app_local_data_dir: {}",
|
||||||
|
e
|
||||||
|
);
|
||||||
|
let _ = &app.emit("download-stop", format!("{}", name));
|
||||||
|
return "-1".to_string();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let game_path = match app.path().app_local_data_dir() {
|
||||||
|
Ok(p) => p.join("game"),
|
||||||
|
Err(e) => {
|
||||||
|
println!("[download] ERROR: Failed to resolve game path: {}", e);
|
||||||
|
let _ = &app.emit("download-stop", format!("{}", name));
|
||||||
return "-1".to_string();
|
return "-1".to_string();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let total_size = resp.content_length().unwrap_or(0);
|
|
||||||
|
|
||||||
let mut downloaded: u64 = 0;
|
|
||||||
let mut stream = resp.bytes_stream();
|
|
||||||
|
|
||||||
let downloads_path = app.path().app_local_data_dir().unwrap().join("downloads");
|
|
||||||
let game_path = app.path().app_local_data_dir().unwrap().join("game");
|
|
||||||
|
|
||||||
let download_part_path = downloads_path.join(format!("{}.part", name));
|
let download_part_path = downloads_path.join(format!("{}.part", name));
|
||||||
let download_zip_path = downloads_path.join(format!("{}.zip", name));
|
let download_zip_path = downloads_path.join(format!("{}.zip", name));
|
||||||
|
println!("[download] Part file: {:?}", download_part_path);
|
||||||
if download_part_path.exists() {
|
println!("[download] Zip file: {:?}", download_zip_path);
|
||||||
let _ = tokio::fs::remove_file(&download_part_path).await;
|
|
||||||
}
|
|
||||||
|
|
||||||
let _ = tokio::fs::create_dir_all(&downloads_path).await;
|
let _ = tokio::fs::create_dir_all(&downloads_path).await;
|
||||||
if let Ok(true) = tokio::fs::try_exists(&game_path.join(name.clone())).await {
|
|
||||||
let _ = tokio::fs::remove_dir_all(&game_path.join(name.clone())).await;
|
let resume_from: u64 = match tokio::fs::metadata(&download_part_path).await {
|
||||||
|
Ok(meta) => {
|
||||||
|
let size = meta.len();
|
||||||
|
println!(
|
||||||
|
"[download] Found existing .part file ({} bytes), will attempt to resume",
|
||||||
|
size
|
||||||
|
);
|
||||||
|
size
|
||||||
|
}
|
||||||
|
Err(_) => 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
let client = reqwest::Client::new();
|
||||||
|
let mut request = client.get(&url);
|
||||||
|
if resume_from > 0 {
|
||||||
|
request = request.header("Range", format!("bytes={}-", resume_from));
|
||||||
|
println!("[download] Requesting range: bytes={}-", resume_from);
|
||||||
}
|
}
|
||||||
let _ = tokio::fs::create_dir_all(&game_path.join(&name)).await;
|
|
||||||
let mut file = tokio::fs::File::create(download_part_path).await.unwrap();
|
let resp = match request.send().await {
|
||||||
|
Ok(r) => {
|
||||||
|
println!("[download] HTTP request succeeded, status: {}", r.status());
|
||||||
|
r
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
println!("[download] ERROR: HTTP request failed: {:?}", e);
|
||||||
|
let _ = &app.emit("download-stop", format!("{}", name));
|
||||||
|
return "-1".to_string();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let status = resp.status();
|
||||||
|
|
||||||
|
let actual_resume_from = if resume_from > 0 && status == reqwest::StatusCode::OK {
|
||||||
|
println!(
|
||||||
|
"[download] Server does not support range requests (got 200), restarting from scratch"
|
||||||
|
);
|
||||||
|
let _ = tokio::fs::remove_file(&download_part_path).await;
|
||||||
|
0
|
||||||
|
} else if resume_from > 0 && status == reqwest::StatusCode::PARTIAL_CONTENT {
|
||||||
|
println!("[download] Server accepted range request (206 Partial Content)");
|
||||||
|
resume_from
|
||||||
|
} else if resume_from > 0 {
|
||||||
|
println!(
|
||||||
|
"[download] Unexpected status {} while resuming, restarting",
|
||||||
|
status
|
||||||
|
);
|
||||||
|
let _ = tokio::fs::remove_file(&download_part_path).await;
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
let remaining_size = resp.content_length().unwrap_or(0);
|
||||||
|
let total_size = actual_resume_from + remaining_size;
|
||||||
|
println!(
|
||||||
|
"[download] Resume offset: {} bytes | Remaining: {} bytes | Total: {} bytes ({:.2} MB)",
|
||||||
|
actual_resume_from,
|
||||||
|
remaining_size,
|
||||||
|
total_size,
|
||||||
|
total_size as f64 / 1_048_576.0
|
||||||
|
);
|
||||||
|
let _ = app.emit("download-size", format!("{}:{}", &name, &total_size));
|
||||||
|
|
||||||
|
let mut file = if actual_resume_from > 0 {
|
||||||
|
match tokio::fs::OpenOptions::new()
|
||||||
|
.append(true)
|
||||||
|
.open(&download_part_path)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(f) => {
|
||||||
|
println!("[download] Opened .part file in append mode for resume");
|
||||||
|
f
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
println!(
|
||||||
|
"[download] ERROR: Failed to open .part file for append: {}",
|
||||||
|
e
|
||||||
|
);
|
||||||
|
let _ = &app.emit("download-stop", format!("{}", name));
|
||||||
|
return "-1".to_string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if download_type == 0 {
|
||||||
|
if let Ok(true) = tokio::fs::try_exists(&game_path.join(&name)).await {
|
||||||
|
println!(
|
||||||
|
"[download] Existing game dir found, removing: {:?}",
|
||||||
|
game_path.join(&name)
|
||||||
|
);
|
||||||
|
let _ = tokio::fs::remove_dir_all(&game_path.join(&name)).await;
|
||||||
|
}
|
||||||
|
let _ = tokio::fs::create_dir_all(&game_path.join(&name)).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
match tokio::fs::File::create(&download_part_path).await {
|
||||||
|
Ok(f) => {
|
||||||
|
println!("[download] Created new .part file");
|
||||||
|
f
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
println!("[download] ERROR: Failed to create .part file: {}", e);
|
||||||
|
let _ = &app.emit("download-stop", format!("{}", name));
|
||||||
|
return "-1".to_string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut downloaded: u64 = actual_resume_from;
|
||||||
|
let mut stream = resp.bytes_stream();
|
||||||
|
|
||||||
|
let start = Instant::now();
|
||||||
|
let mut chunk_count: u64 = 0;
|
||||||
|
|
||||||
while let Ok(Some(chunk_result)) = timeout(Duration::from_secs(5), stream.next()).await {
|
while let Ok(Some(chunk_result)) = timeout(Duration::from_secs(5), stream.next()).await {
|
||||||
|
if is_cancelled(&name) {
|
||||||
|
println!("[download] Cancelled '{}' during chunk loop", name);
|
||||||
|
cancel_map().remove(&name);
|
||||||
|
let _ = window.set_progress_bar(ProgressBarState {
|
||||||
|
status: Some(ProgressBarStatus::None),
|
||||||
|
progress: Some(0),
|
||||||
|
});
|
||||||
|
return "0".to_string();
|
||||||
|
}
|
||||||
|
|
||||||
let chunk = match chunk_result {
|
let chunk = match chunk_result {
|
||||||
Ok(c) => c,
|
Ok(c) => c,
|
||||||
Err(_) => {
|
Err(e) => {
|
||||||
|
println!(
|
||||||
|
"[download] ERROR: Failed to read chunk #{}: {}",
|
||||||
|
chunk_count, e
|
||||||
|
);
|
||||||
|
let _ = &app.emit("download-stop", format!("{}", name));
|
||||||
return "-1".to_string();
|
return "-1".to_string();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(_) = file.write_all(&chunk).await {
|
chunk_count += 1;
|
||||||
|
|
||||||
|
if let Err(e) = file.write_all(&chunk).await {
|
||||||
|
println!(
|
||||||
|
"[download] ERROR: Failed to write chunk #{} to disk: {}",
|
||||||
|
chunk_count, e
|
||||||
|
);
|
||||||
|
let _ = &app.emit("download-stop", format!("{}", name));
|
||||||
return "-1".to_string();
|
return "-1".to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
downloaded += chunk.len() as u64;
|
downloaded += chunk.len() as u64;
|
||||||
|
|
||||||
let progress = if total_size > 0 {
|
let progress = if total_size > 0 {
|
||||||
(downloaded * 100 / total_size) as u8
|
((downloaded as f64) / (total_size as f64)) * 100.0
|
||||||
} else {
|
} else {
|
||||||
0
|
0.0
|
||||||
};
|
};
|
||||||
|
|
||||||
app.emit("download-progress", format!("{}:{}", &name, progress))
|
let session_bytes = downloaded - actual_resume_from;
|
||||||
.unwrap();
|
let elapsed_secs = start.elapsed().as_secs_f64();
|
||||||
|
let speed = if elapsed_secs > 0.0 {
|
||||||
|
session_bytes as f64 / elapsed_secs
|
||||||
|
} else {
|
||||||
|
0.0
|
||||||
|
};
|
||||||
|
let eta_secs = if total_size > downloaded && speed > 0.0 {
|
||||||
|
(total_size - downloaded) as f64 / speed
|
||||||
|
} else {
|
||||||
|
0.0
|
||||||
|
};
|
||||||
|
|
||||||
|
if chunk_count % 50 == 0 || downloaded == total_size {
|
||||||
|
println!(
|
||||||
|
"[download] [{:.1}%] {:.2} MB / {:.2} MB | Speed: {:.1} KB/s | ETA: {:.1}s | Chunks: {}",
|
||||||
|
progress,
|
||||||
|
downloaded as f64 / 1_048_576.0,
|
||||||
|
total_size as f64 / 1_048_576.0,
|
||||||
|
speed / 1024.0,
|
||||||
|
eta_secs,
|
||||||
|
chunk_count,
|
||||||
|
);
|
||||||
|
let _ = window.set_progress_bar(ProgressBarState {
|
||||||
|
status: Some(ProgressBarStatus::Normal),
|
||||||
|
progress: Some(progress as u64),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = app.emit(
|
||||||
|
"download-progress",
|
||||||
|
format!(
|
||||||
|
"{}:{:.8}:{}:{}:{:.2}",
|
||||||
|
&name, progress, downloaded, speed, eta_secs
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if total_size > 0 && downloaded < total_size {
|
if total_size > 0 && downloaded < total_size {
|
||||||
|
println!(
|
||||||
|
"[download] ERROR: Download incomplete — got {} of {} bytes ({:.1}% complete)",
|
||||||
|
downloaded,
|
||||||
|
total_size,
|
||||||
|
(downloaded as f64 / total_size as f64) * 100.0
|
||||||
|
);
|
||||||
|
let _ = window.set_progress_bar(ProgressBarState {
|
||||||
|
status: Some(ProgressBarStatus::None),
|
||||||
|
progress: Some(0),
|
||||||
|
});
|
||||||
return "-1".to_string();
|
return "-1".to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
tokio::fs::rename(
|
println!(
|
||||||
downloads_path.join(format!("{}.part", name)),
|
"[download] Download complete: {} bytes total in {:.2}s (this session)",
|
||||||
|
downloaded,
|
||||||
|
start.elapsed().as_secs_f64()
|
||||||
|
);
|
||||||
|
println!("[download] Verifying SHA-512 hash...");
|
||||||
|
let _ = app.emit("download-hash-checking", format!("{}", &name));
|
||||||
|
|
||||||
|
let download_hash = {
|
||||||
|
let mut file = match tokio::fs::File::open(&download_part_path).await {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(e) => {
|
||||||
|
println!(
|
||||||
|
"[download] ERROR: Failed to open .part file for hashing: {}",
|
||||||
|
e
|
||||||
|
);
|
||||||
|
return "-1".to_string();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut hasher = Sha512::new();
|
||||||
|
let mut bytes_hashed: u64 = 0;
|
||||||
|
let mut buffer = [0u8; 8192];
|
||||||
|
loop {
|
||||||
|
let bytes_read = match file.read(&mut buffer).await {
|
||||||
|
Ok(n) => n,
|
||||||
|
Err(e) => {
|
||||||
|
println!(
|
||||||
|
"[download] ERROR: Failed to read file during hashing: {}",
|
||||||
|
e
|
||||||
|
);
|
||||||
|
return "-1".to_string();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if bytes_read == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
hasher.update(&buffer[..bytes_read]);
|
||||||
|
bytes_hashed += bytes_read as u64;
|
||||||
|
}
|
||||||
|
drop(file);
|
||||||
|
println!("[download] Hashed {} bytes", bytes_hashed);
|
||||||
|
format!("{:x}", hasher.finalize())
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("[download] Expected hash: {}", hash);
|
||||||
|
println!("[download] Computed hash: {}", download_hash);
|
||||||
|
|
||||||
|
if hash != download_hash {
|
||||||
|
println!("[download] ERROR: Hash mismatch! Deleting corrupt .part file.");
|
||||||
|
let _ = tokio::fs::remove_file(&download_part_path).await;
|
||||||
|
let _ = window.set_progress_bar(ProgressBarState {
|
||||||
|
status: Some(ProgressBarStatus::None),
|
||||||
|
progress: Some(0),
|
||||||
|
});
|
||||||
|
return "-1".to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("[download] Hash verified OK");
|
||||||
|
println!("[download] Renaming .part -> .zip: {:?}", download_zip_path);
|
||||||
|
if let Err(e) = tokio::fs::rename(&download_part_path, &download_zip_path).await {
|
||||||
|
println!("[download] ERROR: Failed to rename .part to .zip: {}", e);
|
||||||
|
let _ = window.set_progress_bar(ProgressBarState {
|
||||||
|
status: Some(ProgressBarStatus::None),
|
||||||
|
progress: Some(0),
|
||||||
|
});
|
||||||
|
return "-1".to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = tokio::fs::create_dir_all(&game_path.join(&name)).await;
|
||||||
|
|
||||||
|
println!("[download] Unzipping to: {:?}", game_path.join(&name));
|
||||||
|
let unzip_res = unzip_to_dir(
|
||||||
|
app.clone(),
|
||||||
download_zip_path.clone(),
|
download_zip_path.clone(),
|
||||||
|
if download_type == 2 {
|
||||||
|
game_path
|
||||||
|
.join(&name)
|
||||||
|
.join("BepInEx")
|
||||||
|
.join("plugins")
|
||||||
|
.join(&mod_id)
|
||||||
|
} else {
|
||||||
|
game_path.join(&name)
|
||||||
|
},
|
||||||
|
name.clone(),
|
||||||
)
|
)
|
||||||
.await
|
.await;
|
||||||
.unwrap();
|
|
||||||
let unzip_res = unzip_to_dir(download_zip_path.clone(), game_path.join(&name)).await;
|
println!("[download] Removing zip file: {:?}", download_zip_path);
|
||||||
tokio::fs::remove_file(download_zip_path.clone())
|
let _ = tokio::fs::remove_file(&download_zip_path).await;
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
if unzip_res == "-1" {
|
if unzip_res == "-1" {
|
||||||
|
println!("[download] ERROR: Unzip failed for '{}'", name);
|
||||||
|
let _ = window.set_progress_bar(ProgressBarState {
|
||||||
|
status: Some(ProgressBarStatus::None),
|
||||||
|
progress: Some(0),
|
||||||
|
});
|
||||||
return "-1".to_string();
|
return "-1".to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
println!(
|
||||||
{
|
"[download] SUCCESS: '{}' downloaded, verified, and extracted",
|
||||||
let executable_path = game_path.join(&name).join(&executable);
|
&name
|
||||||
let mut perms = fs::metadata(&executable_path).unwrap().permissions();
|
);
|
||||||
perms.set_mode(0o755);
|
let _ = window.set_progress_bar(ProgressBarState {
|
||||||
fs::set_permissions(executable_path, perms).unwrap();
|
status: Some(ProgressBarStatus::None),
|
||||||
}
|
progress: Some(0),
|
||||||
#[cfg(target_os = "macos")]
|
});
|
||||||
{
|
"1".to_string()
|
||||||
use std::fs;
|
|
||||||
use std::os::unix::fs::PermissionsExt;
|
|
||||||
|
|
||||||
let macos_app_path = game_path
|
|
||||||
.join(&name)
|
|
||||||
.join(&executable)
|
|
||||||
.join("Contents")
|
|
||||||
.join("MacOS")
|
|
||||||
.join(
|
|
||||||
&executable
|
|
||||||
.chars()
|
|
||||||
.take(executable.chars().count() - 4)
|
|
||||||
.collect::<String>(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut perms = fs::metadata(&macos_app_path).unwrap().permissions();
|
|
||||||
perms.set_mode(0o755);
|
|
||||||
fs::set_permissions(&macos_app_path, perms).unwrap();
|
|
||||||
}
|
|
||||||
return "1".to_string();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
fn launch_game(app: AppHandle, name: String, executable: String, wine: bool, wine_command: String) {
|
fn launch_game(
|
||||||
let game_folder = app
|
app: AppHandle,
|
||||||
.path()
|
name: String,
|
||||||
.app_local_data_dir()
|
executable: String,
|
||||||
.unwrap()
|
display_name: String,
|
||||||
.join("game")
|
use_wine: bool,
|
||||||
.join(&name);
|
wine_command: String,
|
||||||
let game_path = game_folder.join(&executable);
|
) {
|
||||||
if !game_path.exists() {
|
let game_folder = match app.path().app_local_data_dir() {
|
||||||
app.dialog()
|
Ok(p) => p.join("game").join(&name),
|
||||||
.message(format!("Executable \"{}\" not found.\n\nTry reinstalling the game or make a support request in the Community link on the sidebar.", game_path.display().to_string()))
|
Err(_) => return,
|
||||||
.kind(MessageDialogKind::Error)
|
};
|
||||||
.title("Game not found")
|
if !game_folder.exists() {
|
||||||
.show(|_| {});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let result = if wine && platform() == "linux" {
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
{
|
|
||||||
let wine_cmd_to_use =
|
|
||||||
wine_command.replace("%path%", &format!("\"{}\"", game_path.to_string_lossy()));
|
|
||||||
|
|
||||||
let parts = shlex::split(&wine_cmd_to_use).expect("failed to split command");
|
let exe_path = game_folder.join(&executable);
|
||||||
let exe = &parts[0];
|
|
||||||
let args = &parts[1..];
|
|
||||||
|
|
||||||
Command::new(exe)
|
//if already running on macos, it'll auto take the user to that proccess
|
||||||
.args(args)
|
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
||||||
.current_dir(&game_folder)
|
{
|
||||||
.spawn()
|
use tauri_plugin_dialog::DialogExt;
|
||||||
}
|
use tauri_plugin_dialog::MessageDialogKind;
|
||||||
|
|
||||||
#[cfg(not(target_os = "linux"))]
|
if !use_wine && is_running_by_path(&exe_path) {
|
||||||
{
|
|
||||||
Err(std::io::Error::new(std::io::ErrorKind::Other, "not linux"))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if is_running_by_path(&game_path) {
|
|
||||||
app.dialog()
|
app.dialog()
|
||||||
.message(format!("The version {} is already running.", name))
|
.message(format!(
|
||||||
|
"{} is already running, if this doesn't seem true, try to kill the proccess.",
|
||||||
|
display_name
|
||||||
|
))
|
||||||
.kind(MessageDialogKind::Error)
|
.kind(MessageDialogKind::Error)
|
||||||
.title("Game already running")
|
.title("Game already running")
|
||||||
.show(|_| {});
|
.show(|_| {});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if platform() == "macos" {
|
}
|
||||||
Command::new("open")
|
|
||||||
.arg(&game_path)
|
#[cfg(target_os = "linux")]
|
||||||
|
{
|
||||||
|
if use_wine {
|
||||||
|
let quoted_path = format!("\"{}\"", exe_path.to_string_lossy());
|
||||||
|
let cmd = wine_command.replace("%path%", "ed_path);
|
||||||
|
|
||||||
|
if let Err(_) = Command::new("bash")
|
||||||
|
.arg("-c")
|
||||||
|
.arg(cmd)
|
||||||
.current_dir(&game_folder)
|
.current_dir(&game_folder)
|
||||||
.spawn()
|
.spawn()
|
||||||
} else {
|
{
|
||||||
Command::new(&game_path).current_dir(&game_folder).spawn()
|
eprintln!("Failed to launch game with Wine");
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let bepinex_folder = match app.path().app_local_data_dir() {
|
||||||
|
Ok(p) => p.join("game").join(&name).join("BepInEx"),
|
||||||
|
Err(_) => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
match result {
|
if platform() == "macos" && !bepinex_folder.exists() {
|
||||||
Ok(_) => println!("Game launched successfully."),
|
if let Err(_) = Command::new("open")
|
||||||
Err(e) => {
|
.arg(&executable)
|
||||||
app.dialog()
|
.current_dir(&game_folder)
|
||||||
.message(format!("Failed to load game:\n{}\n\nTry reinstalling the game or make a support request in the Community link on the sidebar.", e))
|
.spawn()
|
||||||
.kind(MessageDialogKind::Error)
|
{
|
||||||
.title("Failed to launch game")
|
eprintln!("Failed to launch game on macOS");
|
||||||
.show(|_| {});
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
}
|
if (platform() == "macos" || platform() == "linux") && bepinex_folder.exists() {
|
||||||
|
if let Err(_) = Command::new("./run_bepinex.sh")
|
||||||
#[tauri::command]
|
.arg(&executable)
|
||||||
async fn uninstall_version(app: AppHandle, name: String) {
|
.current_dir(&game_folder)
|
||||||
let game_path = app
|
.spawn()
|
||||||
.path()
|
{
|
||||||
.app_local_data_dir()
|
eprintln!("Failed to launch game");
|
||||||
.unwrap()
|
}
|
||||||
.join("game")
|
|
||||||
.join(&name);
|
|
||||||
if game_path.exists() {
|
|
||||||
if let Err(_) = tokio::fs::remove_dir_all(&game_path).await {
|
|
||||||
app.emit("version-failed", &name).unwrap();
|
|
||||||
} else {
|
} else {
|
||||||
app.emit("version-uninstalled", &name).unwrap();
|
if let Err(_) = Command::new(&exe_path).current_dir(&game_folder).spawn() {
|
||||||
|
eprintln!("Failed to launch game");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
app.emit("version-uninstalled", &name).unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn open_folder(app: AppHandle, name: String) {
|
fn verify_signature(body: String, signature: String, public_key: String) -> bool {
|
||||||
let game_path = app
|
let Ok(pem) = general_purpose::STANDARD.decode(public_key) else {
|
||||||
.path()
|
return false;
|
||||||
.app_local_data_dir()
|
};
|
||||||
.unwrap()
|
let Ok(pubkey) = PKey::public_key_from_pem(&pem) else {
|
||||||
.join("game")
|
return false;
|
||||||
.join(&name);
|
};
|
||||||
if game_path.exists() {
|
let Ok(sig) = general_purpose::STANDARD.decode(signature) else {
|
||||||
app.opener()
|
return false;
|
||||||
.open_path(game_path.to_string_lossy(), None::<&str>)
|
};
|
||||||
.unwrap();
|
|
||||||
} else {
|
let mut verifier = match Verifier::new_without_digest(&pubkey) {
|
||||||
app.dialog()
|
Ok(v) => v,
|
||||||
.message(format!(
|
Err(_) => return false,
|
||||||
"Game folder \"{}\" not found.",
|
};
|
||||||
game_path.display()
|
|
||||||
))
|
verifier
|
||||||
.kind(MessageDialogKind::Error)
|
.verify_oneshot(&sig, body.as_bytes())
|
||||||
.title("Folder not found")
|
.unwrap_or(false)
|
||||||
.show(|_| {});
|
}
|
||||||
}
|
|
||||||
|
#[tauri::command]
|
||||||
|
async fn cancel_download(name: String) {
|
||||||
|
println!("[cancel_download] Cancellation requested for '{}'", name);
|
||||||
|
cancel_map().insert(name.clone(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
|
.plugin(tauri_plugin_http::init())
|
||||||
|
.plugin(
|
||||||
|
tauri_plugin_prevent_default::Builder::new()
|
||||||
|
.with_flags(
|
||||||
|
Flags::FIND
|
||||||
|
| Flags::CARET_BROWSING
|
||||||
|
| Flags::DEV_TOOLS
|
||||||
|
| Flags::DOWNLOADS
|
||||||
|
| Flags::FOCUS_MOVE
|
||||||
|
| Flags::RELOAD
|
||||||
|
| Flags::SOURCE
|
||||||
|
| Flags::OPEN
|
||||||
|
| Flags::PRINT
|
||||||
|
| Flags::CONTEXT_MENU,
|
||||||
|
)
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
|
.plugin(tauri_plugin_window_state::Builder::new().build())
|
||||||
|
.plugin(tauri_plugin_clipboard_manager::init())
|
||||||
.plugin(tauri_plugin_notification::init())
|
.plugin(tauri_plugin_notification::init())
|
||||||
.plugin(tauri_plugin_single_instance::init(|app, _args, _cwd| {
|
.plugin(tauri_plugin_single_instance::init(|app, _args, _cwd| {
|
||||||
let _ = app
|
if let Some(window) = app.get_webview_window("main") {
|
||||||
.get_webview_window("main")
|
let _ = window.set_focus();
|
||||||
.expect("no main window")
|
}
|
||||||
.set_focus();
|
|
||||||
}))
|
}))
|
||||||
.plugin(tauri_plugin_dialog::init())
|
.plugin(tauri_plugin_dialog::init())
|
||||||
.plugin(tauri_plugin_fs::init())
|
.plugin(tauri_plugin_fs::init())
|
||||||
@@ -296,14 +653,19 @@ pub fn run() {
|
|||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
download,
|
download,
|
||||||
launch_game,
|
launch_game,
|
||||||
uninstall_version,
|
folder_size,
|
||||||
open_folder
|
verify_signature,
|
||||||
|
cancel_download
|
||||||
])
|
])
|
||||||
.setup(|app| {
|
.setup(|app| {
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
{
|
{
|
||||||
let main_window = app.get_webview_window("main").unwrap();
|
use tauri_plugin_decorum::WebviewWindowExt;
|
||||||
main_window.create_overlay_titlebar().unwrap();
|
if let Some(main_window) = app.get_webview_window("main") {
|
||||||
|
if let Err(e) = main_window.create_overlay_titlebar() {
|
||||||
|
eprintln!("Failed to create overlay titlebar: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "Lncvrt Games Launcher",
|
"productName": "Lncvrt Games Launcher",
|
||||||
"version": "1.0.0",
|
"version": "1.8.0",
|
||||||
"identifier": "xyz.lncvrt.games-launcher",
|
"identifier": "xyz.lncvrt.games-launcher",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "next dev",
|
"beforeDevCommand": "next dev --webpack",
|
||||||
"devUrl": "http://localhost:3000",
|
"devUrl": "http://localhost:3000",
|
||||||
"beforeBuildCommand": "next build",
|
"beforeBuildCommand": "next build",
|
||||||
"frontendDist": "../out"
|
"frontendDist": "../out"
|
||||||
@@ -15,8 +15,8 @@
|
|||||||
"title": "Lncvrt Games Launcher",
|
"title": "Lncvrt Games Launcher",
|
||||||
"width": 1000,
|
"width": 1000,
|
||||||
"height": 600,
|
"height": 600,
|
||||||
"resizable": false,
|
"minWidth": 875,
|
||||||
"maximizable": false
|
"minHeight": 500
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"security": {
|
"security": {
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "Lncvrt Games Launcher",
|
"productName": "Lncvrt Games Launcher",
|
||||||
"version": "1.0.0",
|
"version": "1.8.0",
|
||||||
"identifier": "xyz.lncvrt.games-launcher",
|
"identifier": "xyz.lncvrt.games-launcher",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "next dev",
|
"beforeDevCommand": "next dev --webpack",
|
||||||
"devUrl": "http://localhost:3000",
|
"devUrl": "http://localhost:3000",
|
||||||
"beforeBuildCommand": "next build",
|
"beforeBuildCommand": "next build",
|
||||||
"frontendDist": "../out"
|
"frontendDist": "../out"
|
||||||
@@ -15,8 +15,8 @@
|
|||||||
"title": "Lncvrt Games Launcher",
|
"title": "Lncvrt Games Launcher",
|
||||||
"width": 1000,
|
"width": 1000,
|
||||||
"height": 600,
|
"height": 600,
|
||||||
"resizable": false,
|
"minWidth": 875,
|
||||||
"maximizable": false
|
"minHeight": 500
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"security": {
|
"security": {
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "Lncvrt Games Launcher",
|
"productName": "Lncvrt Games Launcher",
|
||||||
"version": "1.0.0",
|
"version": "1.8.0",
|
||||||
"identifier": "xyz.lncvrt.games-launcher",
|
"identifier": "xyz.lncvrt.games-launcher",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "next dev",
|
"beforeDevCommand": "next dev --webpack",
|
||||||
"devUrl": "http://localhost:3000",
|
"devUrl": "http://localhost:3000",
|
||||||
"beforeBuildCommand": "next build",
|
"beforeBuildCommand": "next build",
|
||||||
"frontendDist": "../out"
|
"frontendDist": "../out"
|
||||||
@@ -16,8 +16,8 @@
|
|||||||
"title": "Lncvrt Games Launcher",
|
"title": "Lncvrt Games Launcher",
|
||||||
"width": 1000,
|
"width": 1000,
|
||||||
"height": 600,
|
"height": 600,
|
||||||
"resizable": false,
|
"minWidth": 875,
|
||||||
"maximizable": false,
|
"minHeight": 500,
|
||||||
"titleBarStyle": "Overlay",
|
"titleBarStyle": "Overlay",
|
||||||
"hiddenTitle": true
|
"hiddenTitle": true
|
||||||
}
|
}
|
||||||
@@ -30,10 +30,8 @@
|
|||||||
"active": true,
|
"active": true,
|
||||||
"targets": ["app"],
|
"targets": ["app"],
|
||||||
"macOS": {
|
"macOS": {
|
||||||
"minimumSystemVersion": "13.7.8"
|
"minimumSystemVersion": "13.0"
|
||||||
},
|
},
|
||||||
"icon": [
|
"icon": ["icons/icon.icns"]
|
||||||
"icons/icon.icns"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "Lncvrt Games Launcher",
|
"productName": "Lncvrt Games Launcher",
|
||||||
"version": "1.0.0",
|
"version": "1.8.0",
|
||||||
"identifier": "xyz.lncvrt.games-launcher",
|
"identifier": "xyz.lncvrt.games-launcher",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "next dev",
|
"beforeDevCommand": "next dev --webpack",
|
||||||
"devUrl": "http://localhost:3000",
|
"devUrl": "http://localhost:3000",
|
||||||
"beforeBuildCommand": "next build",
|
"beforeBuildCommand": "next build",
|
||||||
"frontendDist": "../out"
|
"frontendDist": "../out"
|
||||||
@@ -16,8 +16,8 @@
|
|||||||
"title": "Lncvrt Games Launcher",
|
"title": "Lncvrt Games Launcher",
|
||||||
"width": 1000,
|
"width": 1000,
|
||||||
"height": 632,
|
"height": 632,
|
||||||
"resizable": false,
|
"minWidth": 875,
|
||||||
"maximizable": false,
|
"minHeight": 532,
|
||||||
"titleBarStyle": "Overlay",
|
"titleBarStyle": "Overlay",
|
||||||
"hiddenTitle": true,
|
"hiddenTitle": true,
|
||||||
"decorations": false,
|
"decorations": false,
|
||||||
@@ -30,8 +30,6 @@
|
|||||||
},
|
},
|
||||||
"bundle": {
|
"bundle": {
|
||||||
"active": false,
|
"active": false,
|
||||||
"icon": [
|
"icon": ["icons/icon.ico"]
|
||||||
"icons/icon.ico"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,36 +1,68 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { createContext, useContext, ReactNode } from 'react'
|
import {
|
||||||
import { DownloadProgress } from './types/DownloadProgress'
|
createContext,
|
||||||
import { VersionsConfig } from './types/VersionsConfig'
|
useContext,
|
||||||
import { NormalConfig } from './types/NormalConfig'
|
ReactNode,
|
||||||
import { ServerVersionsResponse } from './types/ServerVersionsResponse'
|
Dispatch,
|
||||||
import { GameVersion } from './types/GameVersion'
|
SetStateAction
|
||||||
import { Game } from './types/Game'
|
} from 'react'
|
||||||
import { ReadonlyURLSearchParams } from 'next/navigation'
|
import { DownloadProgress } from '@/types/DownloadProgress'
|
||||||
|
import { VersionsConfig } from '@/types/VersionsConfig'
|
||||||
|
import { NormalConfig } from '@/types/NormalConfig'
|
||||||
|
import { ServerVersionsResponse } from '@/types/ServerVersionsResponse'
|
||||||
|
import { GameVersion } from '@/types/GameVersion'
|
||||||
|
import { Game } from '@/types/Game'
|
||||||
|
import { Mod } from '@/types/Mod'
|
||||||
|
|
||||||
type GlobalCtxType = {
|
type GlobalCtxType = {
|
||||||
serverVersionList: ServerVersionsResponse | null
|
serverVersionList: ServerVersionsResponse | null
|
||||||
selectedVersionList: string[]
|
selectedVersionList: string[]
|
||||||
setSelectedVersionList: (v: string[]) => void
|
setSelectedVersionList: (value: SetStateAction<string[]>) => void
|
||||||
downloadProgress: DownloadProgress[]
|
downloadProgress: DownloadProgress[]
|
||||||
setDownloadProgress: (v: DownloadProgress[]) => void
|
setDownloadProgress: Dispatch<SetStateAction<DownloadProgress[]>>
|
||||||
showPopup: boolean
|
showPopup: boolean
|
||||||
setShowPopup: (v: boolean) => void
|
setShowPopup: Dispatch<SetStateAction<boolean>>
|
||||||
popupMode: number | null
|
popupMode: number | null
|
||||||
setPopupMode: (v: number | null) => void
|
setPopupMode: Dispatch<SetStateAction<number | null>>
|
||||||
fadeOut: boolean
|
fadeOut: boolean
|
||||||
setFadeOut: (v: boolean) => void
|
setFadeOut: Dispatch<SetStateAction<boolean>>
|
||||||
downloadedVersionsConfig: VersionsConfig | null
|
downloadedVersionsConfig: VersionsConfig | null
|
||||||
setDownloadedVersionsConfig: (v: VersionsConfig | null) => void
|
setDownloadedVersionsConfig: Dispatch<SetStateAction<VersionsConfig | null>>
|
||||||
normalConfig: NormalConfig | null
|
normalConfig: NormalConfig | null
|
||||||
setNormalConfig: (v: NormalConfig | null) => void
|
setNormalConfig: Dispatch<SetStateAction<NormalConfig | null>>
|
||||||
managingVersion: string | null
|
managingVersion: string | null
|
||||||
setManagingVersion: (v: string | null) => void
|
setManagingVersion: Dispatch<SetStateAction<string | null>>
|
||||||
setSelectedGame: (v: number | null) => void
|
setSelectedGame: Dispatch<SetStateAction<number | null>>
|
||||||
getVersionInfo: (id: string | undefined) => GameVersion | undefined
|
getVersionInfo: (id: string | undefined) => GameVersion | undefined
|
||||||
getVersionGame: (id: number | undefined) => Game | undefined
|
getGameInfo: (game: number | undefined) => Game | undefined
|
||||||
getListOfGames: () => Game[]
|
getListOfGames(): Game[]
|
||||||
|
getVersionsAmountData: (gameId: number) => {
|
||||||
|
installed: number
|
||||||
|
total: number
|
||||||
|
} | null
|
||||||
|
viewingInfoFromDownloads: boolean
|
||||||
|
version: string | null
|
||||||
|
downloadVersions: (
|
||||||
|
list: Array<{
|
||||||
|
id: string
|
||||||
|
type: 0 | 1 | 2
|
||||||
|
modDownload?: number
|
||||||
|
gameId?: number
|
||||||
|
modId?: number
|
||||||
|
modVersion?: string
|
||||||
|
}>
|
||||||
|
) => Promise<void>
|
||||||
|
category: number
|
||||||
|
setCategory: Dispatch<SetStateAction<number>>
|
||||||
|
downloadQueue: string[]
|
||||||
|
setDownloadQueue: Dispatch<SetStateAction<string[]>>
|
||||||
|
closePopup: () => void
|
||||||
|
getSpecialVersionsList(game?: number | undefined): GameVersion[]
|
||||||
|
selectedGame: number | null
|
||||||
|
setViewingInfoFromDownloads: Dispatch<SetStateAction<boolean>>
|
||||||
|
showModInfo: Mod | null
|
||||||
|
setShowModInfo: Dispatch<SetStateAction<Mod | null>>
|
||||||
}
|
}
|
||||||
|
|
||||||
const GlobalCtx = createContext<GlobalCtxType | null>(null)
|
const GlobalCtx = createContext<GlobalCtxType | null>(null)
|
||||||
|
|||||||
@@ -1,15 +1,79 @@
|
|||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@apply bg-[#0f0f0f] text-white select-none;
|
@apply bg-(--col0) text-white select-none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark-theme {
|
||||||
|
--col0: rgb(8, 8, 8);
|
||||||
|
--col1: rgb(16, 16, 16);
|
||||||
|
--col2: rgb(32, 32, 32);
|
||||||
|
--col3: rgb(48, 48, 48);
|
||||||
|
--col4: rgb(64, 64, 64);
|
||||||
|
--col5: rgb(80, 80, 80);
|
||||||
|
--col6: rgb(96, 96, 96);
|
||||||
|
--col7: rgb(112, 112, 112);
|
||||||
|
--col8: rgb(128, 128, 128);
|
||||||
|
--col9: rgb(144, 144, 144);
|
||||||
|
}
|
||||||
|
|
||||||
|
.red-theme {
|
||||||
|
--col0: rgb(32, 8, 8);
|
||||||
|
--col1: rgb(40, 16, 16);
|
||||||
|
--col2: rgb(56, 32, 32);
|
||||||
|
--col3: rgb(72, 48, 48);
|
||||||
|
--col4: rgb(88, 64, 64);
|
||||||
|
--col5: rgb(104, 80, 80);
|
||||||
|
--col6: rgb(120, 96, 96);
|
||||||
|
--col7: rgb(136, 112, 112);
|
||||||
|
--col8: rgb(152, 128, 128);
|
||||||
|
--col9: rgb(168, 144, 144);
|
||||||
|
}
|
||||||
|
|
||||||
|
.blue-theme {
|
||||||
|
--col0: rgb(8, 8, 32);
|
||||||
|
--col1: rgb(16, 16, 40);
|
||||||
|
--col2: rgb(32, 32, 56);
|
||||||
|
--col3: rgb(48, 48, 72);
|
||||||
|
--col4: rgb(64, 64, 88);
|
||||||
|
--col5: rgb(80, 80, 104);
|
||||||
|
--col6: rgb(96, 96, 120);
|
||||||
|
--col7: rgb(112, 112, 136);
|
||||||
|
--col8: rgb(128, 128, 152);
|
||||||
|
--col9: rgb(144, 144, 168);
|
||||||
|
}
|
||||||
|
|
||||||
|
.purple-theme {
|
||||||
|
--col0: rgb(20, 8, 32);
|
||||||
|
--col1: rgb(28, 16, 40);
|
||||||
|
--col2: rgb(44, 32, 56);
|
||||||
|
--col3: rgb(60, 48, 72);
|
||||||
|
--col4: rgb(76, 64, 88);
|
||||||
|
--col5: rgb(92, 80, 104);
|
||||||
|
--col6: rgb(108, 96, 120);
|
||||||
|
--col7: rgb(124, 112, 136);
|
||||||
|
--col8: rgb(140, 128, 152);
|
||||||
|
--col9: rgb(156, 144, 168);
|
||||||
}
|
}
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
@apply bg-[#0a6ec8] hover:bg-[#1361ad] disabled:bg-[#124c7e] disabled:hover:bg-[#1b3f63] disabled:text-[#bdbdbd] disabled:hover:text-[#e6e6e6] rounded-md cursor-pointer text-[16px] py-1.5 px-3 transition-colors duration-[0.25s];
|
@apply rounded-md cursor-pointer text-[16px] py-1 px-2 transition-colors border;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-green {
|
.btntheme1 {
|
||||||
@apply bg-[#28a745] hover:bg-[#218838] disabled:bg-[#1c7430] disabled:hover:bg-[#1a5c24] disabled:text-[#bdbdbd] disabled:hover:text-[#e6e6e6];
|
@apply bg-(--col2) border-(--col4) hover:bg-(--col4) hover:border-(--col6) disabled:text-gray-300 disabled:bg-(--col1) disabled:border-(--col5) disabled:hover:text-gray-100 disabled:hover:bg-(--col2) disabled:hover:border-(--col6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btntheme2,
|
||||||
|
.downloads-entry .entry-info-item,
|
||||||
|
.downloads-entry .button {
|
||||||
|
@apply bg-(--col3) border-(--col5) hover:bg-(--col5) hover:border-(--col7) disabled:text-gray-300 disabled:bg-(--col2) disabled:border-(--col6) disabled:hover:text-gray-100 disabled:hover:bg-(--col3) disabled:hover:border-(--col7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btntheme3,
|
||||||
|
.downloads-entry:hover .entry-info-item,
|
||||||
|
.downloads-entry:hover .button {
|
||||||
|
@apply bg-(--col4) border-(--col6) hover:bg-(--col6) hover:border-(--col8) disabled:text-gray-300 disabled:bg-(--col2) disabled:border-(--col7) disabled:hover:text-gray-100 disabled:hover:bg-(--col4) disabled:hover:border-(--col8);
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
@@ -17,11 +81,11 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-track {
|
::-webkit-scrollbar-track {
|
||||||
@apply bg-[#1f1f1f] rounded-lg;
|
@apply bg-(--col2) rounded-lg;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
::-webkit-scrollbar-thumb {
|
||||||
@apply bg-[#555] w-1 rounded-lg active:bg-[#888];
|
@apply bg-(--col4) w-1 rounded-lg active:bg-(--col5);
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes fadeIn {
|
@keyframes fadeIn {
|
||||||
@@ -51,23 +115,23 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.popup-box {
|
.popup-box {
|
||||||
@apply relative w-[60vw] h-[80vh] rounded-lg bg-[#161616] border border-[#323232] flex flex-col p-6;
|
@apply relative w-150 h-120 rounded-lg bg-(--col1) border border-(--col3) flex flex-col p-6;
|
||||||
}
|
}
|
||||||
|
|
||||||
.popup-content {
|
.popup-content {
|
||||||
@apply flex-1 overflow-auto bg-[#242424] border border-[#484848] rounded-lg mt-4;
|
@apply flex-1 overflow-auto bg-(--col2) border border-(--col4) rounded-lg mt-4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.popup-entry {
|
.popup-entry {
|
||||||
@apply relative h-[100px] bg-[#323232] m-2 p-2 rounded-lg border border-[#646464];
|
@apply relative h-fit bg-(--col3) m-2 p-2 rounded-lg border border-(--col5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.popup-entry button {
|
.popup-entry button {
|
||||||
@apply absolute;
|
@apply absolute;
|
||||||
}
|
}
|
||||||
|
|
||||||
.close-button {
|
.popup-top-button {
|
||||||
@apply flex justify-center items-center absolute bg-[#323232] hover:bg-[#484848] text-2xl cursor-pointer text-gray-300 hover:text-white h-12 w-12 p-3 rounded-xl left-2 top-2 transition-colors border border-[#484848] hover:border-[#646464];
|
@apply flex justify-center items-center absolute text-2xl text-gray-200 hover:text-white cursor-pointer h-12 w-12 p-3 rounded-lg top-2 transition-colors border;
|
||||||
}
|
}
|
||||||
|
|
||||||
*:focus {
|
*:focus {
|
||||||
@@ -75,5 +139,9 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.input-field {
|
.input-field {
|
||||||
@apply border-2 border-[#484848] rounded-md bg-[#242424] p-2 px-4 focus:border-blue-600 transition-colors;
|
@apply border-2 border-(--col4) rounded-md bg-(--col2) py-1 px-2 focus:bg-(--col3) focus:border-(--col6) transition-colors w-full;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry-info-item {
|
||||||
|
@apply flex flex-row items-center gap-1 border text-gray-300 py-1 px-2 rounded-md w-fit text-[16px] transition-colors cursor-pointer;
|
||||||
}
|
}
|
||||||
@@ -5,13 +5,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.downloads-scroll {
|
.downloads-scroll {
|
||||||
@apply h-[515px] bg-[#161616] border border-[#242424] rounded-lg overflow-y-auto w-full;
|
@apply bg-(--col1) border border-(--col3) rounded-lg overflow-y-auto w-full;
|
||||||
}
|
}
|
||||||
|
|
||||||
.downloads-entry {
|
.downloads-entry {
|
||||||
@apply flex justify-between items-center m-2 p-4 rounded-lg text-gray-200 text-lg transition-colors cursor-default bg-[#242424] hover:bg-[#323232] border border-[#484848] hover:border-[#565656];
|
@apply flex justify-between items-center m-2 p-2 rounded-lg text-gray-200 text-lg transition-colors bg-(--col2) hover:bg-(--col3) border border-(--col4) hover:border-(--col5) cursor-pointer;
|
||||||
}
|
|
||||||
|
|
||||||
.downloads-entry p.score {
|
|
||||||
@apply font-mono text-blue-500 text-lg;
|
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 88 KiB |
@@ -1,48 +0,0 @@
|
|||||||
import { useEffect, useRef } from 'react'
|
|
||||||
import BerryNoColor from '../assets/berries/BerryNoColor.png'
|
|
||||||
|
|
||||||
export default function RandomBerry () {
|
|
||||||
const canvasRef = useRef<HTMLCanvasElement>(null)
|
|
||||||
const imgRef = useRef<HTMLImageElement>(document.createElement('img'))
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
imgRef.current.src = BerryNoColor.src
|
|
||||||
const canvas = canvasRef.current
|
|
||||||
const ctx = canvas?.getContext('2d')
|
|
||||||
if (!canvas || !ctx) return
|
|
||||||
|
|
||||||
canvas.width = 24
|
|
||||||
canvas.height = 24
|
|
||||||
|
|
||||||
let frame: number
|
|
||||||
const frequency = 5
|
|
||||||
|
|
||||||
const update = () => {
|
|
||||||
const t = (performance.now() / 1000) * frequency
|
|
||||||
|
|
||||||
ctx.clearRect(0, 0, canvas.width, canvas.height)
|
|
||||||
ctx.drawImage(imgRef.current, 0, 0, canvas.width, canvas.height)
|
|
||||||
|
|
||||||
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)
|
|
||||||
const data = imageData.data
|
|
||||||
|
|
||||||
for (let i = 0; i < data.length; i += 4) {
|
|
||||||
const gray = data[i]
|
|
||||||
const r = (Math.sin(t) * 0.5 + 0.5) * 255 * (gray / 255)
|
|
||||||
const g = (Math.sin(t + 2) * 0.5 + 0.5) * 255 * (gray / 255)
|
|
||||||
const b = (Math.sin(t + 4) * 0.5 + 0.5) * 255 * (gray / 255)
|
|
||||||
data[i] = r
|
|
||||||
data[i + 1] = g
|
|
||||||
data[i + 2] = b
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.putImageData(imageData, 0, 0)
|
|
||||||
frame = requestAnimationFrame(update)
|
|
||||||
}
|
|
||||||
|
|
||||||
imgRef.current.onload = () => update()
|
|
||||||
return () => cancelAnimationFrame(frame)
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return <canvas ref={canvasRef} style={{ width: 24, height: 24 }} />
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
@import "tailwindcss";
|
|
||||||
|
|
||||||
.sidebar {
|
|
||||||
@apply fixed top-0 left-0 w-60 h-screen bg-[#161616] flex flex-col border-e border-[#242424] z-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-downloads {
|
|
||||||
@apply text-[#bdbdbd] fixed bottom-3 left-2 bg-[#242424] rounded-lg border border-[#323232] w-55 p-4 cursor-pointer transition-colors duration-[0.25s];
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-downloads:hover {
|
|
||||||
@apply text-white;
|
|
||||||
@apply bg-[#323232] border-[#484848];
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
@apply text-2xl font-bold p-4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-links {
|
|
||||||
@apply flex flex-col p-4 space-y-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.link {
|
|
||||||
@apply text-[#bdbdbd] p-2 rounded-md no-underline cursor-pointer transition-colors duration-[0.25s] border border-transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.link.active {
|
|
||||||
@apply bg-[#242424] border-[#323232];
|
|
||||||
}
|
|
||||||
|
|
||||||
.link.active,
|
|
||||||
.link:hover {
|
|
||||||
@apply text-white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.link.active:hover {
|
|
||||||
@apply bg-[#323232] border-[#484848];
|
|
||||||
}
|
|
||||||
@@ -1,130 +0,0 @@
|
|||||||
'use client'
|
|
||||||
|
|
||||||
import './Sidebar.css'
|
|
||||||
import Icon from '../assets/Icon.png'
|
|
||||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
|
||||||
import {
|
|
||||||
faCog,
|
|
||||||
faDownload,
|
|
||||||
faGamepad,
|
|
||||||
faHexagonNodes
|
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
|
||||||
import { faDiscord } from '@fortawesome/free-brands-svg-icons'
|
|
||||||
import { platform } from '@tauri-apps/plugin-os'
|
|
||||||
import { getCurrentWindow } from '@tauri-apps/api/window'
|
|
||||||
import { useGlobal } from '../GlobalProvider'
|
|
||||||
import Image from 'next/image'
|
|
||||||
import Link from 'next/link'
|
|
||||||
import { usePathname, useSearchParams } from 'next/navigation'
|
|
||||||
|
|
||||||
export default function Sidebar () {
|
|
||||||
const {
|
|
||||||
getListOfGames,
|
|
||||||
setShowPopup,
|
|
||||||
setPopupMode,
|
|
||||||
setFadeOut,
|
|
||||||
downloadProgress
|
|
||||||
} = useGlobal()
|
|
||||||
|
|
||||||
const pathname = usePathname()
|
|
||||||
const params = useSearchParams()
|
|
||||||
|
|
||||||
return (
|
|
||||||
<aside className='sidebar'>
|
|
||||||
<div
|
|
||||||
className='dragarea'
|
|
||||||
style={{
|
|
||||||
height: '30px',
|
|
||||||
width: 'calc(var(--spacing) * 60)',
|
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
marginBottom: '-15px',
|
|
||||||
position: 'absolute',
|
|
||||||
zIndex: 9999,
|
|
||||||
display: platform() == 'macos' ? 'block' : 'none',
|
|
||||||
pointerEvents: 'auto'
|
|
||||||
}}
|
|
||||||
onMouseDown={() => {
|
|
||||||
getCurrentWindow().startDragging()
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
<div className='logo'>
|
|
||||||
<Image
|
|
||||||
draggable={false}
|
|
||||||
src={Icon}
|
|
||||||
width={48}
|
|
||||||
height={48}
|
|
||||||
alt=''
|
|
||||||
style={{
|
|
||||||
marginTop: ['windows', 'macos'].includes(platform())
|
|
||||||
? '20px'
|
|
||||||
: '0px',
|
|
||||||
marginBottom: '-20px'
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<nav className='nav-links'>
|
|
||||||
<Link
|
|
||||||
draggable={false}
|
|
||||||
href='/'
|
|
||||||
className={`link relative flex items-center ${
|
|
||||||
pathname === '/' || pathname === '/game' ? 'active' : ''
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<FontAwesomeIcon icon={faHexagonNodes} className='mr-2' /> Games
|
|
||||||
</Link>
|
|
||||||
{getListOfGames()
|
|
||||||
.sort((a, b) => {
|
|
||||||
return a.id - b.id
|
|
||||||
})
|
|
||||||
.map(i => (
|
|
||||||
<Link
|
|
||||||
key={i.id}
|
|
||||||
draggable={false}
|
|
||||||
href={'/game?id=' + i.id}
|
|
||||||
className={`link ${
|
|
||||||
pathname === '/game' && Number(params.get('id') || 0) == i.id
|
|
||||||
? 'active'
|
|
||||||
: ''
|
|
||||||
} ml-auto w-50 ${
|
|
||||||
pathname === '/' || pathname === '/game' ? '' : 'hidden'
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<FontAwesomeIcon icon={faGamepad} className='mr-1' />{' '}
|
|
||||||
{i.cutOff == null
|
|
||||||
? i.name
|
|
||||||
: i.name.substring(0, i.cutOff) + '...'}
|
|
||||||
</Link>
|
|
||||||
))}
|
|
||||||
<Link
|
|
||||||
draggable={false}
|
|
||||||
href='/settings'
|
|
||||||
className={`link ${pathname === '/settings' ? 'active' : ''}`}
|
|
||||||
>
|
|
||||||
<FontAwesomeIcon icon={faCog} className='mr-1' /> Settings
|
|
||||||
</Link>
|
|
||||||
<a
|
|
||||||
draggable={false}
|
|
||||||
onClick={() => openUrl('https://games.lncvrt.xyz/discord')}
|
|
||||||
className='link'
|
|
||||||
>
|
|
||||||
<FontAwesomeIcon icon={faDiscord} className='mr-1' /> Community
|
|
||||||
</a>
|
|
||||||
</nav>
|
|
||||||
<div
|
|
||||||
className='sidebar-downloads'
|
|
||||||
style={{ display: downloadProgress.length != 0 ? 'block' : 'none' }}
|
|
||||||
onClick={() => {
|
|
||||||
setPopupMode(1)
|
|
||||||
setShowPopup(true)
|
|
||||||
setFadeOut(false)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<p>
|
|
||||||
<FontAwesomeIcon icon={faDownload} /> Downloads
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</aside>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,339 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
|
import { BirdColor } from '@/types/BerryDash/BirdColor'
|
||||||
|
import { GetIconForUser } from '@/lib/BerryDash'
|
||||||
|
import Image from 'next/image'
|
||||||
|
import './styles.css'
|
||||||
|
import { useRouter } from 'next/navigation'
|
||||||
|
import { platform } from '@tauri-apps/plugin-os'
|
||||||
|
import { fetch } from '@tauri-apps/plugin-http'
|
||||||
|
import { verifySignature } from '@/lib/Util'
|
||||||
|
|
||||||
|
interface BaseEntry {
|
||||||
|
id: number
|
||||||
|
username: string
|
||||||
|
value: number
|
||||||
|
icon: number
|
||||||
|
overlay: number
|
||||||
|
birdColor: BirdColor
|
||||||
|
overlayColor: BirdColor
|
||||||
|
customIcon: string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Stats {
|
||||||
|
highScore: string
|
||||||
|
totalNormalBerries: string
|
||||||
|
totalPoisonBerries: string
|
||||||
|
totalSlowBerries: string
|
||||||
|
totalUltraBerries: string
|
||||||
|
totalSpeedyBerries: string
|
||||||
|
totalCoinBerries: string
|
||||||
|
totalRandomBerries: string
|
||||||
|
totalAntiBerries: string
|
||||||
|
totalGoldenBerries: string
|
||||||
|
coins: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface LeaderboardEntry extends BaseEntry {
|
||||||
|
type: 'leaderboard'
|
||||||
|
value: number
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Account extends BaseEntry {
|
||||||
|
type: 'account'
|
||||||
|
stats: Stats
|
||||||
|
xp: bigint
|
||||||
|
}
|
||||||
|
|
||||||
|
export function calculateXP (
|
||||||
|
normalBerries: bigint,
|
||||||
|
poisonBerries: bigint,
|
||||||
|
slowBerries: bigint,
|
||||||
|
ultraBerries: bigint,
|
||||||
|
speedyBerries: bigint,
|
||||||
|
coinBerries: bigint,
|
||||||
|
randomBerries: bigint,
|
||||||
|
antiBerries: bigint,
|
||||||
|
goldenBerries: bigint
|
||||||
|
): bigint {
|
||||||
|
let totalXp = 0n
|
||||||
|
totalXp += normalBerries
|
||||||
|
totalXp -= poisonBerries
|
||||||
|
totalXp -= slowBerries
|
||||||
|
totalXp += ultraBerries * 5n
|
||||||
|
totalXp += speedyBerries * 10n
|
||||||
|
totalXp += coinBerries * 10n
|
||||||
|
totalXp += randomBerries
|
||||||
|
totalXp -= antiBerries
|
||||||
|
totalXp += goldenBerries * 4n
|
||||||
|
|
||||||
|
if (totalXp < 0n) totalXp = 0n
|
||||||
|
return totalXp
|
||||||
|
}
|
||||||
|
|
||||||
|
export function calculateLevel (xp: bigint): number {
|
||||||
|
const levelDivisor = 50.0
|
||||||
|
|
||||||
|
const xpNumber = Number(xp)
|
||||||
|
const discriminant = 95 * 95 + levelDivisor * 2 * xpNumber
|
||||||
|
const level = (-95 + Math.sqrt(discriminant)) / levelDivisor
|
||||||
|
return Math.floor(level) + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function BerryDashLeaderboards () {
|
||||||
|
const [selected, setSelected] = useState<number>(-1)
|
||||||
|
const [selectedBerryOption, setSelectedBerryOption] = useState<number>(0)
|
||||||
|
const [entries, setEntries] = useState<(LeaderboardEntry | Account)[]>([])
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
const Refresh = useCallback(async () => {
|
||||||
|
try {
|
||||||
|
if (selected == 3 || selected == 4) {
|
||||||
|
const response = await fetch(
|
||||||
|
'https://games.lncvrt.xyz/api/berrydash/account?username='
|
||||||
|
)
|
||||||
|
const signature = response.headers.get('x-signature') ?? ''
|
||||||
|
const data = await response.json()
|
||||||
|
if (
|
||||||
|
(await verifySignature(JSON.stringify(data), signature)) &&
|
||||||
|
data.success
|
||||||
|
) {
|
||||||
|
let accounts = data.data as Account[]
|
||||||
|
|
||||||
|
accounts = accounts.map(acc => {
|
||||||
|
const xp = calculateXP(
|
||||||
|
BigInt(acc.stats.totalNormalBerries),
|
||||||
|
BigInt(acc.stats.totalPoisonBerries),
|
||||||
|
BigInt(acc.stats.totalSlowBerries),
|
||||||
|
BigInt(acc.stats.totalUltraBerries),
|
||||||
|
BigInt(acc.stats.totalSpeedyBerries),
|
||||||
|
BigInt(acc.stats.totalCoinBerries),
|
||||||
|
BigInt(acc.stats.totalRandomBerries),
|
||||||
|
BigInt(acc.stats.totalAntiBerries),
|
||||||
|
BigInt(acc.stats.totalGoldenBerries)
|
||||||
|
)
|
||||||
|
return { ...acc, xp }
|
||||||
|
})
|
||||||
|
|
||||||
|
accounts.sort((a, b) => (b.xp > a.xp ? 1 : b.xp < a.xp ? -1 : 0))
|
||||||
|
|
||||||
|
setEntries(accounts)
|
||||||
|
} else console.log('Failed')
|
||||||
|
} else {
|
||||||
|
const response = await fetch(
|
||||||
|
'https://games.lncvrt.xyz/api/berrydash/leaderboard/' +
|
||||||
|
(selected == 0
|
||||||
|
? 'score'
|
||||||
|
: selected == 1
|
||||||
|
? 'berry?berry=' + selectedBerryOption
|
||||||
|
: selected == 2
|
||||||
|
? 'coin'
|
||||||
|
: selected == 5
|
||||||
|
? 'legacy'
|
||||||
|
: 'total')
|
||||||
|
)
|
||||||
|
const signature = response.headers.get('x-signature') ?? ''
|
||||||
|
const data = await response.json()
|
||||||
|
if (
|
||||||
|
(await verifySignature(JSON.stringify(data), signature)) &&
|
||||||
|
data.success
|
||||||
|
)
|
||||||
|
setEntries(data.data as LeaderboardEntry[])
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
setEntries([])
|
||||||
|
}
|
||||||
|
}, [selected, selectedBerryOption])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
document.title = 'Lncvrt Games - Berry Dash Leaderboards'
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (selected != -1) setTimeout(() => Refresh(), 0)
|
||||||
|
}, [selected, Refresh])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='mx-4 mt-4'>
|
||||||
|
<div className='flex justify-between items-center mb-4'>
|
||||||
|
<p className='text-3xl'>Berry Dash Leaderboards</p>
|
||||||
|
<div className='flex gap-2'>
|
||||||
|
<button
|
||||||
|
className='button btntheme1'
|
||||||
|
onClick={() => {
|
||||||
|
setEntries([])
|
||||||
|
Refresh()
|
||||||
|
}}
|
||||||
|
title='Click to refresh the leaderboards.'
|
||||||
|
hidden={selected == -1}
|
||||||
|
>
|
||||||
|
Refresh
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className='button btntheme1'
|
||||||
|
onClick={() => {
|
||||||
|
if (selected == -1) router.push('/game?id=1')
|
||||||
|
else {
|
||||||
|
setSelected(-1)
|
||||||
|
setSelectedBerryOption(0)
|
||||||
|
setEntries([])
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
title='Click to go up a level.'
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={`box ${
|
||||||
|
platform() == 'windows'
|
||||||
|
? 'h-[calc(100vh-116px)]'
|
||||||
|
: 'h-[calc(100vh-84px)]'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{selected == -1 ? (
|
||||||
|
<>
|
||||||
|
<p className='text-center mt-2 text-xl'>Select a Leaderboard</p>
|
||||||
|
<div className='flex flex-col gap-2 mt-2 items-center justify-center'>
|
||||||
|
<button
|
||||||
|
className='leaderboard-button'
|
||||||
|
onClick={() => setSelected(0)}
|
||||||
|
>
|
||||||
|
Score Leaderboard
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className='leaderboard-button'
|
||||||
|
onClick={() => setSelected(1)}
|
||||||
|
>
|
||||||
|
Berry Leaderboard
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className='leaderboard-button'
|
||||||
|
onClick={() => setSelected(2)}
|
||||||
|
>
|
||||||
|
Coins Leaderboard
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className='leaderboard-button'
|
||||||
|
onClick={() => setSelected(3)}
|
||||||
|
>
|
||||||
|
Level Leaderboard
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className='leaderboard-button'
|
||||||
|
onClick={() => setSelected(4)}
|
||||||
|
>
|
||||||
|
Total XP Leaderboard
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className='leaderboard-button'
|
||||||
|
onClick={() => setSelected(5)}
|
||||||
|
>
|
||||||
|
Legacy Leaderboard
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className='leaderboard-button'
|
||||||
|
onClick={() => setSelected(6)}
|
||||||
|
>
|
||||||
|
Total Berries Leaderboard
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<div
|
||||||
|
className={`flex flex-col gap-2 overflow-y-auto ${
|
||||||
|
selected == 1
|
||||||
|
? platform() == 'windows'
|
||||||
|
? 'h-[calc(100vh-156px)]'
|
||||||
|
: 'h-[calc(100vh-124px)]'
|
||||||
|
: platform() == 'windows'
|
||||||
|
? 'h-[calc(100vh-128px)]'
|
||||||
|
: 'h-[calc(100vh-96px)]'
|
||||||
|
} px-1`}
|
||||||
|
>
|
||||||
|
{entries.map((item, index) => {
|
||||||
|
const isAccount = 'stats' in item
|
||||||
|
const isLeaderboard = 'value' in item && !isAccount
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={item.id}
|
||||||
|
className='leaderboard-entry flex justify-between items-center'
|
||||||
|
>
|
||||||
|
<div className='flex items-center gap-1'>
|
||||||
|
<Image
|
||||||
|
src={
|
||||||
|
!item.customIcon
|
||||||
|
? `https://games.lncvrt.xyz/api/berrydash/render-icon?icon=${
|
||||||
|
item.icon == 1
|
||||||
|
? GetIconForUser(item.id)
|
||||||
|
: item.icon
|
||||||
|
}&overlay=${item.overlay}&birdR=${
|
||||||
|
item.birdColor[0]
|
||||||
|
}&birdG=${item.birdColor[1]}&birdB=${
|
||||||
|
item.birdColor[2]
|
||||||
|
}&overlayR=${item.overlayColor[0]}&overlayG=${
|
||||||
|
item.overlayColor[1]
|
||||||
|
}&overlayB=${item.overlayColor[2]}`
|
||||||
|
: `https://games.lncvrt.xyz/api/berrydash/icon-marketplace/icon?id=${item.customIcon}&raw=true`
|
||||||
|
}
|
||||||
|
width={48}
|
||||||
|
height={48}
|
||||||
|
alt=''
|
||||||
|
className='pointer-events-none scale-x-[-1]'
|
||||||
|
/>
|
||||||
|
<p>
|
||||||
|
{item.username} (#{index + 1})
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{isLeaderboard ? (
|
||||||
|
<p>
|
||||||
|
{selected === 1 || selected === 6
|
||||||
|
? 'Berries'
|
||||||
|
: selected === 2
|
||||||
|
? 'Coins'
|
||||||
|
: 'Score'}
|
||||||
|
: {item.value.toLocaleString()}
|
||||||
|
</p>
|
||||||
|
) : isAccount ? (
|
||||||
|
<p>
|
||||||
|
{selected === 3 ? 'Level' : 'XP'}:{' '}
|
||||||
|
{selected === 3
|
||||||
|
? calculateLevel(item.xp).toLocaleString()
|
||||||
|
: item.xp.toLocaleString()}
|
||||||
|
</p>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
{selected == 1 && (
|
||||||
|
<div className='flex justify-center'>
|
||||||
|
<select
|
||||||
|
className='mt-1.25 bg-(--col2) border border-(--col4) rounded-md'
|
||||||
|
value={selectedBerryOption}
|
||||||
|
onChange={e => setSelectedBerryOption(Number(e.target.value))}
|
||||||
|
>
|
||||||
|
<option value='0'>Normal Berry</option>
|
||||||
|
<option value='1'>Poison Berry</option>
|
||||||
|
<option value='2'>Slow Berry</option>
|
||||||
|
<option value='3'>Ultra Berry</option>
|
||||||
|
<option value='4'>Speedy Berry</option>
|
||||||
|
<option value='5'>Coin Berry</option>
|
||||||
|
<option value='6'>Random Berry</option>
|
||||||
|
<option value='7'>Anti Berry</option>
|
||||||
|
<option value='8'>Golden Berry</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
@import "tailwindcss";
|
||||||
|
|
||||||
|
.box {
|
||||||
|
@apply bg-(--col1) border border-(--col3) rounded-lg w-auto p-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leaderboard-button {
|
||||||
|
@apply bg-(--col2) hover:bg-(--col4) border border-(--col4) hover:border-(--col6) rounded-lg px-4 py-2 inline-block transition-all duration-200 cursor-pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leaderboard-entry {
|
||||||
|
@apply rounded-lg text-gray-200 text-lg px-1 py-0.5 transition-colors bg-(--col2) hover:bg-(--col3) border border-(--col4) hover:border-(--col5) cursor-pointer;
|
||||||
|
}
|
||||||
@@ -1,17 +1,20 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import { platform } from '@tauri-apps/plugin-os'
|
import '@/app/Installs.css'
|
||||||
import '../Installs.css'
|
|
||||||
import { format } from 'date-fns'
|
|
||||||
import { invoke } from '@tauri-apps/api/core'
|
import { invoke } from '@tauri-apps/api/core'
|
||||||
import { message } from '@tauri-apps/plugin-dialog'
|
import { useGlobal } from '@/app/GlobalProvider'
|
||||||
import { useGlobal } from '../GlobalProvider'
|
import { useRouter, useSearchParams } from 'next/navigation'
|
||||||
import { useSearchParams } from 'next/navigation'
|
import { platform } from '@tauri-apps/plugin-os'
|
||||||
|
import { faWarning } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
|
import { ask } from '@tauri-apps/plugin-dialog'
|
||||||
|
import { BaseDirectory, exists, remove } from '@tauri-apps/plugin-fs'
|
||||||
|
import { writeVersionsConfig } from '@/lib/BazookaManager'
|
||||||
|
import { openFolder } from '@/lib/Util'
|
||||||
|
|
||||||
export default function Installs () {
|
export default function Installs () {
|
||||||
const {
|
const {
|
||||||
downloadProgress,
|
|
||||||
showPopup,
|
showPopup,
|
||||||
setShowPopup,
|
setShowPopup,
|
||||||
setPopupMode,
|
setPopupMode,
|
||||||
@@ -21,131 +24,384 @@ export default function Installs () {
|
|||||||
normalConfig,
|
normalConfig,
|
||||||
setManagingVersion,
|
setManagingVersion,
|
||||||
getVersionInfo,
|
getVersionInfo,
|
||||||
getVersionGame,
|
getGameInfo,
|
||||||
setSelectedGame
|
setSelectedGame,
|
||||||
|
serverVersionList,
|
||||||
|
category,
|
||||||
|
setCategory,
|
||||||
|
setDownloadedVersionsConfig,
|
||||||
|
downloadVersions,
|
||||||
|
downloadProgress
|
||||||
} = useGlobal()
|
} = useGlobal()
|
||||||
|
|
||||||
const params = useSearchParams()
|
const params = useSearchParams()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
const id = Number(params.get('id') || 0)
|
||||||
|
const game = serverVersionList?.games.find(g => g.id === id)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!showPopup) return
|
if (!showPopup) return
|
||||||
setSelectedVersionList([])
|
setSelectedVersionList([])
|
||||||
}, [normalConfig, setSelectedVersionList, showPopup])
|
}, [normalConfig, setSelectedVersionList, showPopup])
|
||||||
|
|
||||||
|
if (!id || !game) return <p>Invalid game</p>
|
||||||
|
|
||||||
|
const needsRevisionUpdate = (
|
||||||
|
lastRevision: number | undefined,
|
||||||
|
version: string
|
||||||
|
) => {
|
||||||
|
if (!lastRevision) return false
|
||||||
|
return (
|
||||||
|
lastRevision > 0 &&
|
||||||
|
(downloadedVersionsConfig == undefined
|
||||||
|
? 0
|
||||||
|
: downloadedVersionsConfig?.list[version]) /
|
||||||
|
1000 <=
|
||||||
|
lastRevision
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='mx-4 mt-4'>
|
<div className='mx-4 mt-4'>
|
||||||
<div className='flex justify-between items-center mb-4'>
|
<div className='flex justify-between items-center mb-4'>
|
||||||
<p className='text-3xl'>Installs</p>
|
<p
|
||||||
<button
|
className={`text-3xl truncate ${
|
||||||
className='button text-3xl'
|
category != -1
|
||||||
onClick={() => {
|
? 'w-[calc(100vw-495px)]'
|
||||||
setSelectedGame(Number(params.get('id') || 0))
|
: game.id == 1
|
||||||
setPopupMode(0)
|
? 'w-[calc(100vw-560px)]'
|
||||||
setShowPopup(true)
|
: 'w-[calc(100vw-440px)]'
|
||||||
setFadeOut(false)
|
}`}
|
||||||
}}
|
|
||||||
disabled={downloadProgress.length != 0}
|
|
||||||
>
|
>
|
||||||
Download versions
|
{game.name} Installs
|
||||||
</button>
|
</p>
|
||||||
|
<div className='flex gap-2'>
|
||||||
|
<button
|
||||||
|
className='button btntheme1'
|
||||||
|
onClick={() => {
|
||||||
|
router.push('/game/berrydash/leaderboards')
|
||||||
|
}}
|
||||||
|
title='View the leaderboards for this game.'
|
||||||
|
hidden={game.id != 1}
|
||||||
|
>
|
||||||
|
Leaderboards
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className='button btntheme1'
|
||||||
|
onClick={() => {
|
||||||
|
setCategory(-1)
|
||||||
|
}}
|
||||||
|
title='Click to go up a level.'
|
||||||
|
hidden={category == -1}
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className='button btntheme1'
|
||||||
|
onClick={() => {
|
||||||
|
setSelectedGame(id)
|
||||||
|
setPopupMode(0)
|
||||||
|
setShowPopup(true)
|
||||||
|
setFadeOut(false)
|
||||||
|
}}
|
||||||
|
title='Click to download more versions of this game.'
|
||||||
|
>
|
||||||
|
Download versions
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='downloads-container'>
|
<div className='downloads-container'>
|
||||||
<div className='downloads-scroll'>
|
<div
|
||||||
{downloadedVersionsConfig && downloadedVersionsConfig.list.length ? (
|
className={`downloads-scroll ${
|
||||||
downloadedVersionsConfig.list
|
platform() == 'windows'
|
||||||
.filter(v => {
|
? 'h-[calc(100vh-116px)]'
|
||||||
const info = getVersionInfo(v)
|
: 'h-[calc(100vh-84px)]'
|
||||||
if (!info) return false
|
}`}
|
||||||
return info.game === Number(params.get('id') || 0)
|
>
|
||||||
|
{category == -1 &&
|
||||||
|
Object.entries(game.categoryNames)
|
||||||
|
.sort(([a], [b]) => Number(b) - Number(a))
|
||||||
|
.filter(([key]) => {
|
||||||
|
const count = Object.keys(
|
||||||
|
downloadedVersionsConfig?.list ?? {}
|
||||||
|
).filter(v => {
|
||||||
|
const info = getVersionInfo(v)
|
||||||
|
if (!info) return false
|
||||||
|
|
||||||
|
if (
|
||||||
|
platform() == 'linux' &&
|
||||||
|
info.wine &&
|
||||||
|
!normalConfig?.settings.useWineOnUnixWhenNeeded
|
||||||
|
)
|
||||||
|
return false
|
||||||
|
|
||||||
|
return info.game === id && info.category === Number(key)
|
||||||
|
}).length
|
||||||
|
|
||||||
|
return count >= 1
|
||||||
})
|
})
|
||||||
|
.map(([key, value]) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={key}
|
||||||
|
className={'downloads-entry'}
|
||||||
|
title={'Click to view category'}
|
||||||
|
onClick={() => setCategory(Number(key))}
|
||||||
|
>
|
||||||
|
<div className='h-18 w-screen relative'>
|
||||||
|
<p className='text-2xl'>{value}</p>
|
||||||
|
|
||||||
|
<div
|
||||||
|
className='entry-info-item flex absolute left-0 bottom-0'
|
||||||
|
title='The amount of versions installed of this game in installed/installable format.'
|
||||||
|
onClick={e => e.stopPropagation()}
|
||||||
|
>
|
||||||
|
<p>
|
||||||
|
{(() => {
|
||||||
|
const count =
|
||||||
|
Object.keys(
|
||||||
|
downloadedVersionsConfig?.list ?? []
|
||||||
|
).filter(v => {
|
||||||
|
const info = getVersionInfo(v)
|
||||||
|
if (!info) return false
|
||||||
|
if (
|
||||||
|
platform() == 'linux' &&
|
||||||
|
info.wine &&
|
||||||
|
!normalConfig?.settings
|
||||||
|
.useWineOnUnixWhenNeeded
|
||||||
|
)
|
||||||
|
return false
|
||||||
|
return (
|
||||||
|
info.game === id &&
|
||||||
|
info.category == Number(key)
|
||||||
|
)
|
||||||
|
}).length ?? 0
|
||||||
|
return `${count} install${count === 1 ? '' : 's'}`
|
||||||
|
})()}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
{Object.keys(downloadedVersionsConfig?.list ?? []).filter(v => {
|
||||||
|
const info = getVersionInfo(v)
|
||||||
|
if (!info) return false
|
||||||
|
return info.game === id
|
||||||
|
}).length != 0 ? (
|
||||||
|
Object.keys(downloadedVersionsConfig?.list ?? [])
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
const infoA = getVersionInfo(a)
|
const infoA = getVersionInfo(a)
|
||||||
const infoB = getVersionInfo(b)
|
const infoB = getVersionInfo(b)
|
||||||
if (!infoA && !infoB) return 0
|
if (!infoA || !infoB) return -1
|
||||||
if (!infoA) return 1
|
|
||||||
if (!infoB) return -1
|
|
||||||
return infoB.place - infoA.place
|
return infoB.place - infoA.place
|
||||||
})
|
})
|
||||||
.map((entry, i) => (
|
.filter(v => {
|
||||||
<div key={i} className='downloads-entry'>
|
const info = getVersionInfo(v)
|
||||||
<div className='flex flex-col'>
|
if (!info) return false
|
||||||
|
if (
|
||||||
|
platform() == 'linux' &&
|
||||||
|
info.wine &&
|
||||||
|
!normalConfig?.settings.useWineOnUnixWhenNeeded
|
||||||
|
)
|
||||||
|
return false
|
||||||
|
return (
|
||||||
|
info.game === id &&
|
||||||
|
(category == -1
|
||||||
|
? info.category == -1
|
||||||
|
: info.category == category)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.map(entry => (
|
||||||
|
<div
|
||||||
|
key={entry}
|
||||||
|
className={'downloads-entry'}
|
||||||
|
title={
|
||||||
|
'Click to launch game. Right-click to manage this version install'
|
||||||
|
}
|
||||||
|
onClick={async () => {
|
||||||
|
if (
|
||||||
|
needsRevisionUpdate(
|
||||||
|
getVersionInfo(entry)?.lastRevision,
|
||||||
|
entry
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
const answer = await ask(
|
||||||
|
'Before proceeding, if you do not want your installation directory wiped just yet, please backup the files to another directory. When you click "Yes", it will be wiped. Click "No" if you want to open the installation folder instead.',
|
||||||
|
{
|
||||||
|
title: 'Revision Update',
|
||||||
|
kind: 'warning'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if (answer) {
|
||||||
|
const answer2 = await ask(
|
||||||
|
'Are you sure you want to update? If you did not read the last popup, please go back and read it.',
|
||||||
|
{
|
||||||
|
title: 'Revision Update',
|
||||||
|
kind: 'warning'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if (!answer2) return
|
||||||
|
|
||||||
|
//open downloads popup
|
||||||
|
setPopupMode(1)
|
||||||
|
setShowPopup(true)
|
||||||
|
setFadeOut(false)
|
||||||
|
|
||||||
|
//uninstall
|
||||||
|
setDownloadedVersionsConfig(prev => {
|
||||||
|
if (!prev) return prev
|
||||||
|
const updatedList = Object.fromEntries(
|
||||||
|
Object.entries(prev.list).filter(
|
||||||
|
([k]) => k !== entry
|
||||||
|
)
|
||||||
|
)
|
||||||
|
const updatedConfig = {
|
||||||
|
...prev,
|
||||||
|
list: updatedList
|
||||||
|
}
|
||||||
|
writeVersionsConfig(updatedConfig)
|
||||||
|
return updatedConfig
|
||||||
|
})
|
||||||
|
|
||||||
|
if (
|
||||||
|
await exists('game/' + entry, {
|
||||||
|
baseDir: BaseDirectory.AppLocalData
|
||||||
|
})
|
||||||
|
)
|
||||||
|
await remove('game/' + entry, {
|
||||||
|
baseDir: BaseDirectory.AppLocalData,
|
||||||
|
recursive: true
|
||||||
|
})
|
||||||
|
|
||||||
|
//reinstall
|
||||||
|
setSelectedVersionList([entry])
|
||||||
|
downloadVersions([
|
||||||
|
{
|
||||||
|
id: entry,
|
||||||
|
type: 0
|
||||||
|
}
|
||||||
|
])
|
||||||
|
} else {
|
||||||
|
openFolder(entry)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const verInfo = getVersionInfo(entry)
|
||||||
|
if (verInfo == undefined) return
|
||||||
|
const gameInfo = getGameInfo(verInfo.game)
|
||||||
|
if (gameInfo == undefined) return
|
||||||
|
invoke('launch_game', {
|
||||||
|
name: verInfo.id,
|
||||||
|
executable: verInfo.executable,
|
||||||
|
displayName: verInfo.displayName,
|
||||||
|
useWine: !!(
|
||||||
|
platform() == 'linux' &&
|
||||||
|
verInfo.wine &&
|
||||||
|
normalConfig?.settings.useWineOnUnixWhenNeeded
|
||||||
|
),
|
||||||
|
wineCommand: normalConfig?.settings.wineOnUnixCommand
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
onContextMenu={e => {
|
||||||
|
e.preventDefault()
|
||||||
|
setManagingVersion(entry)
|
||||||
|
setPopupMode(2)
|
||||||
|
setShowPopup(true)
|
||||||
|
setFadeOut(false)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className='h-18 w-screen relative'>
|
||||||
<p className='text-2xl'>
|
<p className='text-2xl'>
|
||||||
{getVersionGame(getVersionInfo(entry)?.game)?.name} v
|
{getVersionInfo(entry)?.displayName}{' '}
|
||||||
{getVersionInfo(entry)?.versionName}
|
|
||||||
</p>
|
</p>
|
||||||
<p className='text-gray-400 text-md'>
|
|
||||||
Installed{' '}
|
<div className='flex gap-2 absolute left-0 bottom-0'>
|
||||||
{format(
|
<div
|
||||||
new Date(downloadedVersionsConfig.timestamps[entry]),
|
className='entry-info-item'
|
||||||
'MM/dd/yyyy'
|
title='The date the game was installed.'
|
||||||
)}
|
>
|
||||||
</p>
|
<p>
|
||||||
</div>
|
Installed{' '}
|
||||||
<div className='flex flex-row items-center gap-2'>
|
{new Intl.DateTimeFormat(undefined).format(
|
||||||
|
downloadedVersionsConfig?.list[entry]
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className='entry-info-item'
|
||||||
|
title='This version is using wine. It cannot be guarenteed to work fully and might not work at all.'
|
||||||
|
hidden={
|
||||||
|
!(
|
||||||
|
platform() == 'linux' && getVersionInfo(entry)?.wine
|
||||||
|
) ||
|
||||||
|
needsRevisionUpdate(
|
||||||
|
getVersionInfo(entry)?.lastRevision,
|
||||||
|
entry
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faWarning} color='#ffc800' />
|
||||||
|
<p>Uses wine</p>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className='entry-info-item'
|
||||||
|
hidden={
|
||||||
|
!needsRevisionUpdate(
|
||||||
|
getVersionInfo(entry)?.lastRevision,
|
||||||
|
entry
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faWarning} color='#ffc800' />
|
||||||
|
<p>Needs revision update!</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<button
|
<button
|
||||||
className='button'
|
className='absolute right-0 bottom-0 button'
|
||||||
onClick={async () => {
|
title='Click to manage mods for this game!'
|
||||||
|
onClick={async e => {
|
||||||
|
e.stopPropagation()
|
||||||
|
|
||||||
|
if (
|
||||||
|
!(await exists('game/' + entry + '/BepInEx', {
|
||||||
|
baseDir: BaseDirectory.AppLocalData
|
||||||
|
}))
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
(await ask(
|
||||||
|
"You don't have BepInEx (the mod loader for Unity Games), would you like to install it now? It is about 1MB in size. If you choose yes, it will download the recommended BepInEx version for " +
|
||||||
|
getVersionInfo(entry)?.displayName +
|
||||||
|
'.',
|
||||||
|
{ title: 'BepInEx not found!', kind: 'error' }
|
||||||
|
)) &&
|
||||||
|
!downloadProgress.find(d => d.version == entry)
|
||||||
|
) {
|
||||||
|
downloadVersions([
|
||||||
|
{
|
||||||
|
id: entry,
|
||||||
|
type: 1
|
||||||
|
}
|
||||||
|
])
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
setManagingVersion(entry)
|
setManagingVersion(entry)
|
||||||
setPopupMode(2)
|
setPopupMode(3)
|
||||||
setShowPopup(true)
|
setShowPopup(true)
|
||||||
setFadeOut(false)
|
setFadeOut(false)
|
||||||
}}
|
}}
|
||||||
|
hidden={!getVersionInfo(entry)?.modSupportDownload}
|
||||||
>
|
>
|
||||||
Manage
|
Mod Manager
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className='button button-green'
|
|
||||||
onClick={async () => {
|
|
||||||
const verInfo = getVersionInfo(entry)
|
|
||||||
if (verInfo == undefined) return
|
|
||||||
let plat = platform()
|
|
||||||
let willUseWine = false
|
|
||||||
let cfg = null
|
|
||||||
while (normalConfig != null) {
|
|
||||||
cfg = normalConfig
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if (plat === 'macos' || plat === 'linux') {
|
|
||||||
if (
|
|
||||||
!verInfo.platforms.includes(plat) &&
|
|
||||||
verInfo.platforms.includes('windows')
|
|
||||||
) {
|
|
||||||
if (
|
|
||||||
cfg != null &&
|
|
||||||
!cfg.settings.useWineOnUnixWhenNeeded
|
|
||||||
) {
|
|
||||||
await message(
|
|
||||||
'Wine support is disabled in settings and this version requires wine',
|
|
||||||
{
|
|
||||||
title: 'Wine is needed to load this version',
|
|
||||||
kind: 'error'
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
plat = 'windows'
|
|
||||||
willUseWine = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
invoke('launch_game', {
|
|
||||||
name: verInfo.id,
|
|
||||||
executable:
|
|
||||||
verInfo.executables[
|
|
||||||
verInfo.platforms.indexOf(plat)
|
|
||||||
],
|
|
||||||
wine: willUseWine,
|
|
||||||
wineCommand: cfg?.settings.wineOnUnixCommand
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Launch
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<div className='flex justify-center items-center h-full'>
|
<div className='flex justify-center items-center h-full'>
|
||||||
<p className='text-3xl'>No games installed</p>
|
<p className='text-3xl'>No versions installed</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import { platform } from '@tauri-apps/plugin-os'
|
|
||||||
import './Installs.css'
|
import './Installs.css'
|
||||||
import { format } from 'date-fns'
|
|
||||||
import { invoke } from '@tauri-apps/api/core'
|
|
||||||
import { message } from '@tauri-apps/plugin-dialog'
|
|
||||||
import { useGlobal } from './GlobalProvider'
|
import { useGlobal } from './GlobalProvider'
|
||||||
import Link from 'next/link'
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
|
import {
|
||||||
|
faCheck,
|
||||||
|
faShieldHalved,
|
||||||
|
faWarning
|
||||||
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
|
import { platform } from '@tauri-apps/plugin-os'
|
||||||
|
import { useRouter } from 'next/navigation'
|
||||||
|
|
||||||
export default function Installs () {
|
export default function Installs () {
|
||||||
const {
|
const {
|
||||||
downloadProgress,
|
|
||||||
showPopup,
|
showPopup,
|
||||||
setShowPopup,
|
setShowPopup,
|
||||||
setPopupMode,
|
setPopupMode,
|
||||||
@@ -19,13 +21,14 @@ export default function Installs () {
|
|||||||
setSelectedVersionList,
|
setSelectedVersionList,
|
||||||
downloadedVersionsConfig,
|
downloadedVersionsConfig,
|
||||||
normalConfig,
|
normalConfig,
|
||||||
setManagingVersion,
|
|
||||||
getVersionInfo,
|
|
||||||
getVersionGame,
|
|
||||||
setSelectedGame,
|
setSelectedGame,
|
||||||
getListOfGames
|
getListOfGames,
|
||||||
|
getVersionsAmountData,
|
||||||
|
setCategory
|
||||||
} = useGlobal()
|
} = useGlobal()
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!showPopup) return
|
if (!showPopup) return
|
||||||
setSelectedVersionList([])
|
setSelectedVersionList([])
|
||||||
@@ -36,34 +39,86 @@ export default function Installs () {
|
|||||||
<div className='flex justify-between items-center mb-4'>
|
<div className='flex justify-between items-center mb-4'>
|
||||||
<p className='text-3xl'>Games</p>
|
<p className='text-3xl'>Games</p>
|
||||||
<button
|
<button
|
||||||
className='button text-3xl'
|
className='button btntheme1'
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setSelectedGame(null)
|
setSelectedGame(null)
|
||||||
setPopupMode(0)
|
setPopupMode(0)
|
||||||
setShowPopup(true)
|
setShowPopup(true)
|
||||||
setFadeOut(false)
|
setFadeOut(false)
|
||||||
}}
|
}}
|
||||||
disabled={downloadProgress.length != 0}
|
title='Click to download more games.'
|
||||||
>
|
>
|
||||||
Download game
|
Download game
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className='downloads-container'>
|
<div className='downloads-container'>
|
||||||
<div className='downloads-scroll'>
|
<div
|
||||||
{downloadedVersionsConfig && downloadedVersionsConfig.list.length ? (
|
className={`downloads-scroll ${
|
||||||
|
platform() == 'windows'
|
||||||
|
? 'h-[calc(100vh-116px)]'
|
||||||
|
: 'h-[calc(100vh-84px)]'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{downloadedVersionsConfig &&
|
||||||
|
Object.keys(downloadedVersionsConfig.list).length ? (
|
||||||
getListOfGames()
|
getListOfGames()
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
return a.id - b.id
|
return a.id - b.id
|
||||||
})
|
})
|
||||||
.map(i => (
|
.map(i => (
|
||||||
<div key={i.id} className='downloads-entry'>
|
<div
|
||||||
<div className='flex flex-col'>
|
key={i.id}
|
||||||
|
className={'downloads-entry'}
|
||||||
|
title={'Click to view game installs'}
|
||||||
|
onClick={() => {
|
||||||
|
setCategory(-1)
|
||||||
|
router.push('/game?id=' + i.id)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className='h-18 w-screen relative'>
|
||||||
<p className='text-2xl'>{i.name}</p>
|
<p className='text-2xl'>{i.name}</p>
|
||||||
</div>
|
|
||||||
<div className='flex flex-row items-center gap-2'>
|
<div className='flex gap-2 absolute left-0 bottom-0'>
|
||||||
<Link className='button' href={'/game?id=' + i.id}>
|
<div
|
||||||
Installs
|
className='entry-info-item'
|
||||||
</Link>
|
title='The amount of versions installed of this game in installed/installable format.'
|
||||||
|
onClick={e => e.stopPropagation()}
|
||||||
|
>
|
||||||
|
<p>
|
||||||
|
{(() => {
|
||||||
|
const data = getVersionsAmountData(i.id)
|
||||||
|
if (!data) return 'N/A'
|
||||||
|
return `${data.installed}/${data.total}`
|
||||||
|
})()}{' '}
|
||||||
|
versions installed
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className='entry-info-item'
|
||||||
|
hidden={!i.official}
|
||||||
|
title='This game is official.'
|
||||||
|
onClick={e => e.stopPropagation()}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faCheck} color='#19c84b' />
|
||||||
|
<p>Official</p>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className='entry-info-item'
|
||||||
|
hidden={i.official}
|
||||||
|
title={
|
||||||
|
i.verified
|
||||||
|
? 'This game is verified to be safe'
|
||||||
|
: 'This game is not verified to be save. Proceed with caution.'
|
||||||
|
}
|
||||||
|
onClick={e => e.stopPropagation()}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={i.verified ? faShieldHalved : faWarning}
|
||||||
|
color={i.verified ? '#19c84b' : '#ffc800'}
|
||||||
|
/>
|
||||||
|
<p>{i.verified ? 'Verified' : 'Unverified'}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))
|
))
|
||||||
|
|||||||
@@ -1,26 +1,35 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { Setting } from '../componets/Setting'
|
import { Setting } from '@/componets/Setting'
|
||||||
import { writeNormalConfig } from '../util/BazookaManager'
|
import { writeNormalConfig } from '@/lib/BazookaManager'
|
||||||
|
import { useGlobal } from '@/app/GlobalProvider'
|
||||||
|
import { copyToClipboard } from '@/lib/Clipboard'
|
||||||
import { platform } from '@tauri-apps/plugin-os'
|
import { platform } from '@tauri-apps/plugin-os'
|
||||||
import { useGlobal } from '../GlobalProvider'
|
|
||||||
|
|
||||||
export default function Settings () {
|
export default function Settings () {
|
||||||
const [allowNotifications, setAllowNotifications] = useState(false)
|
const [allowNotifications, setAllowNotifications] = useState(false)
|
||||||
|
const [alwaysShowGamesInSidebar, setAlwaysShowGamesInSidebar] =
|
||||||
|
useState(false)
|
||||||
const [useWineOnUnixWhenNeeded, setUseWineOnUnixWhenNeeded] = useState(false)
|
const [useWineOnUnixWhenNeeded, setUseWineOnUnixWhenNeeded] = useState(false)
|
||||||
const [wineOnUnixCommand, setWineOnUnixCommand] = useState('wine %path%')
|
const [wineOnUnixCommand, setWineOnUnixCommand] = useState('wine %path%')
|
||||||
|
const [theme, setTheme] = useState(0)
|
||||||
|
|
||||||
const [loaded, setLoaded] = useState(false)
|
const [loaded, setLoaded] = useState(false)
|
||||||
const { normalConfig } = useGlobal()
|
const { normalConfig, setNormalConfig, version } = useGlobal()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
;(async () => {
|
;(async () => {
|
||||||
while (normalConfig != null) {
|
while (normalConfig != null) {
|
||||||
|
setAllowNotifications(normalConfig.settings.allowNotifications)
|
||||||
|
setAlwaysShowGamesInSidebar(
|
||||||
|
normalConfig.settings.alwaysShowGamesInSidebar
|
||||||
|
)
|
||||||
setUseWineOnUnixWhenNeeded(
|
setUseWineOnUnixWhenNeeded(
|
||||||
normalConfig.settings.useWineOnUnixWhenNeeded
|
normalConfig.settings.useWineOnUnixWhenNeeded
|
||||||
)
|
)
|
||||||
setWineOnUnixCommand(normalConfig.settings.wineOnUnixCommand)
|
setWineOnUnixCommand(normalConfig.settings.wineOnUnixCommand)
|
||||||
setAllowNotifications(normalConfig.settings.allowNotifications)
|
setTheme(normalConfig.settings.theme)
|
||||||
setLoaded(true)
|
setLoaded(true)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -31,50 +40,146 @@ export default function Settings () {
|
|||||||
<>
|
<>
|
||||||
<p className='text-3xl ml-4 mt-4'>Settings</p>
|
<p className='text-3xl ml-4 mt-4'>Settings</p>
|
||||||
{loaded && (
|
{loaded && (
|
||||||
<div className='ml-4 mt-4 bg-[#161616] border border-[#242424] rounded-lg p-4 w-fit h-fit'>
|
<div className='ml-4 mt-4 bg-(--col1) border border-(--col3) rounded-lg p-4 w-fit h-fit'>
|
||||||
<Setting
|
<Setting
|
||||||
label='Allow sending notifications'
|
label='Allow sending notifications'
|
||||||
value={allowNotifications}
|
value={allowNotifications}
|
||||||
onChange={async () => {
|
onChange={async () => {
|
||||||
while (normalConfig != null) {
|
if (!normalConfig) return
|
||||||
setAllowNotifications(!allowNotifications)
|
setAllowNotifications(!allowNotifications)
|
||||||
normalConfig.settings.allowNotifications = !allowNotifications
|
setNormalConfig({
|
||||||
await writeNormalConfig(normalConfig)
|
...normalConfig,
|
||||||
break
|
settings: {
|
||||||
}
|
...normalConfig.settings,
|
||||||
|
allowNotifications: !allowNotifications
|
||||||
|
}
|
||||||
|
})
|
||||||
|
await writeNormalConfig({
|
||||||
|
...normalConfig,
|
||||||
|
settings: {
|
||||||
|
...normalConfig.settings,
|
||||||
|
allowNotifications: !allowNotifications
|
||||||
|
}
|
||||||
|
})
|
||||||
}}
|
}}
|
||||||
|
title='This setting does as you expect, allow the launcher to send notifications for when stuff like downloading is done.'
|
||||||
/>
|
/>
|
||||||
<Setting
|
<Setting
|
||||||
label='Use wine to launch Berry Dash when needed'
|
label='Always show games in sidebar'
|
||||||
|
value={alwaysShowGamesInSidebar}
|
||||||
|
onChange={async () => {
|
||||||
|
if (!normalConfig) return
|
||||||
|
setAlwaysShowGamesInSidebar(!alwaysShowGamesInSidebar)
|
||||||
|
setNormalConfig({
|
||||||
|
...normalConfig,
|
||||||
|
settings: {
|
||||||
|
...normalConfig.settings,
|
||||||
|
alwaysShowGamesInSidebar: !alwaysShowGamesInSidebar
|
||||||
|
}
|
||||||
|
})
|
||||||
|
await writeNormalConfig({
|
||||||
|
...normalConfig,
|
||||||
|
settings: {
|
||||||
|
...normalConfig.settings,
|
||||||
|
alwaysShowGamesInSidebar: !alwaysShowGamesInSidebar
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
title="This setting will make it so when you are on a page like this, the games won't disappear."
|
||||||
|
/>
|
||||||
|
<Setting
|
||||||
|
label='Use wine when needed to launch games'
|
||||||
value={useWineOnUnixWhenNeeded}
|
value={useWineOnUnixWhenNeeded}
|
||||||
onChange={async () => {
|
onChange={async () => {
|
||||||
while (normalConfig != null) {
|
if (!normalConfig) return
|
||||||
setUseWineOnUnixWhenNeeded(!useWineOnUnixWhenNeeded)
|
setUseWineOnUnixWhenNeeded(!useWineOnUnixWhenNeeded)
|
||||||
normalConfig.settings.useWineOnUnixWhenNeeded =
|
setNormalConfig({
|
||||||
!useWineOnUnixWhenNeeded
|
...normalConfig,
|
||||||
await writeNormalConfig(normalConfig)
|
settings: {
|
||||||
break
|
...normalConfig.settings,
|
||||||
}
|
useWineOnUnixWhenNeeded: !useWineOnUnixWhenNeeded
|
||||||
|
}
|
||||||
|
})
|
||||||
|
await writeNormalConfig({
|
||||||
|
...normalConfig,
|
||||||
|
settings: {
|
||||||
|
...normalConfig.settings,
|
||||||
|
useWineOnUnixWhenNeeded: !useWineOnUnixWhenNeeded
|
||||||
|
}
|
||||||
|
})
|
||||||
}}
|
}}
|
||||||
className={platform() == 'linux' ? '' : 'hidden'}
|
className={platform() == 'linux' ? '' : 'hidden'}
|
||||||
/>
|
/>
|
||||||
|
<p hidden={!(platform() == 'linux' && useWineOnUnixWhenNeeded)}>
|
||||||
|
Wine Command:
|
||||||
|
</p>
|
||||||
<input
|
<input
|
||||||
type='text'
|
type='text'
|
||||||
value={wineOnUnixCommand}
|
value={wineOnUnixCommand}
|
||||||
onChange={async e => {
|
onChange={async e => {
|
||||||
while (normalConfig != null) {
|
if (!normalConfig) return
|
||||||
setWineOnUnixCommand(e.target.value)
|
setWineOnUnixCommand(e.target.value)
|
||||||
normalConfig.settings.wineOnUnixCommand = e.target.value
|
setNormalConfig({
|
||||||
await writeNormalConfig(normalConfig)
|
...normalConfig,
|
||||||
break
|
settings: {
|
||||||
}
|
...normalConfig.settings,
|
||||||
|
wineOnUnixCommand: e.target.value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
await writeNormalConfig({
|
||||||
|
...normalConfig,
|
||||||
|
settings: {
|
||||||
|
...normalConfig.settings,
|
||||||
|
wineOnUnixCommand: e.target.value
|
||||||
|
}
|
||||||
|
})
|
||||||
}}
|
}}
|
||||||
className={`input-field ${
|
className={`input-field my-1 ${
|
||||||
platform() == 'linux' && useWineOnUnixWhenNeeded ? '' : 'hidden'
|
platform() == 'linux' && useWineOnUnixWhenNeeded ? '' : 'hidden'
|
||||||
}`}
|
}`}
|
||||||
></input>
|
></input>
|
||||||
|
<div title='The theme you want the launcher to use.'>
|
||||||
|
<label className='text-lg'>Theme:</label>
|
||||||
|
<select
|
||||||
|
className='ml-2 bg-(--col2) border border-(--col4) rounded-md'
|
||||||
|
value={theme}
|
||||||
|
onChange={async e => {
|
||||||
|
if (!normalConfig) return
|
||||||
|
const newTheme = parseInt(e.target.value)
|
||||||
|
setTheme(newTheme)
|
||||||
|
setNormalConfig({
|
||||||
|
...normalConfig,
|
||||||
|
settings: {
|
||||||
|
...normalConfig.settings,
|
||||||
|
theme: newTheme
|
||||||
|
}
|
||||||
|
})
|
||||||
|
await writeNormalConfig({
|
||||||
|
...normalConfig,
|
||||||
|
settings: {
|
||||||
|
...normalConfig.settings,
|
||||||
|
theme: newTheme
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<option value={0}>Dark (default)</option>
|
||||||
|
<option value={1}>Red</option>
|
||||||
|
<option value={2}>Blue</option>
|
||||||
|
<option value={3}>Purple</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
<p
|
||||||
|
className='fixed bottom-1.5 right-1.5 rounded-md cursor-pointer px-1 border z-100 transition-colors btntheme1'
|
||||||
|
onClick={async () => {
|
||||||
|
await copyToClipboard(`v${version}`, normalConfig)
|
||||||
|
}}
|
||||||
|
title='The current launcher version.'
|
||||||
|
>
|
||||||
|
v{version}
|
||||||
|
</p>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
export class DownloadProgress {
|
|
||||||
constructor(
|
|
||||||
public version: string,
|
|
||||||
public progress: number,
|
|
||||||
public failed: boolean,
|
|
||||||
public queued: boolean
|
|
||||||
) { }
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
export interface GameVersion {
|
|
||||||
id: string
|
|
||||||
versionName: string
|
|
||||||
releaseDate: number
|
|
||||||
downloadUrls: string[]
|
|
||||||
platforms: string[]
|
|
||||||
executables: string[]
|
|
||||||
game: number
|
|
||||||
place: number
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
export interface LeaderboardEntry {
|
|
||||||
username: string
|
|
||||||
userid: bigint
|
|
||||||
value: bigint
|
|
||||||
icon: number
|
|
||||||
overlay: number
|
|
||||||
birdColor: number[]
|
|
||||||
overlayColor: number[]
|
|
||||||
customIcon: string | null
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
import { LeaderboardEntry } from './LeaderboardEntry'
|
|
||||||
|
|
||||||
export interface LeaderboardResponse {
|
|
||||||
entries: LeaderboardEntry[]
|
|
||||||
customIcons: Record<string, string>
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
export class SettingsType {
|
|
||||||
constructor(
|
|
||||||
public allowNotifications: boolean = true,
|
|
||||||
public useWineOnUnixWhenNeeded: boolean = false,
|
|
||||||
public wineOnUnixCommand: string = 'wine %path%'
|
|
||||||
) { }
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
type VersionsConfigData = {
|
|
||||||
version: string
|
|
||||||
list: string[]
|
|
||||||
timestamps: Record<string, number>
|
|
||||||
}
|
|
||||||
|
|
||||||
export class VersionsConfig {
|
|
||||||
constructor(
|
|
||||||
public version: string,
|
|
||||||
public list: string[] = [],
|
|
||||||
public timestamps: Record<string, number> = {}
|
|
||||||
) { }
|
|
||||||
|
|
||||||
static import(data: VersionsConfigData) {
|
|
||||||
const cfg = new VersionsConfig(data.version)
|
|
||||||
cfg.list = [...data.list]
|
|
||||||
cfg.timestamps = { ...data.timestamps }
|
|
||||||
return cfg
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
After Width: | Height: | Size: 1.2 MiB |
@@ -0,0 +1,17 @@
|
|||||||
|
type ProgressBarProps = {
|
||||||
|
progress: number
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ProgressBar ({ progress, className }: ProgressBarProps) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={`w-full bg-(--col1) border border-(--col5) rounded-full h-4 overflow-hidden ${className}`}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className='bg-(--col8) border-r border-r-(--col5) h-full'
|
||||||
|
style={{ width: `${progress}%` }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -5,11 +5,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.setting-checkbox {
|
.setting-checkbox {
|
||||||
@apply appearance-none w-full h-full border-2 border-[#484848] rounded-md bg-[#242424] transition-colors duration-200 cursor-pointer;
|
@apply appearance-none w-full h-full border-2 border-(--col4) rounded-md bg-(--col2) transition-colors cursor-pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.setting-checkbox:checked {
|
.setting-checkbox:checked {
|
||||||
@apply bg-blue-500 border-blue-600;
|
@apply bg-(--col4) border-(--col6);
|
||||||
}
|
}
|
||||||
|
|
||||||
.fa-check-icon {
|
.fa-check-icon {
|
||||||
@@ -1,11 +1,17 @@
|
|||||||
import './Setting.css'
|
import './Setting.css'
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
import { faCheck } from '@fortawesome/free-solid-svg-icons'
|
import { faCheck } from '@fortawesome/free-solid-svg-icons'
|
||||||
import { SettingProps } from '../types/SettingProps'
|
import { SettingProps } from '@/types/SettingProps'
|
||||||
|
|
||||||
export function Setting ({ label, value, onChange, className }: SettingProps) {
|
export function Setting ({
|
||||||
|
label,
|
||||||
|
value,
|
||||||
|
onChange,
|
||||||
|
className,
|
||||||
|
title
|
||||||
|
}: SettingProps) {
|
||||||
return (
|
return (
|
||||||
<div className={`flex items-center gap-2 mb-2 ${className}`}>
|
<div className={`flex items-center gap-2 mb-2 ${className}`} title={title}>
|
||||||
<label className='text-white text-lg'>{label}</label>
|
<label className='text-white text-lg'>{label}</label>
|
||||||
<div className='setting-checkbox-wrapper'>
|
<div className='setting-checkbox-wrapper'>
|
||||||
<input
|
<input
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
@import "tailwindcss";
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
@apply fixed top-0 left-0 w-60 h-screen bg-(--col1) flex flex-col border-e border-(--col2) z-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-downloads {
|
||||||
|
@apply text-[#bdbdbd] fixed bottom-2 left-2 bg-(--col2) rounded-lg border border-(--col3) px-4 py-3 text-xl cursor-pointer transition-colors duration-[0.25s] opacity-75;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-downloads:hover {
|
||||||
|
@apply text-white opacity-100;
|
||||||
|
@apply bg-(--col3) border-(--col4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-links {
|
||||||
|
@apply flex flex-col px-4 space-y-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link {
|
||||||
|
@apply text-[#bdbdbd] p-2 rounded-md no-underline cursor-pointer transition-colors duration-[0.25s] border border-transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link.active {
|
||||||
|
@apply bg-(--col2) border-(--col3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.link.active,
|
||||||
|
.link:hover {
|
||||||
|
@apply text-white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link.active:hover {
|
||||||
|
@apply bg-(--col3) border-(--col4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar ::-webkit-scrollbar {
|
||||||
|
@apply hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.macos-drag {
|
||||||
|
@apply h-7 fixed top-0 left-0 w-60 -z-10;
|
||||||
|
}
|
||||||
@@ -0,0 +1,212 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import './Sidebar.css'
|
||||||
|
import Icon from '@/assets/Icon.png'
|
||||||
|
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
|
import {
|
||||||
|
faCog,
|
||||||
|
faDownload,
|
||||||
|
faGamepad,
|
||||||
|
faHexagonNodes,
|
||||||
|
faLayerGroup
|
||||||
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
|
import { faDiscord } from '@fortawesome/free-brands-svg-icons'
|
||||||
|
import { platform } from '@tauri-apps/plugin-os'
|
||||||
|
import { useGlobal } from '@/app/GlobalProvider'
|
||||||
|
import Image from 'next/image'
|
||||||
|
import Link from 'next/link'
|
||||||
|
import { usePathname, useRouter, useSearchParams } from 'next/navigation'
|
||||||
|
import { getCurrentWindow } from '@tauri-apps/api/window'
|
||||||
|
import { Lexend } from 'next/font/google'
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
const lexend = Lexend({
|
||||||
|
subsets: ['latin']
|
||||||
|
})
|
||||||
|
|
||||||
|
export default function Sidebar () {
|
||||||
|
const {
|
||||||
|
normalConfig,
|
||||||
|
getListOfGames,
|
||||||
|
setShowPopup,
|
||||||
|
setPopupMode,
|
||||||
|
setFadeOut,
|
||||||
|
downloadProgress,
|
||||||
|
downloadedVersionsConfig,
|
||||||
|
getVersionInfo,
|
||||||
|
category,
|
||||||
|
setCategory
|
||||||
|
} = useGlobal()
|
||||||
|
|
||||||
|
const pathname = usePathname()
|
||||||
|
const params = useSearchParams()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<aside className='sidebar'>
|
||||||
|
<div
|
||||||
|
className='macos-drag'
|
||||||
|
hidden={platform() != 'macos'}
|
||||||
|
onMouseDown={e => {
|
||||||
|
if (e.buttons === 1) {
|
||||||
|
if (e.detail === 2) {
|
||||||
|
getCurrentWindow().toggleMaximize()
|
||||||
|
} else {
|
||||||
|
getCurrentWindow().startDragging()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
className={`flex items-center h-10 w-60 ${
|
||||||
|
(platform() == 'windows' ? 'pl-1 pt-1' : 'pl-2 pt-2') +
|
||||||
|
(platform() == 'macos' ? ' mt-7' : '')
|
||||||
|
}`}
|
||||||
|
onMouseDown={e => {
|
||||||
|
if (platform() != 'macos') return
|
||||||
|
if (e.buttons === 1) {
|
||||||
|
if (e.detail === 2) {
|
||||||
|
getCurrentWindow().toggleMaximize()
|
||||||
|
} else {
|
||||||
|
getCurrentWindow().startDragging()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Image draggable={false} src={Icon} width={36} height={36} alt='' />
|
||||||
|
<p className={`ml-1 text-[16px] whitespace-nowrap ${lexend.className}`}>
|
||||||
|
Lncvrt Games Launcher
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<nav className='nav-links overflow-auto pt-2'>
|
||||||
|
<Link
|
||||||
|
draggable={false}
|
||||||
|
href='/'
|
||||||
|
className={`link relative flex items-center ${
|
||||||
|
pathname === '/' || pathname.startsWith('/game') ? 'active' : ''
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faHexagonNodes} className='mr-2' /> Games
|
||||||
|
</Link>
|
||||||
|
{getListOfGames()
|
||||||
|
.sort((a, b) => {
|
||||||
|
return a.id - b.id
|
||||||
|
})
|
||||||
|
.map(i => (
|
||||||
|
<React.Fragment key={i.id}>
|
||||||
|
<div
|
||||||
|
draggable={false}
|
||||||
|
className={`link ${
|
||||||
|
(pathname === '/game' &&
|
||||||
|
Number(params.get('id') || 0) == i.id) ||
|
||||||
|
(i.id == 1 && pathname === '/game/berrydash/leaderboards')
|
||||||
|
? 'active'
|
||||||
|
: ''
|
||||||
|
} ml-auto w-50 ${
|
||||||
|
normalConfig?.settings.alwaysShowGamesInSidebar ||
|
||||||
|
pathname === '/' ||
|
||||||
|
pathname.startsWith('/game')
|
||||||
|
? ''
|
||||||
|
: 'hidden'
|
||||||
|
}`}
|
||||||
|
onClick={() => {
|
||||||
|
setCategory(-1)
|
||||||
|
router.push('/game?id=' + i.id)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className='flex items-center'>
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={
|
||||||
|
Object.entries(i.categoryNames).length > 0
|
||||||
|
? faLayerGroup
|
||||||
|
: faGamepad
|
||||||
|
}
|
||||||
|
className='mr-1'
|
||||||
|
/>
|
||||||
|
<span className='truncate max-w-full'>{i.name}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{Object.entries(i.categoryNames)
|
||||||
|
.sort(([a], [b]) => Number(b) - Number(a))
|
||||||
|
.filter(([key]) => {
|
||||||
|
const count = Object.keys(
|
||||||
|
downloadedVersionsConfig?.list ?? {}
|
||||||
|
).filter(v => {
|
||||||
|
const info = getVersionInfo(v)
|
||||||
|
if (!info) return false
|
||||||
|
|
||||||
|
if (
|
||||||
|
platform() == 'linux' &&
|
||||||
|
info.wine &&
|
||||||
|
!normalConfig?.settings.useWineOnUnixWhenNeeded
|
||||||
|
)
|
||||||
|
return false
|
||||||
|
|
||||||
|
return info.game === i.id && info.category === Number(key)
|
||||||
|
}).length
|
||||||
|
|
||||||
|
return count >= 1
|
||||||
|
})
|
||||||
|
.map(([key, value]) => (
|
||||||
|
<div
|
||||||
|
key={`${i.id}-${key}`}
|
||||||
|
draggable={false}
|
||||||
|
className={`link ${
|
||||||
|
((pathname === '/game' &&
|
||||||
|
Number(params.get('id') || 0) == i.id) ||
|
||||||
|
(i.id == 1 &&
|
||||||
|
pathname === '/game/berrydash/leaderboards')) &&
|
||||||
|
category == Number(key)
|
||||||
|
? 'active'
|
||||||
|
: ''
|
||||||
|
} ml-auto w-47.5 ${
|
||||||
|
normalConfig?.settings.alwaysShowGamesInSidebar ||
|
||||||
|
pathname === '/' ||
|
||||||
|
pathname.startsWith('/game')
|
||||||
|
? ''
|
||||||
|
: 'hidden'
|
||||||
|
}`}
|
||||||
|
onClick={() => {
|
||||||
|
setCategory(Number(key))
|
||||||
|
router.push('/game?id=' + i.id)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className='flex items-center'>
|
||||||
|
<FontAwesomeIcon icon={faGamepad} className='mr-1' />
|
||||||
|
<span className='truncate max-w-full'>{value}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
|
<Link
|
||||||
|
draggable={false}
|
||||||
|
href='/settings'
|
||||||
|
className={`link ${pathname === '/settings' ? 'active' : ''}`}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faCog} className='mr-1' /> Settings
|
||||||
|
</Link>
|
||||||
|
<button
|
||||||
|
onClick={() => openUrl('https://games.lncvrt.xyz/discord')}
|
||||||
|
className='link mr-auto'
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faDiscord} className='mr-1' /> Community
|
||||||
|
</button>
|
||||||
|
</nav>
|
||||||
|
<div
|
||||||
|
className='sidebar-downloads'
|
||||||
|
hidden={downloadProgress.length == 0}
|
||||||
|
onClick={() => {
|
||||||
|
setPopupMode(1)
|
||||||
|
setShowPopup(true)
|
||||||
|
setFadeOut(false)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<p>
|
||||||
|
<FontAwesomeIcon icon={faDownload} /> Downloads
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,240 @@
|
|||||||
|
import { useGlobal } from '@/app/GlobalProvider'
|
||||||
|
import prettyBytes from 'pretty-bytes'
|
||||||
|
import ProgressBar from '../ProgressBar'
|
||||||
|
import { formatEtaSmart } from '@/lib/Util'
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
|
import {
|
||||||
|
faCancel,
|
||||||
|
faPause,
|
||||||
|
faPlay,
|
||||||
|
faTrash
|
||||||
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
|
import { invoke } from '@tauri-apps/api/core'
|
||||||
|
import { writeVersionsConfig } from '@/lib/BazookaManager'
|
||||||
|
import { notifyUser } from '@/lib/Notifications'
|
||||||
|
import { getCurrentWindow, UserAttentionType } from '@tauri-apps/api/window'
|
||||||
|
|
||||||
|
export default function DownloadsPopup () {
|
||||||
|
const {
|
||||||
|
downloadProgress,
|
||||||
|
getVersionInfo,
|
||||||
|
setDownloadProgress,
|
||||||
|
downloadQueue,
|
||||||
|
setDownloadQueue,
|
||||||
|
normalConfig,
|
||||||
|
setDownloadedVersionsConfig
|
||||||
|
} = useGlobal()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<p className='text-xl text-center'>Downloads</p>
|
||||||
|
<div className='popup-content'>
|
||||||
|
{downloadProgress.map((v, i) => {
|
||||||
|
const queuePosition = downloadQueue.indexOf(v.version)
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={i}
|
||||||
|
className='popup-entry flex flex-col justify-between relative'
|
||||||
|
>
|
||||||
|
<div className='absolute right-2 top-2 flex flex-row gap-2'>
|
||||||
|
<div
|
||||||
|
className='cursor-pointer bg-(--col5) hover:bg-(--col7) border border-(--col7) hover:border-(--col9) transition-colors w-8 h-8 flex items-center justify-center rounded-full'
|
||||||
|
hidden={!v.downloading && !v.paused}
|
||||||
|
onClick={async () => {
|
||||||
|
if (v.downloading) {
|
||||||
|
await invoke('cancel_download', { name: v.version })
|
||||||
|
} else {
|
||||||
|
setDownloadProgress(prev => {
|
||||||
|
const i = prev.findIndex(d => d.version === v.version)
|
||||||
|
if (i === -1) return prev
|
||||||
|
const copy = [...prev]
|
||||||
|
copy[i] = {
|
||||||
|
...copy[i],
|
||||||
|
paused: false,
|
||||||
|
downloading: true
|
||||||
|
}
|
||||||
|
return copy
|
||||||
|
})
|
||||||
|
const res = await invoke<string>('download', {
|
||||||
|
url: v.url,
|
||||||
|
name: v.version,
|
||||||
|
executable: v.executable,
|
||||||
|
hash: v.hash
|
||||||
|
})
|
||||||
|
|
||||||
|
if (res === '1') {
|
||||||
|
setDownloadProgress(prev =>
|
||||||
|
prev.filter(d => d.version !== v.version)
|
||||||
|
)
|
||||||
|
setDownloadedVersionsConfig(prev => {
|
||||||
|
if (!prev) return prev
|
||||||
|
|
||||||
|
const updated = {
|
||||||
|
...prev,
|
||||||
|
list: {
|
||||||
|
...prev.list,
|
||||||
|
[v.version]: Date.now()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeVersionsConfig(updated)
|
||||||
|
return updated
|
||||||
|
})
|
||||||
|
} else if (res == '0') {
|
||||||
|
setDownloadProgress(prev => {
|
||||||
|
const i = prev.findIndex(d => d.version === v.version)
|
||||||
|
if (i === -1) return prev
|
||||||
|
if (prev[i].canceled) {
|
||||||
|
return prev.filter((_, idx) => idx !== i)
|
||||||
|
}
|
||||||
|
const copy = [...prev]
|
||||||
|
copy[i] = {
|
||||||
|
...copy[i],
|
||||||
|
downloading: false,
|
||||||
|
paused: true,
|
||||||
|
failed: false
|
||||||
|
}
|
||||||
|
return copy
|
||||||
|
})
|
||||||
|
} else if (res == '-1') {
|
||||||
|
setDownloadProgress(prev =>
|
||||||
|
prev.map(d =>
|
||||||
|
d.version === v.version
|
||||||
|
? {
|
||||||
|
...d,
|
||||||
|
queued: false,
|
||||||
|
failed: true,
|
||||||
|
progress: 0
|
||||||
|
}
|
||||||
|
: d
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if (normalConfig?.settings.allowNotifications)
|
||||||
|
await notifyUser(
|
||||||
|
'Download Failed',
|
||||||
|
`The download for version ${
|
||||||
|
getVersionInfo(v.version)?.displayName
|
||||||
|
} has failed.`
|
||||||
|
)
|
||||||
|
await getCurrentWindow().requestUserAttention(
|
||||||
|
UserAttentionType.Critical
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={v.downloading ? faPause : faPlay}
|
||||||
|
className='w-6 h-6'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className='cursor-pointer bg-(--col5) hover:bg-(--col7) border border-(--col7) hover:border-(--col9) transition-colors w-8 h-8 flex items-center justify-center rounded-full'
|
||||||
|
hidden={!v.downloading && !v.paused}
|
||||||
|
onClick={async () => {
|
||||||
|
if (!v.paused) {
|
||||||
|
await invoke('cancel_download', { name: v.version })
|
||||||
|
setDownloadProgress(prev => {
|
||||||
|
const i = prev.findIndex(d => d.version === v.version)
|
||||||
|
if (i === -1) return prev
|
||||||
|
const copy = [...prev]
|
||||||
|
copy[i] = {
|
||||||
|
...copy[i],
|
||||||
|
canceled: true
|
||||||
|
}
|
||||||
|
return copy
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
setDownloadProgress(prev => {
|
||||||
|
const i = prev.findIndex(d => d.version === v.version)
|
||||||
|
if (i === -1) return prev
|
||||||
|
return prev.filter((_, idx) => idx !== i)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faCancel} className='w-6 h-6' />
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className='cursor-pointer bg-(--col5) hover:bg-(--col7) border border-(--col7) hover:border-(--col9) transition-colors w-8 h-8 flex items-center justify-center rounded-full'
|
||||||
|
hidden={!v.failed && !v.queued}
|
||||||
|
onClick={() => {
|
||||||
|
setDownloadQueue(prev =>
|
||||||
|
prev.filter(id => id !== v.version)
|
||||||
|
)
|
||||||
|
setDownloadProgress(prev =>
|
||||||
|
prev.filter(d => d.version !== v.version)
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faTrash} className='w-6 h-6' />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p className='text-2xl text-center'>
|
||||||
|
{v.type == 1
|
||||||
|
? 'Mod Manager for '
|
||||||
|
: v.type == 2
|
||||||
|
? 'Mod for '
|
||||||
|
: null}{' '}
|
||||||
|
{getVersionInfo(v.version)?.displayName}
|
||||||
|
</p>
|
||||||
|
<div className='mt-6.25 flex items-center justify-between'>
|
||||||
|
{v.failed || v.queued ? (
|
||||||
|
<div className='flex items-center justify-between w-full'>
|
||||||
|
<span
|
||||||
|
className={`${
|
||||||
|
v.failed ? 'text-red-500' : 'text-yellow-300'
|
||||||
|
} inline-block text-center flex-1`}
|
||||||
|
>
|
||||||
|
{v.failed
|
||||||
|
? 'Download failed'
|
||||||
|
: queuePosition === 0
|
||||||
|
? 'Starting soon...'
|
||||||
|
: `Queued (Position ${queuePosition + 1})`}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
) : v.hash_checking ? (
|
||||||
|
<span className='text-blue-300 inline-block w-full text-center'>
|
||||||
|
Verifying file integerty...
|
||||||
|
</span>
|
||||||
|
) : v.unzipping ? (
|
||||||
|
<div className='flex flex-col gap-1 w-full'>
|
||||||
|
<span className='text-center'>
|
||||||
|
Unzipped {v.unzipped} / {v.unzipTotal} files
|
||||||
|
</span>
|
||||||
|
<ProgressBar
|
||||||
|
progress={(v.unzipped / v.unzipTotal) * 100}
|
||||||
|
className='w-full'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className='flex flex-col gap-1 w-full'>
|
||||||
|
<span className='text-center'>
|
||||||
|
Downloaded{' '}
|
||||||
|
{prettyBytes(v.progressBytes, {
|
||||||
|
minimumFractionDigits: 1,
|
||||||
|
maximumFractionDigits: 1
|
||||||
|
})}{' '}
|
||||||
|
of{' '}
|
||||||
|
{prettyBytes(v.size, {
|
||||||
|
minimumFractionDigits: 1,
|
||||||
|
maximumFractionDigits: 1
|
||||||
|
})}{' '}
|
||||||
|
(ETA: {formatEtaSmart(v.etaSecs)} • Speed:{' '}
|
||||||
|
{prettyBytes(v.speed, {
|
||||||
|
minimumFractionDigits: 1,
|
||||||
|
maximumFractionDigits: 1
|
||||||
|
})}
|
||||||
|
/s)
|
||||||
|
</span>
|
||||||
|
<ProgressBar progress={v.progress} className='w-full' />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
import { useGlobal } from '@/app/GlobalProvider'
|
||||||
|
import {
|
||||||
|
faCheck,
|
||||||
|
faCode,
|
||||||
|
faDownload,
|
||||||
|
faShieldHalved,
|
||||||
|
faWarning
|
||||||
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
|
|
||||||
|
export default function GamesDownloadPopup () {
|
||||||
|
const { serverVersionList, getVersionsAmountData, setSelectedGame } =
|
||||||
|
useGlobal()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<p className='text-xl text-center'>Select a game to download</p>
|
||||||
|
<div className='popup-content'>
|
||||||
|
{serverVersionList?.games
|
||||||
|
.filter(v => {
|
||||||
|
const data = getVersionsAmountData(v.id)
|
||||||
|
if (!data) return false
|
||||||
|
if (data.total > 0) return true
|
||||||
|
})
|
||||||
|
.map((v, i) => (
|
||||||
|
<div key={i} className='popup-entry'>
|
||||||
|
<p className='text-2xl'>{v.name}</p>
|
||||||
|
<div className='flex gap-2'>
|
||||||
|
<div
|
||||||
|
className='entry-info-item btntheme3'
|
||||||
|
title='The amount of versions installed of this game in installed/installable format.'
|
||||||
|
>
|
||||||
|
<p>
|
||||||
|
{(() => {
|
||||||
|
const data = getVersionsAmountData(v.id)
|
||||||
|
if (!data) return 'N/A'
|
||||||
|
return `${data.installed}/${data.total}`
|
||||||
|
})()}{' '}
|
||||||
|
versions installed
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className='entry-info-item btntheme3'
|
||||||
|
hidden={!v.official}
|
||||||
|
title='This game is official.'
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faCheck} color='#19c84b' />
|
||||||
|
<p>Official</p>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className='entry-info-item btntheme3'
|
||||||
|
hidden={v.official}
|
||||||
|
title={
|
||||||
|
v.verified
|
||||||
|
? 'This game is verified to be safe'
|
||||||
|
: 'This game is NOT verified to be save. Proceed with caution.'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={v.verified ? faShieldHalved : faWarning}
|
||||||
|
color={v.verified ? '#19c84b' : '#ffc800'}
|
||||||
|
/>
|
||||||
|
<p>{v.verified ? 'Verified' : 'Unverified'}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className='entry-info-item btntheme3 mt-2'
|
||||||
|
hidden={v.developer == null}
|
||||||
|
title={`The developer of ${v.name} is ${v.developer}.`}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faCode} color='lightgray' />
|
||||||
|
<p>Developer: {v.developer}</p>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
className='button btntheme3 right-2 bottom-2'
|
||||||
|
onClick={() => setSelectedGame(v.id)}
|
||||||
|
title={`Click to download specific versions of the game. You have ${(() => {
|
||||||
|
const data = getVersionsAmountData(v.id)
|
||||||
|
if (!data) return 'N/A'
|
||||||
|
return `${data.installed} of ${data.total}`
|
||||||
|
})()} versions downloaded.`}
|
||||||
|
>
|
||||||
|
<>
|
||||||
|
<FontAwesomeIcon icon={faDownload} /> Download
|
||||||
|
</>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,214 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import {
|
||||||
|
faArrowUpRightFromSquare,
|
||||||
|
faCheck,
|
||||||
|
faCode,
|
||||||
|
faHardDrive,
|
||||||
|
faShieldHalved,
|
||||||
|
faWarning
|
||||||
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
|
import { useGlobal } from '@/app/GlobalProvider'
|
||||||
|
import { invoke } from '@tauri-apps/api/core'
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import prettyBytes from 'pretty-bytes'
|
||||||
|
import { message } from '@tauri-apps/plugin-dialog'
|
||||||
|
import { BaseDirectory, exists, remove } from '@tauri-apps/plugin-fs'
|
||||||
|
import { writeVersionsConfig } from '@/lib/BazookaManager'
|
||||||
|
import { openFolder } from '@/lib/Util'
|
||||||
|
|
||||||
|
export default function ManageVersionPopup () {
|
||||||
|
const {
|
||||||
|
getGameInfo,
|
||||||
|
getVersionInfo,
|
||||||
|
managingVersion,
|
||||||
|
downloadedVersionsConfig,
|
||||||
|
viewingInfoFromDownloads,
|
||||||
|
setManagingVersion,
|
||||||
|
closePopup,
|
||||||
|
setDownloadedVersionsConfig,
|
||||||
|
setPopupMode,
|
||||||
|
setSelectedVersionList,
|
||||||
|
downloadVersions
|
||||||
|
} = useGlobal()
|
||||||
|
const [versionSize, setVersionSize] = useState<number>(0)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (viewingInfoFromDownloads) return
|
||||||
|
invoke<string>('folder_size', {
|
||||||
|
version: managingVersion
|
||||||
|
}).then(size => {
|
||||||
|
setVersionSize(Number(size))
|
||||||
|
})
|
||||||
|
}, [managingVersion, setVersionSize, viewingInfoFromDownloads])
|
||||||
|
|
||||||
|
if (!managingVersion || !downloadedVersionsConfig) return <></>
|
||||||
|
|
||||||
|
const versionInfo = getVersionInfo(managingVersion)
|
||||||
|
const gameInfo = getGameInfo(versionInfo?.game)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<p className='text-xl text-center'>Viewing {versionInfo?.displayName}</p>
|
||||||
|
<div className='popup-content flex flex-col items-center justify-center gap-2 h-full'>
|
||||||
|
<div
|
||||||
|
className='entry-info-item btntheme2'
|
||||||
|
hidden={viewingInfoFromDownloads}
|
||||||
|
>
|
||||||
|
<p>
|
||||||
|
Installed{' '}
|
||||||
|
{new Intl.DateTimeFormat(undefined).format(
|
||||||
|
downloadedVersionsConfig.list[managingVersion] ?? 0
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className='entry-info-item btntheme2'
|
||||||
|
hidden={!versionInfo || versionInfo.releaseDate == 0}
|
||||||
|
>
|
||||||
|
<p>
|
||||||
|
Released{' '}
|
||||||
|
{new Intl.DateTimeFormat(undefined).format(
|
||||||
|
versionInfo?.releaseDate ? versionInfo.releaseDate * 1000 : 0
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className='entry-info-item btntheme2' hidden={!gameInfo?.official}>
|
||||||
|
<FontAwesomeIcon icon={faCheck} color='#19c84b' />
|
||||||
|
<p>Official</p>
|
||||||
|
</div>
|
||||||
|
<div className='entry-info-item btntheme2' hidden={gameInfo?.official}>
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={gameInfo?.verified ? faShieldHalved : faWarning}
|
||||||
|
color={gameInfo?.verified ? '#19c84b' : '#ffc800'}
|
||||||
|
/>
|
||||||
|
<p>{gameInfo?.verified ? 'Verified' : 'Unverified'}</p>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className='entry-info-item btntheme2'
|
||||||
|
hidden={gameInfo?.developer == null}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faCode} color='lightgray' />
|
||||||
|
<p>Developer: {gameInfo?.developer}</p>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className='entry-info-item btntheme2'
|
||||||
|
hidden={viewingInfoFromDownloads}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faHardDrive} color='lightgray' />
|
||||||
|
<p>
|
||||||
|
Size on disk:{' '}
|
||||||
|
{versionSize && versionSize > 0
|
||||||
|
? prettyBytes(versionSize, {
|
||||||
|
minimumFractionDigits: 2,
|
||||||
|
maximumFractionDigits: 2
|
||||||
|
})
|
||||||
|
: 'N/A'}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className='entry-info-item btntheme2'
|
||||||
|
onClick={async () => {
|
||||||
|
if (!versionInfo) return
|
||||||
|
await message(atob(versionInfo.changelog), {
|
||||||
|
title: 'Changelog for ' + versionInfo.displayName,
|
||||||
|
kind: 'info'
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
hidden={!versionInfo?.changelog}
|
||||||
|
>
|
||||||
|
<p>View Changelog</p>
|
||||||
|
<FontAwesomeIcon icon={faArrowUpRightFromSquare} color='lightgray' />
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className='entry-info-item btntheme2'
|
||||||
|
onClick={async () => openFolder(managingVersion)}
|
||||||
|
title="Click to browse the game's files."
|
||||||
|
hidden={viewingInfoFromDownloads}
|
||||||
|
>
|
||||||
|
Open Folder
|
||||||
|
<FontAwesomeIcon icon={faArrowUpRightFromSquare} color='lightgray' />
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className='entry-info-item btntheme2'
|
||||||
|
onClick={async () => {
|
||||||
|
closePopup()
|
||||||
|
|
||||||
|
setDownloadedVersionsConfig(prev => {
|
||||||
|
if (!prev) return prev
|
||||||
|
const updatedList = Object.fromEntries(
|
||||||
|
Object.entries(prev.list).filter(([k]) => k !== managingVersion)
|
||||||
|
)
|
||||||
|
const updatedConfig = {
|
||||||
|
...prev,
|
||||||
|
list: updatedList
|
||||||
|
}
|
||||||
|
writeVersionsConfig(updatedConfig)
|
||||||
|
return updatedConfig
|
||||||
|
})
|
||||||
|
|
||||||
|
if (
|
||||||
|
await exists('game/' + managingVersion, {
|
||||||
|
baseDir: BaseDirectory.AppLocalData
|
||||||
|
})
|
||||||
|
)
|
||||||
|
await remove('game/' + managingVersion, {
|
||||||
|
baseDir: BaseDirectory.AppLocalData,
|
||||||
|
recursive: true
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
title='Click to uninstall this game. This will NOT remove any progress or any save files.'
|
||||||
|
hidden={viewingInfoFromDownloads}
|
||||||
|
>
|
||||||
|
Uninstall
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className='entry-info-item btntheme2'
|
||||||
|
onClick={async () => {
|
||||||
|
//change popup to downloads
|
||||||
|
setManagingVersion(null)
|
||||||
|
setPopupMode(1)
|
||||||
|
|
||||||
|
//uninstall
|
||||||
|
setDownloadedVersionsConfig(prev => {
|
||||||
|
if (!prev) return prev
|
||||||
|
const updatedList = Object.fromEntries(
|
||||||
|
Object.entries(prev.list).filter(([k]) => k !== managingVersion)
|
||||||
|
)
|
||||||
|
const updatedConfig = {
|
||||||
|
...prev,
|
||||||
|
list: updatedList
|
||||||
|
}
|
||||||
|
writeVersionsConfig(updatedConfig)
|
||||||
|
return updatedConfig
|
||||||
|
})
|
||||||
|
|
||||||
|
if (
|
||||||
|
await exists('game/' + managingVersion, {
|
||||||
|
baseDir: BaseDirectory.AppLocalData
|
||||||
|
})
|
||||||
|
)
|
||||||
|
await remove('game/' + managingVersion, {
|
||||||
|
baseDir: BaseDirectory.AppLocalData,
|
||||||
|
recursive: true
|
||||||
|
})
|
||||||
|
|
||||||
|
//reinstall
|
||||||
|
setSelectedVersionList([managingVersion])
|
||||||
|
downloadVersions([
|
||||||
|
{
|
||||||
|
id: managingVersion,
|
||||||
|
type: 0
|
||||||
|
}
|
||||||
|
])
|
||||||
|
}}
|
||||||
|
title="Click to reinstall this game. This will NOT remove any progress or any save files. This WILL uninstall any modifications to the game's executable files."
|
||||||
|
hidden={viewingInfoFromDownloads}
|
||||||
|
>
|
||||||
|
Reinstall
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,380 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { useGlobal } from '@/app/GlobalProvider'
|
||||||
|
import { writeVersionsConfig } from '@/lib/BazookaManager'
|
||||||
|
import { verifySignature } from '@/lib/Util'
|
||||||
|
import { Mod } from '@/types/Mod'
|
||||||
|
import {
|
||||||
|
faArrowUpRightFromSquare,
|
||||||
|
faClock,
|
||||||
|
faCodeBranch,
|
||||||
|
faDownload,
|
||||||
|
faGlobe,
|
||||||
|
faPeopleGroup,
|
||||||
|
faRefresh,
|
||||||
|
faTrash
|
||||||
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
|
import { message } from '@tauri-apps/plugin-dialog'
|
||||||
|
import { BaseDirectory, exists, remove } from '@tauri-apps/plugin-fs'
|
||||||
|
import { arch, platform } from '@tauri-apps/plugin-os'
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
|
||||||
|
export default function ModDownloadsPopup () {
|
||||||
|
const {
|
||||||
|
getVersionInfo,
|
||||||
|
managingVersion,
|
||||||
|
downloadedVersionsConfig,
|
||||||
|
showModInfo,
|
||||||
|
setShowModInfo,
|
||||||
|
downloadVersions,
|
||||||
|
downloadProgress,
|
||||||
|
setDownloadedVersionsConfig
|
||||||
|
} = useGlobal()
|
||||||
|
|
||||||
|
const [mods, setMods] = useState<Mod[] | 0 | 1>(0)
|
||||||
|
const [tab, setTab] = useState<number>(0)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!managingVersion) return
|
||||||
|
;(async () => {
|
||||||
|
const response = await fetch(
|
||||||
|
`https://games.lncvrt.xyz/api/launcher/mods?platform=${platform()}&arch=${arch()}&version=${managingVersion}`
|
||||||
|
)
|
||||||
|
const signature = response.headers.get('x-signature') ?? ''
|
||||||
|
const data = await response.json()
|
||||||
|
if (await verifySignature(JSON.stringify(data), signature)) {
|
||||||
|
setMods(data as Mod[])
|
||||||
|
} else {
|
||||||
|
setMods(1)
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
}, [managingVersion])
|
||||||
|
|
||||||
|
if (!managingVersion) return <></>
|
||||||
|
|
||||||
|
const versionInfo = getVersionInfo(managingVersion)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<button
|
||||||
|
className='popup-top-button btntheme1 right-2'
|
||||||
|
onClick={async () => {
|
||||||
|
setMods(0)
|
||||||
|
const response = await fetch(
|
||||||
|
`https://games.lncvrt.xyz/api/launcher/mods?platform=${platform()}&arch=${arch()}&version=${managingVersion}`
|
||||||
|
)
|
||||||
|
const signature = response.headers.get('x-signature') ?? ''
|
||||||
|
const data = await response.json()
|
||||||
|
if (await verifySignature(JSON.stringify(data), signature)) {
|
||||||
|
setMods(data as Mod[])
|
||||||
|
} else {
|
||||||
|
setMods(1)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
hidden={typeof mods == 'number' || showModInfo != null}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faRefresh} />
|
||||||
|
</button>
|
||||||
|
<p className='text-xl text-center'>
|
||||||
|
{!showModInfo
|
||||||
|
? versionInfo?.displayName + ' Mod Manager'
|
||||||
|
: showModInfo.name +
|
||||||
|
' by ' +
|
||||||
|
showModInfo.creators[0] +
|
||||||
|
(showModInfo.creators.length > 1
|
||||||
|
? ' + ' + (showModInfo.creators.length - 1) + ' more'
|
||||||
|
: '')}
|
||||||
|
</p>
|
||||||
|
{typeof mods != 'number' && !showModInfo ? (
|
||||||
|
<div className='flex flex-row justify-center items-center -mb-2 mt-0.5 gap-1.5'>
|
||||||
|
<button
|
||||||
|
className={`button ${tab == 0 ? 'btntheme3' : 'btntheme2'}`}
|
||||||
|
onClick={() => setTab(0)}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faDownload} />
|
||||||
|
Installed
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className={`button ${tab == 1 ? 'btntheme3' : 'btntheme2'}`}
|
||||||
|
onClick={() => setTab(1)}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faGlobe} />
|
||||||
|
Download
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
<div className='popup-content h-full'>
|
||||||
|
{typeof mods == 'number' ||
|
||||||
|
(!showModInfo &&
|
||||||
|
mods.filter(v =>
|
||||||
|
tab == 0
|
||||||
|
? Object.keys(downloadedVersionsConfig?.mods ?? []).includes(
|
||||||
|
String(versionInfo?.game + '-' + v.id)
|
||||||
|
)
|
||||||
|
: !Object.keys(downloadedVersionsConfig?.mods ?? []).includes(
|
||||||
|
String(versionInfo?.game + '-' + v.id)
|
||||||
|
)
|
||||||
|
).length == 0) ? (
|
||||||
|
<p className='text-2xl flex justify-center items-center h-full'>
|
||||||
|
{typeof mods == 'number'
|
||||||
|
? mods == 0
|
||||||
|
? 'Loading'
|
||||||
|
: 'Failed to load mods'
|
||||||
|
: tab == 0
|
||||||
|
? 'No mods installed'
|
||||||
|
: 'No mods available to download'}
|
||||||
|
</p>
|
||||||
|
) : !showModInfo ? (
|
||||||
|
<div className='flex flex-col items-center justify-center gap-2 p-2'>
|
||||||
|
{mods
|
||||||
|
.filter(v =>
|
||||||
|
tab == 0
|
||||||
|
? Object.keys(downloadedVersionsConfig?.mods ?? []).includes(
|
||||||
|
String(versionInfo?.game + '-' + v.id)
|
||||||
|
)
|
||||||
|
: !Object.keys(downloadedVersionsConfig?.mods ?? []).includes(
|
||||||
|
String(versionInfo?.game + '-' + v.id)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.map(v => {
|
||||||
|
const localVersion =
|
||||||
|
tab == 0
|
||||||
|
? Object.keys(
|
||||||
|
downloadedVersionsConfig?.mods?.[
|
||||||
|
versionInfo?.game + '-' + v.id
|
||||||
|
] ?? {}
|
||||||
|
)[0]
|
||||||
|
: null
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={v.id}
|
||||||
|
className='bg-(--col3) border border-(--col5) rounded-lg w-full h-16 flex flex-row'
|
||||||
|
>
|
||||||
|
<div className='flex flex-col justify-center h-full px-3 w-fit'>
|
||||||
|
<p>
|
||||||
|
<span className='text-lg'>{v.name}</span>{' '}
|
||||||
|
<span
|
||||||
|
className={
|
||||||
|
tab != 0 || v.latestVersion == localVersion
|
||||||
|
? 'text-green-300'
|
||||||
|
: 'text-red-300'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
v{tab == 0 ? localVersion : v.latestVersion}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
className='text-green-300'
|
||||||
|
hidden={tab != 0 || v.latestVersion == localVersion}
|
||||||
|
>
|
||||||
|
{' '}
|
||||||
|
(available: v{v.latestVersion})
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p className='text-yellow-200'>
|
||||||
|
Made by {v.creators[0]}
|
||||||
|
{v.creators.length > 1
|
||||||
|
? ' + ' + (v.creators.length - 1) + ' more'
|
||||||
|
: null}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-row items-center h-full gap-2 px-3 ml-auto'>
|
||||||
|
<p className='text-green-400' hidden={tab == 0}>
|
||||||
|
<FontAwesomeIcon icon={faDownload} />{' '}
|
||||||
|
{v.downloads.toLocaleString()}
|
||||||
|
</p>
|
||||||
|
<button
|
||||||
|
className='button btntheme3'
|
||||||
|
onClick={async () => {
|
||||||
|
const path =
|
||||||
|
'game/' +
|
||||||
|
versionInfo?.id +
|
||||||
|
'/BepInEx/plugins/' +
|
||||||
|
v.id
|
||||||
|
if (
|
||||||
|
await exists(path, {
|
||||||
|
baseDir: BaseDirectory.AppLocalData
|
||||||
|
})
|
||||||
|
)
|
||||||
|
await remove(path, {
|
||||||
|
baseDir: BaseDirectory.AppLocalData,
|
||||||
|
recursive: true
|
||||||
|
})
|
||||||
|
setDownloadedVersionsConfig(prev => {
|
||||||
|
if (!prev) return prev
|
||||||
|
const updatedMods = Object.fromEntries(
|
||||||
|
Object.entries(prev.mods).filter(
|
||||||
|
([k]) => k !== versionInfo?.game + '-' + v.id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
const updatedConfig = {
|
||||||
|
...prev,
|
||||||
|
mods: updatedMods
|
||||||
|
}
|
||||||
|
writeVersionsConfig(updatedConfig)
|
||||||
|
return updatedConfig
|
||||||
|
})
|
||||||
|
|
||||||
|
downloadVersions([
|
||||||
|
{
|
||||||
|
id: managingVersion,
|
||||||
|
type: 2,
|
||||||
|
modDownload: v.latestDownload,
|
||||||
|
gameId: versionInfo?.game,
|
||||||
|
modId: v.id,
|
||||||
|
modVersion: v.latestVersion
|
||||||
|
}
|
||||||
|
])
|
||||||
|
}}
|
||||||
|
hidden={tab != 0 || v.latestVersion == localVersion}
|
||||||
|
disabled={downloadProgress.length != 0}
|
||||||
|
>
|
||||||
|
Update
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className='button btntheme3'
|
||||||
|
onClick={() => setShowModInfo(v)}
|
||||||
|
>
|
||||||
|
{tab == 0 ? 'View' : 'Get'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className='flex flex-col h-full w-full items-center'>
|
||||||
|
<div className='flex flex-col p-2 h-fit w-fit bg-(--col3) border border-(--col5) rounded-lg m-2 items-center'>
|
||||||
|
<p>
|
||||||
|
<FontAwesomeIcon icon={faDownload} className='text-green-400' />{' '}
|
||||||
|
Downloads {showModInfo.downloads.toLocaleString()}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<FontAwesomeIcon icon={faClock} /> Released{' '}
|
||||||
|
{new Intl.DateTimeFormat(undefined).format(
|
||||||
|
showModInfo.released * 1000
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<FontAwesomeIcon icon={faClock} /> Updated{' '}
|
||||||
|
{new Intl.DateTimeFormat(undefined).format(
|
||||||
|
showModInfo.updated * 1000
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<FontAwesomeIcon icon={faCodeBranch} /> Version{' '}
|
||||||
|
{showModInfo.latestVersion}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-col p-2 bg-(--col3) border border-(--col5) rounded-lg h-full w-[calc(100%-16px)]'>
|
||||||
|
{showModInfo.description
|
||||||
|
? atob(showModInfo.description)
|
||||||
|
: '(No description added)'}
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-row h-fit w-full gap-2 justify-center my-2'>
|
||||||
|
{Object.keys(downloadedVersionsConfig?.mods ?? []).includes(
|
||||||
|
String(versionInfo?.game + '-' + showModInfo.id)
|
||||||
|
) ? (
|
||||||
|
<button
|
||||||
|
className='button btntheme2 w-fit'
|
||||||
|
disabled={downloadProgress.length != 0}
|
||||||
|
onClick={async () => {
|
||||||
|
const path =
|
||||||
|
'game/' +
|
||||||
|
versionInfo?.id +
|
||||||
|
'/BepInEx/plugins/' +
|
||||||
|
showModInfo.id
|
||||||
|
if (
|
||||||
|
await exists(path, {
|
||||||
|
baseDir: BaseDirectory.AppLocalData
|
||||||
|
})
|
||||||
|
)
|
||||||
|
await remove(path, {
|
||||||
|
baseDir: BaseDirectory.AppLocalData,
|
||||||
|
recursive: true
|
||||||
|
})
|
||||||
|
setDownloadedVersionsConfig(prev => {
|
||||||
|
if (!prev) return prev
|
||||||
|
const updatedMods = Object.fromEntries(
|
||||||
|
Object.entries(prev.mods).filter(
|
||||||
|
([k]) =>
|
||||||
|
k !== versionInfo?.game + '-' + showModInfo.id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
const updatedConfig = {
|
||||||
|
...prev,
|
||||||
|
mods: updatedMods
|
||||||
|
}
|
||||||
|
writeVersionsConfig(updatedConfig)
|
||||||
|
return updatedConfig
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faTrash} className='text-red-400' />{' '}
|
||||||
|
Uninstall
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<button
|
||||||
|
className='button btntheme2 w-fit'
|
||||||
|
onClick={() => {
|
||||||
|
downloadVersions([
|
||||||
|
{
|
||||||
|
id: managingVersion,
|
||||||
|
type: 2,
|
||||||
|
modDownload: showModInfo.latestDownload,
|
||||||
|
gameId: versionInfo?.game,
|
||||||
|
modId: showModInfo.id,
|
||||||
|
modVersion: showModInfo.latestVersion
|
||||||
|
}
|
||||||
|
])
|
||||||
|
}}
|
||||||
|
disabled={downloadProgress.length != 0}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faDownload}
|
||||||
|
className='text-green-400'
|
||||||
|
/>{' '}
|
||||||
|
Install
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
<button
|
||||||
|
className='button btntheme2 w-fit'
|
||||||
|
onClick={async () => {
|
||||||
|
await message(
|
||||||
|
!showModInfo.changelog
|
||||||
|
? '(No changelog provided)'
|
||||||
|
: atob(showModInfo?.changelog ?? ''),
|
||||||
|
{
|
||||||
|
title: 'Changelog for ' + showModInfo.name,
|
||||||
|
kind: 'info'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faArrowUpRightFromSquare}
|
||||||
|
color='lightgray'
|
||||||
|
/>{' '}
|
||||||
|
View changelog
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className='button btntheme2 w-fit'
|
||||||
|
hidden={showModInfo.creators.length < 2}
|
||||||
|
onClick={async () => {
|
||||||
|
if (!versionInfo) return
|
||||||
|
await message(showModInfo.creators.join(', '), {
|
||||||
|
title: 'Creators for ' + showModInfo.name,
|
||||||
|
kind: 'info'
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faPeopleGroup} color='lightgray' /> View
|
||||||
|
all creators
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
import { useGlobal } from '@/app/GlobalProvider'
|
||||||
|
import { faAdd, faInfo, faRemove } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
|
|
||||||
|
export default function VersionsDownloadPopup () {
|
||||||
|
const {
|
||||||
|
selectedVersionList,
|
||||||
|
setSelectedVersionList,
|
||||||
|
setManagingVersion,
|
||||||
|
setPopupMode,
|
||||||
|
getSpecialVersionsList,
|
||||||
|
selectedGame,
|
||||||
|
setViewingInfoFromDownloads,
|
||||||
|
downloadedVersionsConfig,
|
||||||
|
downloadVersions,
|
||||||
|
getGameInfo
|
||||||
|
} = useGlobal()
|
||||||
|
|
||||||
|
if (!selectedGame) return <></>
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<p className='text-xl text-center'>Select versions to download</p>
|
||||||
|
<div className='popup-content'>
|
||||||
|
{getSpecialVersionsList(selectedGame).map((v, i) => (
|
||||||
|
<div key={i} className='popup-entry'>
|
||||||
|
<div className='flex items-center'>
|
||||||
|
<p
|
||||||
|
className={`text-2xl truncate ${
|
||||||
|
selectedVersionList.includes(v.id)
|
||||||
|
? 'max-w-84.5'
|
||||||
|
: 'max-w-91.5'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{v.displayName}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
className='button btntheme3 right-20.75 bottom-1.75'
|
||||||
|
onClick={() => {
|
||||||
|
setSelectedVersionList(prev =>
|
||||||
|
prev.includes(v.id)
|
||||||
|
? prev.filter(i => i !== v.id)
|
||||||
|
: [...prev, v.id]
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
title={
|
||||||
|
selectedVersionList.includes(v.id)
|
||||||
|
? 'This version will be downloaded. Click to remove from the list of versions that will be downloaded.'
|
||||||
|
: 'This version will NOT be downloaded. Click to add from the list of versions that will be downloaded.'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{selectedVersionList.includes(v.id) ? (
|
||||||
|
<>
|
||||||
|
<FontAwesomeIcon icon={faRemove} /> Remove
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<FontAwesomeIcon icon={faAdd} /> Add
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className='button btntheme3 right-1.5 bottom-1.75'
|
||||||
|
onClick={() => {
|
||||||
|
setManagingVersion(v.id)
|
||||||
|
setViewingInfoFromDownloads(true)
|
||||||
|
setPopupMode(2)
|
||||||
|
}}
|
||||||
|
title='Click to view version info'
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faInfo} /> Info
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<div className='flex justify-center'>
|
||||||
|
<button
|
||||||
|
className='button btntheme1 w-fit mt-2 -mb-4'
|
||||||
|
onClick={() => {
|
||||||
|
if (downloadedVersionsConfig) {
|
||||||
|
downloadVersions(
|
||||||
|
selectedVersionList.map(versionId => ({
|
||||||
|
id: versionId,
|
||||||
|
type: 0
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
setPopupMode(1)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
disabled={selectedVersionList.length == 0}
|
||||||
|
title={
|
||||||
|
selectedVersionList.length == 0
|
||||||
|
? 'Select at least one version to download'
|
||||||
|
: `Download ${selectedVersionList.length} version${
|
||||||
|
selectedVersionList.length == 1 ? '' : 's'
|
||||||
|
} of ${getGameInfo(selectedGame)?.name}`
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Download {selectedVersionList.length} version
|
||||||
|
{selectedVersionList.length == 1 ? '' : 's'}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className='button btntheme1 w-fit mt-2 ml-2 -mb-4'
|
||||||
|
onClick={() => {
|
||||||
|
const allIds = getSpecialVersionsList(selectedGame).map(v => v.id)
|
||||||
|
setSelectedVersionList(prev =>
|
||||||
|
prev.length === allIds.length ? [] : allIds
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
title={
|
||||||
|
selectedVersionList.length ===
|
||||||
|
getSpecialVersionsList(selectedGame).length
|
||||||
|
? 'Click to remove all selected versions for download.'
|
||||||
|
: 'Click to add all selected versions for download.'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{selectedVersionList.length ===
|
||||||
|
getSpecialVersionsList(selectedGame).length
|
||||||
|
? 'Deselect All'
|
||||||
|
: 'Select All'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { app } from '@tauri-apps/api'
|
import { app } from '@tauri-apps/api'
|
||||||
import { NormalConfig } from '../types/NormalConfig'
|
import { NormalConfig } from '@/types/NormalConfig'
|
||||||
import {
|
import {
|
||||||
BaseDirectory,
|
BaseDirectory,
|
||||||
create,
|
create,
|
||||||
@@ -8,9 +8,9 @@ import {
|
|||||||
readTextFile,
|
readTextFile,
|
||||||
writeFile
|
writeFile
|
||||||
} from '@tauri-apps/plugin-fs'
|
} from '@tauri-apps/plugin-fs'
|
||||||
import { VersionsConfig } from '../types/VersionsConfig'
|
import { VersionsConfig } from '@/types/VersionsConfig'
|
||||||
|
|
||||||
export async function readNormalConfig(): Promise<NormalConfig> {
|
export async function readNormalConfig (): Promise<NormalConfig> {
|
||||||
const version = await app.getVersion()
|
const version = await app.getVersion()
|
||||||
try {
|
try {
|
||||||
const options = {
|
const options = {
|
||||||
@@ -25,22 +25,44 @@ export async function readNormalConfig(): Promise<NormalConfig> {
|
|||||||
const file = await create('config.json', options)
|
const file = await create('config.json', options)
|
||||||
await file.write(
|
await file.write(
|
||||||
new TextEncoder().encode(
|
new TextEncoder().encode(
|
||||||
JSON.stringify(new NormalConfig(version), null, 2),
|
JSON.stringify(new NormalConfig(version), null, 2)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
await file.close()
|
await file.close()
|
||||||
return new NormalConfig(version)
|
return new NormalConfig(version)
|
||||||
}
|
}
|
||||||
const config = await readTextFile('config.json', options)
|
const config = await readTextFile('config.json', options)
|
||||||
return NormalConfig.import(
|
const raw = JSON.parse(config)
|
||||||
JSON.parse(config)
|
if (
|
||||||
)
|
raw.settings &&
|
||||||
|
raw.settings.theme &&
|
||||||
|
(raw.version == '1.0.0' ||
|
||||||
|
raw.version == '1.1.0' ||
|
||||||
|
raw.version == '1.1.1' ||
|
||||||
|
raw.version == '1.2.0' ||
|
||||||
|
raw.version == '1.3.0' ||
|
||||||
|
raw.version == '1.3.1' ||
|
||||||
|
raw.version == '1.4.0' ||
|
||||||
|
raw.version == '1.5.0' ||
|
||||||
|
raw.version == '1.5.1' ||
|
||||||
|
raw.version == '1.5.2' ||
|
||||||
|
raw.version == '1.5.3' ||
|
||||||
|
raw.version == '1.5.4')
|
||||||
|
) {
|
||||||
|
const parsed = Number(raw.settings.theme)
|
||||||
|
if (parsed == 3) raw.settings.theme = 2
|
||||||
|
if (parsed == 4) raw.settings.theme = 3
|
||||||
|
else if (parsed != 0 && parsed != 1) raw.settings.theme = 0
|
||||||
|
}
|
||||||
|
raw.version = version
|
||||||
|
writeNormalConfig(raw)
|
||||||
|
return NormalConfig.import(raw)
|
||||||
} catch {
|
} catch {
|
||||||
return new NormalConfig(version)
|
return new NormalConfig(version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function writeNormalConfig(data: NormalConfig) {
|
export async function writeNormalConfig (data: NormalConfig) {
|
||||||
const options = {
|
const options = {
|
||||||
baseDir: BaseDirectory.AppLocalData
|
baseDir: BaseDirectory.AppLocalData
|
||||||
}
|
}
|
||||||
@@ -51,24 +73,18 @@ export async function writeNormalConfig(data: NormalConfig) {
|
|||||||
await mkdir('', options)
|
await mkdir('', options)
|
||||||
}
|
}
|
||||||
const file = await create('config.json', options)
|
const file = await create('config.json', options)
|
||||||
await file.write(
|
await file.write(new TextEncoder().encode(JSON.stringify(data, null, 2)))
|
||||||
new TextEncoder().encode(
|
|
||||||
JSON.stringify(data, null, 2)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
await file.close()
|
await file.close()
|
||||||
} else {
|
} else {
|
||||||
await writeFile(
|
await writeFile(
|
||||||
'config.json',
|
'config.json',
|
||||||
new TextEncoder().encode(
|
new TextEncoder().encode(JSON.stringify(data, null, 2)),
|
||||||
JSON.stringify(data, null, 2)
|
|
||||||
),
|
|
||||||
options
|
options
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function readVersionsConfig(): Promise<VersionsConfig> {
|
export async function readVersionsConfig (): Promise<VersionsConfig> {
|
||||||
const version = await app.getVersion()
|
const version = await app.getVersion()
|
||||||
try {
|
try {
|
||||||
const options = {
|
const options = {
|
||||||
@@ -90,15 +106,26 @@ export async function readVersionsConfig(): Promise<VersionsConfig> {
|
|||||||
return new VersionsConfig(version)
|
return new VersionsConfig(version)
|
||||||
}
|
}
|
||||||
const config = await readTextFile('versions.json', options)
|
const config = await readTextFile('versions.json', options)
|
||||||
return VersionsConfig.import(
|
const raw = JSON.parse(config)
|
||||||
JSON.parse(config)
|
if (raw.list && raw.timestamps) {
|
||||||
)
|
raw.list = raw.timestamps
|
||||||
|
delete raw.timestamps
|
||||||
|
|
||||||
|
await writeFile(
|
||||||
|
'versions.json',
|
||||||
|
new TextEncoder().encode(JSON.stringify(raw, null, 2)),
|
||||||
|
options
|
||||||
|
)
|
||||||
|
}
|
||||||
|
raw.version = version
|
||||||
|
writeVersionsConfig(raw)
|
||||||
|
return VersionsConfig.import(raw)
|
||||||
} catch {
|
} catch {
|
||||||
return new VersionsConfig(version)
|
return new VersionsConfig(version)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function writeVersionsConfig(data: VersionsConfig) {
|
export async function writeVersionsConfig (data: VersionsConfig) {
|
||||||
const options = {
|
const options = {
|
||||||
baseDir: BaseDirectory.AppLocalData
|
baseDir: BaseDirectory.AppLocalData
|
||||||
}
|
}
|
||||||
@@ -109,18 +136,12 @@ export async function writeVersionsConfig(data: VersionsConfig) {
|
|||||||
await mkdir('', options)
|
await mkdir('', options)
|
||||||
}
|
}
|
||||||
const file = await create('versions.json', options)
|
const file = await create('versions.json', options)
|
||||||
await file.write(
|
await file.write(new TextEncoder().encode(JSON.stringify(data, null, 2)))
|
||||||
new TextEncoder().encode(
|
|
||||||
JSON.stringify(data, null, 2)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
await file.close()
|
await file.close()
|
||||||
} else {
|
} else {
|
||||||
await writeFile(
|
await writeFile(
|
||||||
'versions.json',
|
'versions.json',
|
||||||
new TextEncoder().encode(
|
new TextEncoder().encode(JSON.stringify(data, null, 2)),
|
||||||
JSON.stringify(data, null, 2)
|
|
||||||
),
|
|
||||||
options
|
options
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
export const GetIconForUser = (user: number) => {
|
||||||
|
if (user == 1) return -1
|
||||||
|
else if (user == 2) return -2
|
||||||
|
else if (user == 4) return -3
|
||||||
|
else if (user == 3) return -4
|
||||||
|
else return 1
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { NormalConfig } from '@/types/NormalConfig'
|
||||||
|
import { notifyUser } from './Notifications'
|
||||||
|
|
||||||
|
export async function copyToClipboard (
|
||||||
|
text: string,
|
||||||
|
normalConfig: NormalConfig | null
|
||||||
|
) {
|
||||||
|
if (normalConfig?.settings.allowNotifications)
|
||||||
|
await notifyUser('Copied', 'Text "' + text + '" copied to clipboard')
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import {
|
||||||
|
isPermissionGranted,
|
||||||
|
requestPermission,
|
||||||
|
sendNotification
|
||||||
|
} from '@tauri-apps/plugin-notification'
|
||||||
|
|
||||||
|
export async function notifyUser (title: string, body: string) {
|
||||||
|
let permissionGranted = await isPermissionGranted()
|
||||||
|
if (!permissionGranted) {
|
||||||
|
const permission = await requestPermission()
|
||||||
|
permissionGranted = permission === 'granted'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (permissionGranted) {
|
||||||
|
sendNotification({ title, body })
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
import { message } from '@tauri-apps/plugin-dialog'
|
||||||
|
import { BaseDirectory, exists, stat } from '@tauri-apps/plugin-fs'
|
||||||
|
import { openPath } from '@tauri-apps/plugin-opener'
|
||||||
|
import { join, appLocalDataDir } from '@tauri-apps/api/path'
|
||||||
|
import { invoke } from '@tauri-apps/api/core'
|
||||||
|
|
||||||
|
export const openFolder = async (name: string) => {
|
||||||
|
const relativePath = await join('game', name)
|
||||||
|
const basePath = await appLocalDataDir()
|
||||||
|
const absolutePath = await join(basePath, relativePath)
|
||||||
|
|
||||||
|
const folderExists = await exists(relativePath, {
|
||||||
|
baseDir: BaseDirectory.AppLocalData
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!folderExists) {
|
||||||
|
await message(`Game folder "${absolutePath}" not found.`, {
|
||||||
|
title: 'Folder not found',
|
||||||
|
kind: 'error'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const folderStat = await stat(relativePath, {
|
||||||
|
baseDir: BaseDirectory.AppLocalData
|
||||||
|
})
|
||||||
|
|
||||||
|
if (folderStat.isFile) {
|
||||||
|
await message(`Game folder "${absolutePath}" not found.`, {
|
||||||
|
title: 'Folder not found',
|
||||||
|
kind: 'error'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await openPath(absolutePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const formatEtaSmart = (seconds: number) => {
|
||||||
|
if (seconds < 60) return `${Math.floor(seconds)}s`
|
||||||
|
if (seconds < 3600)
|
||||||
|
return `${Math.floor(seconds / 60)}m ${Math.floor(seconds % 60)}s`
|
||||||
|
if (seconds < 86400) {
|
||||||
|
const h = Math.floor(seconds / 3600)
|
||||||
|
const m = Math.floor((seconds % 3600) / 60)
|
||||||
|
return `${h}h ${m}m`
|
||||||
|
}
|
||||||
|
const d = Math.floor(seconds / 86400)
|
||||||
|
const h = Math.floor((seconds % 86400) / 3600)
|
||||||
|
return `${d}d ${h}h`
|
||||||
|
}
|
||||||
|
|
||||||
|
export const verifySignature = async (body: string, signature: string) => {
|
||||||
|
try {
|
||||||
|
const result = await invoke<boolean>('verify_signature', {
|
||||||
|
body: body ?? '',
|
||||||
|
signature: signature ?? '',
|
||||||
|
publicKey: process.env.NEXT_PUBLIC_PUBLIC_SIGNING_KEY ?? ''
|
||||||
|
})
|
||||||
|
return Boolean(result)
|
||||||
|
} catch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export type BirdColor = [number, number, number]
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
export class DownloadProgress {
|
||||||
|
constructor (
|
||||||
|
public version: string,
|
||||||
|
public progress: number,
|
||||||
|
public progressBytes: number,
|
||||||
|
public failed: boolean,
|
||||||
|
public downloading: boolean,
|
||||||
|
public paused: boolean,
|
||||||
|
public canceled: boolean,
|
||||||
|
public queued: boolean,
|
||||||
|
public hash_checking: boolean,
|
||||||
|
public speed: number,
|
||||||
|
public size: number,
|
||||||
|
public etaSecs: number,
|
||||||
|
public unzipping: boolean,
|
||||||
|
public unzipTotal: number,
|
||||||
|
public unzipped: number,
|
||||||
|
public url: string | null,
|
||||||
|
public executable: string | null,
|
||||||
|
public hash: string | null,
|
||||||
|
public type: 0 | 1 | 2,
|
||||||
|
public modDownload: number | null,
|
||||||
|
public modGame: number | null,
|
||||||
|
public modId: number | null,
|
||||||
|
public modVersion: string | null
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -3,5 +3,6 @@ export interface Game {
|
|||||||
name: string
|
name: string
|
||||||
official: boolean
|
official: boolean
|
||||||
verified: boolean
|
verified: boolean
|
||||||
cutOff: number | null
|
developer: string | null
|
||||||
|
categoryNames: Record<string, string>
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
export interface GameVersion {
|
||||||
|
id: string
|
||||||
|
displayName: string
|
||||||
|
releaseDate: number
|
||||||
|
game: number
|
||||||
|
place: number
|
||||||
|
changelog: string
|
||||||
|
wine: number | undefined
|
||||||
|
category: number
|
||||||
|
lastRevision: number
|
||||||
|
download: number | undefined
|
||||||
|
executable: string
|
||||||
|
modSupportDownload: number | undefined
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
export interface Mod {
|
||||||
|
id: number
|
||||||
|
name: string
|
||||||
|
description: string | null
|
||||||
|
creators: string[]
|
||||||
|
downloads: number
|
||||||
|
released: number
|
||||||
|
updated: number
|
||||||
|
latestVersion: string
|
||||||
|
latestDownload: number
|
||||||
|
changelog: string | null
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Game } from "./Game"
|
import { Game } from './Game'
|
||||||
import { GameVersion } from "./GameVersion"
|
import { GameVersion } from './GameVersion'
|
||||||
|
|
||||||
export interface ServerVersionsResponse {
|
export interface ServerVersionsResponse {
|
||||||
versions: GameVersion[]
|
versions: GameVersion[]
|
||||||
@@ -3,4 +3,5 @@ export type SettingProps = {
|
|||||||
value: boolean
|
value: boolean
|
||||||
onChange: (val: boolean) => void
|
onChange: (val: boolean) => void
|
||||||
className?: string
|
className?: string
|
||||||
|
title?: string
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
export class SettingsType {
|
||||||
|
constructor (
|
||||||
|
public allowNotifications: boolean = true,
|
||||||
|
public alwaysShowGamesInSidebar: boolean = true,
|
||||||
|
public useWineOnUnixWhenNeeded: boolean = false,
|
||||||
|
public wineOnUnixCommand: string = 'wine %path%',
|
||||||
|
public theme: number = 0
|
||||||
|
) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
export type VersionsConfigData = {
|
||||||
|
version: string
|
||||||
|
list: Record<string, number>
|
||||||
|
mods: Record<string, Record<string, number>>
|
||||||
|
}
|
||||||
|
|
||||||
|
export class VersionsConfig {
|
||||||
|
constructor (
|
||||||
|
public version: string,
|
||||||
|
public list: Record<string, number> = {},
|
||||||
|
public mods: Record<string, Record<string, number>> = {}
|
||||||
|
) {}
|
||||||
|
|
||||||
|
static import (data: VersionsConfigData) {
|
||||||
|
const cfg = new VersionsConfig(data.version)
|
||||||
|
cfg.list = { ...data.list }
|
||||||
|
cfg.mods = { ...data.mods }
|
||||||
|
return cfg
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ES2017",
|
"target": "es2024",
|
||||||
"lib": ["dom", "dom.iterable", "esnext"],
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
@@ -28,7 +28,9 @@
|
|||||||
"**/*.tsx",
|
"**/*.tsx",
|
||||||
".next/types/**/*.ts",
|
".next/types/**/*.ts",
|
||||||
".next/dev/types/**/*.ts",
|
".next/dev/types/**/*.ts",
|
||||||
"**/*.mts"
|
"**/*.mts",
|
||||||
|
"next.config.ts",
|
||||||
|
"eslint.config.ts"
|
||||||
],
|
],
|
||||||
"exclude": ["node_modules"]
|
"exclude": ["node_modules"]
|
||||||
}
|
}
|
||||||