Compare commits
2659 Commits
shared-pro
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d22c9e24f4 | ||
|
|
e31197f649 | ||
|
|
0dee21814d | ||
|
|
0657e4466f | ||
|
|
13dbb4c57e | ||
|
|
99493b9917 | ||
|
|
72a52eb7b1 | ||
|
|
b33e12c71d | ||
|
|
82d86839c7 | ||
|
|
3a20e15340 | ||
|
|
1c89b84314 | ||
|
|
6387fb21c6 | ||
|
|
c7d0839bfb | ||
|
|
175b90be5a | ||
|
|
13103b4950 | ||
|
|
8804478221 | ||
|
|
b8982a6d17 | ||
|
|
ff88724d01 | ||
|
|
7dffb352d5 | ||
|
|
1df6e29aa1 | ||
|
|
5deb4179ad | ||
|
|
358cf31c87 | ||
|
|
6db1d66591 | ||
|
|
8052fda840 | ||
|
|
15892a88d3 | ||
|
|
32793c50e1 | ||
|
|
0e0ca1971a | ||
|
|
bb9af18eed | ||
|
|
d4516d3527 | ||
|
|
87de47fe5e | ||
|
|
7d76fe1b6a | ||
|
|
ae25a15abd | ||
|
|
0f755b94ce | ||
|
|
bcf46d440b | ||
|
|
526561f2de | ||
|
|
a8caa1afc3 | ||
|
|
98e9a8473d | ||
|
|
936395484e | ||
|
|
0c3e23db96 | ||
|
|
013ba4d86d | ||
|
|
93813c448c | ||
|
|
c20b869e62 | ||
|
|
56c556821b | ||
|
|
44267619b6 | ||
|
|
90043fe84d | ||
|
|
a6a98ff63e | ||
|
|
911652133b | ||
|
|
cee1b5f522 | ||
|
|
62f5a23fcb | ||
|
|
eb595cdc3e | ||
|
|
572cd065ed | ||
|
|
76dc8a0897 | ||
|
|
4723de6269 | ||
|
|
e15fa35bad | ||
|
|
2cc6bc8ce4 | ||
|
|
5d19d31b2c | ||
|
|
c1b95ede07 | ||
|
|
058185c7fd | ||
|
|
6fb125cf0f | ||
|
|
a945e9b005 | ||
|
|
b943638afb | ||
|
|
207dc0e2bb | ||
|
|
359fbd4738 | ||
|
|
f7700acce4 | ||
|
|
87a3e2d022 | ||
|
|
5d17663040 | ||
|
|
cff3c72f94 | ||
|
|
fadf475f06 | ||
|
|
7228499737 | ||
|
|
bca467a634 | ||
|
|
cb72d2ac80 | ||
|
|
3c79607d1f | ||
|
|
36ad1f16e4 | ||
|
|
5d4f334505 | ||
|
|
1fdb5ba748 | ||
|
|
26df6f51ef | ||
|
|
6caf794ae1 | ||
|
|
2692953e31 | ||
|
|
242fd713ab | ||
|
|
7a12c4d5e2 | ||
|
|
f256ef43c0 | ||
|
|
e0cde2d6ff | ||
|
|
e4e77dc0d2 | ||
|
|
8ba6467f21 | ||
|
|
088cb54317 | ||
|
|
c47bcf665d | ||
|
|
bc90c27e27 | ||
|
|
c1be57773a | ||
|
|
315c68912c | ||
|
|
559d203996 | ||
|
|
54522518c3 | ||
|
|
bacb1561d5 | ||
|
|
b8521f926f | ||
|
|
b29672f4b4 | ||
|
|
a32fe6a41f | ||
|
|
0e35135093 | ||
|
|
31ecace083 | ||
|
|
e5b134f8f4 | ||
|
|
139a4863d1 | ||
|
|
8faea1663a | ||
|
|
ece8a07486 | ||
|
|
0030f35d0c | ||
|
|
1e24225350 | ||
|
|
e84a178586 | ||
|
|
0a83ed965e | ||
|
|
30035a9a1c | ||
|
|
512d456c66 | ||
|
|
bff26af465 | ||
|
|
f4d0f14cb6 | ||
|
|
55916b6bda | ||
|
|
a38e1dee1f | ||
|
|
ef76a81cd5 | ||
|
|
9dc5644264 | ||
|
|
8e35cf6957 | ||
|
|
ae1c3d6531 | ||
|
|
4964c8d373 | ||
|
|
497b2e977e | ||
|
|
f95d0d78f2 | ||
|
|
94a7d13af8 | ||
|
|
3a10e63756 | ||
|
|
238138d56e | ||
|
|
1846c59733 | ||
|
|
f1207f0a3a | ||
|
|
26e964174d | ||
|
|
897418ead3 | ||
|
|
eef09e1ffe | ||
|
|
fdb2b1195e | ||
|
|
4b3e036e2a | ||
|
|
3233e7fc54 | ||
|
|
dd98a1316a | ||
|
|
e5030a8fbe | ||
|
|
f549560e47 | ||
|
|
33d26238ce | ||
|
|
bcec478a64 | ||
|
|
8971d39683 | ||
|
|
1c1631f131 | ||
|
|
14b1ff79e0 | ||
|
|
479aaf503b | ||
|
|
240cccf8a1 | ||
|
|
2599dc2672 | ||
|
|
e2668f20b7 | ||
|
|
cf767c7ef2 | ||
|
|
14a7787e3d | ||
|
|
db963eb5de | ||
|
|
a1812cd954 | ||
|
|
5ed9d1749a | ||
|
|
17ca209862 | ||
|
|
03192c1dfd | ||
|
|
6f03fae233 | ||
|
|
22fc0c994d | ||
|
|
a1ccbc5757 | ||
|
|
053cf10198 | ||
|
|
257efd8ad7 | ||
|
|
b75cfc063b | ||
|
|
2d8420131d | ||
|
|
c793b68aed | ||
|
|
47af459f24 | ||
|
|
f10e0f2bf1 | ||
|
|
569d60cb57 | ||
|
|
74d36a6a2d | ||
|
|
ced073d26c | ||
|
|
cc34e69524 | ||
|
|
d4864deac5 | ||
|
|
125207880d | ||
|
|
a8f17f40f5 | ||
|
|
dbde3c4669 | ||
|
|
ba4fecb0cb | ||
|
|
ef04dcc37b | ||
|
|
65126b3a23 | ||
|
|
58495e6276 | ||
|
|
706976439d | ||
|
|
0a9ffd3dc8 | ||
|
|
fb30c0ba2b | ||
|
|
97e4d8e132 | ||
|
|
5bdff3929b | ||
|
|
a08562bfe2 | ||
|
|
2b4319ea55 | ||
|
|
c32405720d | ||
|
|
b9ba3cd3e8 | ||
|
|
31381c860b | ||
|
|
e410a07cac | ||
|
|
9f93cd8705 | ||
|
|
dd391be095 | ||
|
|
f84f8c1c2b | ||
|
|
301967d204 | ||
|
|
c9b98a6154 | ||
|
|
ab8e474339 | ||
|
|
8a26011e76 | ||
|
|
d4de1dc9a1 | ||
|
|
4e3bd4e282 | ||
|
|
d24528f6a6 | ||
|
|
1b1d41605b | ||
|
|
6955731def | ||
|
|
4386891716 | ||
|
|
6741aba880 | ||
|
|
ee8ee7af82 | ||
|
|
a2e323c9ee | ||
|
|
f8fb23e05f | ||
|
|
a3839461cf | ||
|
|
858c7e393f | ||
|
|
0278241006 | ||
|
|
3afb682fc6 | ||
|
|
06f1df1995 | ||
|
|
3489771d2e | ||
|
|
448ae5a2b7 | ||
|
|
72340790e5 | ||
|
|
c9423fe478 | ||
|
|
02a850ae63 | ||
|
|
ede6d0c3cc | ||
|
|
7685989a8c | ||
|
|
4e8ebb5e5c | ||
|
|
3f77ab19ed | ||
|
|
d3d0c8c523 | ||
|
|
4e093131f3 | ||
|
|
6ca8a4e5fd | ||
|
|
63b15ded60 | ||
|
|
85e65aeffe | ||
|
|
ad44398492 | ||
|
|
a4ba41bf15 | ||
|
|
4441be5380 | ||
|
|
c0accb42fa | ||
|
|
7223c2b197 | ||
|
|
7b535a1c2a | ||
|
|
0aa76567a6 | ||
|
|
6fa1369c49 | ||
|
|
b66d99c59c | ||
|
|
a9cfc37aac | ||
|
|
be37f077d3 | ||
|
|
f52d020a3c | ||
|
|
74cf3f076e | ||
|
|
84adf79564 | ||
|
|
dc0d923cee | ||
|
|
2ffd7476aa | ||
|
|
034fd06284 | ||
|
|
49aac6bdca | ||
|
|
4e4a7be7ef | ||
|
|
9c1bdf16e4 | ||
|
|
9e527ff141 | ||
|
|
c6022ad977 | ||
|
|
ea9a3539eb | ||
|
|
e4f0dddf82 | ||
|
|
be425cff6f | ||
|
|
e225bc9f66 | ||
|
|
f19643095e | ||
|
|
37cc81a36d | ||
|
|
863bf62f8d | ||
|
|
9a6390bb4d | ||
|
|
62de07e4e6 | ||
|
|
6e46317a37 | ||
|
|
b59f208e91 | ||
|
|
8fdc7403b1 | ||
|
|
895cd11e30 | ||
|
|
58ce3a4967 | ||
|
|
bdd4deb302 | ||
|
|
ec2a56cd73 | ||
|
|
10a5864a47 | ||
|
|
16766be82f | ||
|
|
1884410e0d | ||
|
|
6d57da2053 | ||
|
|
e4adbb9469 | ||
|
|
8ee621295c | ||
|
|
32920dd825 | ||
|
|
2d5d2d5df8 | ||
|
|
8dd32bbe98 | ||
|
|
f71830e0fa | ||
|
|
bd0d6a9ac0 | ||
|
|
dfef0df464 | ||
|
|
9821737431 | ||
|
|
f932ce7706 | ||
|
|
de3019e92b | ||
|
|
20b616a7c4 | ||
|
|
4180544e0a | ||
|
|
9168d349fc | ||
|
|
3dad6b317f | ||
|
|
4a2605bc1e | ||
|
|
41543e3af0 | ||
|
|
6003f1a10e | ||
|
|
3d9be0cc3f | ||
|
|
5e7444f115 | ||
|
|
20fcf70e90 | ||
|
|
0508f13cb6 | ||
|
|
2f68c62b3a | ||
|
|
ea64e08791 | ||
|
|
6f485d62ad | ||
|
|
362fc11c81 | ||
|
|
9e9fb0a9fc | ||
|
|
ff4c7f47b2 | ||
|
|
25016053ca | ||
|
|
f9c0c1bc53 | ||
|
|
73e54a5fbb | ||
|
|
6f902e2107 | ||
|
|
ecb1379585 | ||
|
|
068711e7a9 | ||
|
|
f695fe0ee7 | ||
|
|
6cdc07406d | ||
|
|
daf6999111 | ||
|
|
42731521f1 | ||
|
|
182119aedf | ||
|
|
59e18b3104 | ||
|
|
5c1f198397 | ||
|
|
3cd6718384 | ||
|
|
1903980b71 | ||
|
|
84a28e045b | ||
|
|
d0aef27f7b | ||
|
|
d6a74b0cfe | ||
|
|
0c43eb0d22 | ||
|
|
f8494030aa | ||
|
|
817151e47c | ||
|
|
d5dfb609cf | ||
|
|
09aae0edc9 | ||
|
|
6aa6db4e8c | ||
|
|
76be502e16 | ||
|
|
04659a8198 | ||
|
|
6c16688ca9 | ||
|
|
f2ec89e62b | ||
|
|
edd09b0b16 | ||
|
|
59edc8d618 | ||
|
|
56520572b2 | ||
|
|
487bdd1e48 | ||
|
|
8ad5e011ca | ||
|
|
6f43fc272b | ||
|
|
e008b657a5 | ||
|
|
365367dd16 | ||
|
|
36367e475e | ||
|
|
13f2961e43 | ||
|
|
69b70d70a8 | ||
|
|
d0d0dcf09f | ||
|
|
41b9729b9b | ||
|
|
a2009cae39 | ||
|
|
fab086b3e1 | ||
|
|
f379126242 | ||
|
|
8e0d9f2da6 | ||
|
|
e931b5c8ef | ||
|
|
84617d0c49 | ||
|
|
0908cf4e94 | ||
|
|
916f27c5ab | ||
|
|
9b442d04d9 | ||
|
|
9024b2eec5 | ||
|
|
4624a29332 | ||
|
|
3d2cef40d5 | ||
|
|
e8f8be1940 | ||
|
|
49faba6ad2 | ||
|
|
b9d90aa635 | ||
|
|
5bcf65dd67 | ||
|
|
742d2ed9c3 | ||
|
|
86128f953a | ||
|
|
b8e5a6944e | ||
|
|
4508fad588 | ||
|
|
fd2f500038 | ||
|
|
a20374d6e3 | ||
|
|
ffc69dbaba | ||
|
|
6b98655069 | ||
|
|
b5a9a93323 | ||
|
|
5fbf5b22c0 | ||
|
|
99cd96faa8 | ||
|
|
c4b60f1720 | ||
|
|
a19bf3dc0e | ||
|
|
77021d2af8 | ||
|
|
16893ec0e3 | ||
|
|
d49cc87b8c | ||
|
|
c998d2566e | ||
|
|
84a9438a70 | ||
|
|
09ae3515f7 | ||
|
|
b665c17be8 | ||
|
|
eccd852426 | ||
|
|
827e3ec0a0 | ||
|
|
801c03981a | ||
|
|
31a001bbc1 | ||
|
|
621ed5fb02 | ||
|
|
887e437d35 | ||
|
|
1ea196051f | ||
|
|
366f528853 | ||
|
|
d6c8af7ed5 | ||
|
|
4dd33a2f9e | ||
|
|
1009695a15 | ||
|
|
d3427375b0 | ||
|
|
5c8ed9a8ca | ||
|
|
9c5d817a8a | ||
|
|
d51a1c47c7 | ||
|
|
2b7378bd64 | ||
|
|
c1bb934fc6 | ||
|
|
0d223e3ab5 | ||
|
|
b704e0c8ed | ||
|
|
79279479b1 | ||
|
|
ee4d7c88f1 | ||
|
|
09023f2b49 | ||
|
|
36cfcc2093 | ||
|
|
c2d455f166 | ||
|
|
6859509eb5 | ||
|
|
e2de39ad83 | ||
|
|
ca2307e609 | ||
|
|
0c58b5b83d | ||
|
|
74a12bd606 | ||
|
|
9bb9e13ee8 | ||
|
|
19787a3f51 | ||
|
|
650ab71a83 | ||
|
|
90def724c2 | ||
|
|
f357275fd3 | ||
|
|
2c2a13b587 | ||
|
|
b3a664e0d4 | ||
|
|
3140dab99d | ||
|
|
a74b2da147 | ||
|
|
701fef08f8 | ||
|
|
37ecf75087 | ||
|
|
4c99e379f2 | ||
|
|
fc2c740843 | ||
|
|
1358336a76 | ||
|
|
a02eb5445b | ||
|
|
195cc9cee0 | ||
|
|
719b395b7b | ||
|
|
27fba4ba11 | ||
|
|
6667b620d1 | ||
|
|
c77f3395b2 | ||
|
|
067f471766 | ||
|
|
f75d824c92 | ||
|
|
c4f582e35b | ||
|
|
a8727d9a68 | ||
|
|
423dae5208 | ||
|
|
dc7d8d6018 | ||
|
|
db09ded836 | ||
|
|
df33ff7f60 | ||
|
|
ca63c09a0d | ||
|
|
9c2cd868a7 | ||
|
|
f6d64e8fde | ||
|
|
253e64884a | ||
|
|
a88593fec5 | ||
|
|
6c4548a303 | ||
|
|
4851f18079 | ||
|
|
bbb917c405 | ||
|
|
81d34dfa86 | ||
|
|
31723a2d3c | ||
|
|
975427b319 | ||
|
|
d9983debce | ||
|
|
6a12ef0e2c | ||
|
|
56ba342346 | ||
|
|
6d810a421a | ||
|
|
098519dea1 | ||
|
|
7183b3d761 | ||
|
|
0ac49d846f | ||
|
|
cade2c182c | ||
|
|
affeec82f0 | ||
|
|
a75538c093 | ||
|
|
037cc86c1f | ||
|
|
1e8d550e96 | ||
|
|
acc379d14d | ||
|
|
5bc63a5ad3 | ||
|
|
a8630e93bc | ||
|
|
9574e8e639 | ||
|
|
14dacb2352 | ||
|
|
8baa2a72fb | ||
|
|
a5427f7287 | ||
|
|
9180f5c8d0 | ||
|
|
b5abce161f | ||
|
|
8b3ede4218 | ||
|
|
a4e024c690 | ||
|
|
e368e35e74 | ||
|
|
1e09305fb3 | ||
|
|
4d32bb2330 | ||
|
|
46710c9501 | ||
|
|
79d131c7eb | ||
|
|
b1955363a6 | ||
|
|
495dbbb7f8 | ||
|
|
e0d0736f7e | ||
|
|
12bfebd8b5 | ||
|
|
af791f78b7 | ||
|
|
0f4af98a21 | ||
|
|
75b357a069 | ||
|
|
d7814e115d | ||
|
|
24295ea482 | ||
|
|
701bf853d5 | ||
|
|
7fd3d737b8 | ||
|
|
497b0bca0b | ||
|
|
208015a911 | ||
|
|
8abe2283d7 | ||
|
|
9e97c068d8 | ||
|
|
abbfb3ca2f | ||
|
|
5c8e7a8b38 | ||
|
|
0d7934e3b8 | ||
|
|
e4cc8ef509 | ||
|
|
d670a5cbb6 | ||
|
|
227386bb0d | ||
|
|
abd679d716 | ||
|
|
ec5e3b0050 | ||
|
|
494616e9f2 | ||
|
|
82f81dc154 | ||
|
|
316fe72ea5 | ||
|
|
6266f29b99 | ||
|
|
fd9653e283 | ||
|
|
b2f4366415 | ||
|
|
f859c34442 | ||
|
|
c52d5e9a74 | ||
|
|
021fee616d | ||
|
|
0409fcec2f | ||
|
|
8e754cfeb5 | ||
|
|
adf3d9540d | ||
|
|
d5f2ada8f7 | ||
|
|
a01da5452c | ||
|
|
17d61277fa | ||
|
|
bb3de4b74b | ||
|
|
01fe08f079 | ||
|
|
8b7547ae38 | ||
|
|
0437503b75 | ||
|
|
2fea772ffb | ||
|
|
24765db045 | ||
|
|
82393f2ae7 | ||
|
|
c86c98d000 | ||
|
|
4d9741c424 | ||
|
|
81ec068747 | ||
|
|
4a031f7bbd | ||
|
|
5b00ac17e5 | ||
|
|
9952c3a0c1 | ||
|
|
cae6f12ea0 | ||
|
|
ef08d8e538 | ||
|
|
8457d1484b | ||
|
|
591fcfaf40 | ||
|
|
dfd4cbd7ca | ||
|
|
b48601ed06 | ||
|
|
39ab03786c | ||
|
|
246df0d107 | ||
|
|
a873e6623b | ||
|
|
fa4bca5cb8 | ||
|
|
7e81083c04 | ||
|
|
c082148ecd | ||
|
|
76b1d1df8c | ||
|
|
02dd2a3980 | ||
|
|
c1b1e67a2c | ||
|
|
b7f514c6cc | ||
|
|
547ec730c7 | ||
|
|
6ceed4b226 | ||
|
|
7e8ceadfd4 | ||
|
|
fee8d6c34e | ||
|
|
9aa70359a8 | ||
|
|
58cbc1ada5 | ||
|
|
5f7d550a5a | ||
|
|
b5d788ca6c | ||
|
|
217b5700a2 | ||
|
|
ca7cfb30c7 | ||
|
|
283a915a12 | ||
|
|
24271a2388 | ||
|
|
3e5b842b7a | ||
|
|
465f7ac0c5 | ||
|
|
284f156e9f | ||
|
|
ac25a36bce | ||
|
|
f2e653b732 | ||
|
|
7f445e9b8c | ||
|
|
57e27fb0fa | ||
|
|
e86c9df39d | ||
|
|
1f060b8513 | ||
|
|
c970e9c015 | ||
|
|
10ef25eabb | ||
|
|
381cbe837b | ||
|
|
c39bb78e38 | ||
|
|
6ec1dcf088 | ||
|
|
742c0edd9e | ||
|
|
eff3189ded | ||
|
|
7d480ffbd6 | ||
|
|
d851f32ea0 | ||
|
|
88b1a370d4 | ||
|
|
b8957d386a | ||
|
|
414e2ed2cd | ||
|
|
2987f507fe | ||
|
|
2cfb637451 | ||
|
|
47b0ccdf78 | ||
|
|
7184c5f5c7 | ||
|
|
53d45dafc2 | ||
|
|
d90cc09620 | ||
|
|
c741ba26cc | ||
|
|
510a6977be | ||
|
|
d83e1a5c6b | ||
|
|
1557a6e1c0 | ||
|
|
396cf14d61 | ||
|
|
4685330eaf | ||
|
|
8cd77ad1d8 | ||
|
|
3b0e59c8ab | ||
|
|
1f230383ce | ||
|
|
a1a920ee67 | ||
|
|
1aa2299b55 | ||
|
|
b188b3feb3 | ||
|
|
5ab1263495 | ||
|
|
7bb3059cd9 | ||
|
|
42db6001ed | ||
|
|
3fa07f64d3 | ||
|
|
648b40a8f5 | ||
|
|
ac46026f99 | ||
|
|
3ef56ce66e | ||
|
|
b4998d3603 | ||
|
|
ae2cd947b2 | ||
|
|
aae00e1312 | ||
|
|
24e90f0a54 | ||
|
|
f5208a85b0 | ||
|
|
8db4b3f83b | ||
|
|
33ad04d036 | ||
|
|
4bcdb3f495 | ||
|
|
70979172b0 | ||
|
|
493b9a3975 | ||
|
|
5a21a67d46 | ||
|
|
ff72c906ba | ||
|
|
907b1f67ed | ||
|
|
72cbe7f905 | ||
|
|
deb16aa7ab | ||
|
|
d0efa44c9e | ||
|
|
d321843c02 | ||
|
|
2b44b145cb | ||
|
|
9f5606889e | ||
|
|
417f2a8b91 | ||
|
|
d3a7bf967e | ||
|
|
db145cd8ad | ||
|
|
7d614f7ac5 | ||
|
|
c7a2a3e29b | ||
|
|
3b966c03ee | ||
|
|
66d943d391 | ||
|
|
f5f876e458 | ||
|
|
27c3439120 | ||
|
|
f212d04261 | ||
|
|
06f01aa85c | ||
|
|
5f48dc08a9 | ||
|
|
e81e056758 | ||
|
|
2d95ff0830 | ||
|
|
81d921d625 | ||
|
|
e988513ed7 | ||
|
|
783d4f82d9 | ||
|
|
b5011f458f | ||
|
|
5d0e4366d2 | ||
|
|
8643dc02dd | ||
|
|
7c4dcb2817 | ||
|
|
6b64fdafcb | ||
|
|
185dd47668 | ||
|
|
f165665a35 | ||
|
|
ad38749f98 | ||
|
|
7825dd64ca | ||
|
|
f6af620643 | ||
|
|
b5aeef7ebf | ||
|
|
f5a201dd94 | ||
|
|
72dab12033 | ||
|
|
ce4b4ba41d | ||
|
|
945206153d | ||
|
|
9f977d082b | ||
|
|
4a2ec0c40c | ||
|
|
70bf61a645 | ||
|
|
674f4b1095 | ||
|
|
3304070034 | ||
|
|
19ca5f08c6 | ||
|
|
5605910ac8 | ||
|
|
b1eda435a5 | ||
|
|
e88ca8430e | ||
|
|
d39db02a73 | ||
|
|
86a64ca929 | ||
|
|
5ea0f7d4c7 | ||
|
|
b3fa2fa6d2 | ||
|
|
999dc640bc | ||
|
|
9be9658ffb | ||
|
|
595d5362f6 | ||
|
|
f212fcf892 | ||
|
|
8c1c5572c0 | ||
|
|
31d151638a | ||
|
|
fb6b41630c | ||
|
|
6ab806cbde | ||
|
|
c0267f7746 | ||
|
|
a54b6dc7b9 | ||
|
|
9ec43ebe70 | ||
|
|
486cd68bf7 | ||
|
|
98c050e7e9 | ||
|
|
25fcee984b | ||
|
|
86922c4547 | ||
|
|
7bbdfd25cd | ||
|
|
b8ad22a6fb | ||
|
|
8dd955563e | ||
|
|
663ab83b08 | ||
|
|
c143929b69 | ||
|
|
1b73d248b3 | ||
|
|
cc22a92daf | ||
|
|
39f0408929 | ||
|
|
e66f46a464 | ||
|
|
9243296197 | ||
|
|
26ce83f8f1 | ||
|
|
907ef38189 | ||
|
|
a7d4001b00 | ||
|
|
e3a3379615 | ||
|
|
356a06e694 | ||
|
|
fce516a76f | ||
|
|
42ade0fbd1 | ||
|
|
ba07f5dad4 | ||
|
|
cc89e0f3f1 | ||
|
|
0e14d3f9c1 | ||
|
|
ff7975773e | ||
|
|
6716e2277d | ||
|
|
f986dc5d11 | ||
|
|
570a4096f9 | ||
|
|
c88bfbb5f0 | ||
|
|
d302795512 | ||
|
|
115acce80c | ||
|
|
a8731b0ca2 | ||
|
|
fd596bf418 | ||
|
|
ef7cfffeb6 | ||
|
|
ac9bcabd9c | ||
|
|
5bb961f16b | ||
|
|
a46677832b | ||
|
|
624abf0df4 | ||
|
|
e81a4ade97 | ||
|
|
9708685506 | ||
|
|
28b6bf8603 | ||
|
|
2713f0e610 | ||
|
|
f7d1cd2a4f | ||
|
|
3b8963fad0 | ||
|
|
060682a1ac | ||
|
|
95cd48571e | ||
|
|
3d619e6a98 | ||
|
|
edb7e5f323 | ||
|
|
0221034b60 | ||
|
|
9500384100 | ||
|
|
0b31f2eb41 | ||
|
|
b3a6393c91 | ||
|
|
5b5599128a | ||
|
|
cb0f03ca9c | ||
|
|
2e35f3608b | ||
|
|
16c5a5a3a6 | ||
|
|
2e7db502a9 | ||
|
|
d29b71ec45 | ||
|
|
9cd0af914a | ||
|
|
4a575393f0 | ||
|
|
76c93c767d | ||
|
|
e69337a1fc | ||
|
|
50734af6cd | ||
|
|
81b0922c93 | ||
|
|
d4f8fff7af | ||
|
|
bd61f5d591 | ||
|
|
016c3d779b | ||
|
|
acf26940d6 | ||
|
|
4bafae881f | ||
|
|
8311451420 | ||
|
|
4b75cb8357 | ||
|
|
bf16d360af | ||
|
|
38d95b4faf | ||
|
|
b06e7d3cf4 | ||
|
|
9e7ea82f94 | ||
|
|
d74fc8a5d5 | ||
|
|
4a43b45a99 | ||
|
|
d6a72fbfc4 | ||
|
|
396f737612 | ||
|
|
2dd8d5a119 | ||
|
|
656c5b61cc | ||
|
|
9fd0f6834a | ||
|
|
58dac27186 | ||
|
|
c8befb6843 | ||
|
|
fafd47fd90 | ||
|
|
e0990910f6 | ||
|
|
599f23c8aa | ||
|
|
a0bd011b80 | ||
|
|
157c27c20d | ||
|
|
4d0407a3b3 | ||
|
|
f73ed1213f | ||
|
|
679ffbcce7 | ||
|
|
daabe11d11 | ||
|
|
aaf125cfca | ||
|
|
161fc6bb68 | ||
|
|
1afed9f256 | ||
|
|
e8d6c15fee | ||
|
|
8686b28c28 | ||
|
|
d68251ad4b | ||
|
|
a02b4ae08f | ||
|
|
9ed1dd714b | ||
|
|
95dc6c66d9 | ||
|
|
e91c76c10c | ||
|
|
9deddbbe7c | ||
|
|
2d416d491c | ||
|
|
a19ce0458a | ||
|
|
3fca24e6fd | ||
|
|
6f956e0423 | ||
|
|
637a923e84 | ||
|
|
bb3ce9fbc6 | ||
|
|
06f2340569 | ||
|
|
510c29cc71 | ||
|
|
807aa04807 | ||
|
|
c84e2e0537 | ||
|
|
1f8d569b79 | ||
|
|
93ae24e707 | ||
|
|
910e219c0e | ||
|
|
3a4843fb46 | ||
|
|
1b3744baa2 | ||
|
|
7dd340f0b6 | ||
|
|
1d0d8d7fbe | ||
|
|
c7d8c8b104 | ||
|
|
a380d39865 | ||
|
|
34d3310eae | ||
|
|
6de8d2684a | ||
|
|
9763a43943 | ||
|
|
f328eec26d | ||
|
|
7684a54678 | ||
|
|
51f3174609 | ||
|
|
4fcd518b0a | ||
|
|
1e0d7c7e28 | ||
|
|
984da93a7b | ||
|
|
c2c7eda799 | ||
|
|
04b85630b9 | ||
|
|
ae4f3759c2 | ||
|
|
a238dcc5e6 | ||
|
|
57ba84107c | ||
|
|
ca913cafbc | ||
|
|
7032421096 | ||
|
|
06ac959496 | ||
|
|
41c15f8c96 | ||
|
|
5cad3dfbae | ||
|
|
49a20a303a | ||
|
|
90f74427d9 | ||
|
|
ba9dc6ce26 | ||
|
|
3a73994ad4 | ||
|
|
797e1f1f21 | ||
|
|
f1713647cf | ||
|
|
8704d3acb3 | ||
|
|
ce4250281f | ||
|
|
aecbc714c4 | ||
|
|
c20242cf1c | ||
|
|
04ba76aac8 | ||
|
|
d1bc65c266 | ||
|
|
60edbcd5f0 | ||
|
|
dab284f339 | ||
|
|
df76d9a50a | ||
|
|
abec2e48d4 | ||
|
|
0f2ddb452c | ||
|
|
6fa1acc461 | ||
|
|
9502639447 | ||
|
|
ef4acb1b66 | ||
|
|
8cb72d306b | ||
|
|
1ef8bf4690 | ||
|
|
22779c9dbc | ||
|
|
b52467b6d6 | ||
|
|
d33a0cd589 | ||
|
|
a04cb54d86 | ||
|
|
10785f156f | ||
|
|
4736fb8e32 | ||
|
|
531e7ec73d | ||
|
|
ff946b4f2f | ||
|
|
68f0e68343 | ||
|
|
12a3520563 | ||
|
|
e84426a4f9 | ||
|
|
8b80934f77 | ||
|
|
b6618f81f8 | ||
|
|
8140db32dd | ||
|
|
13db5f4423 | ||
|
|
0ae1e40d79 | ||
|
|
34d931573c | ||
|
|
721365578a | ||
|
|
7be02318e0 | ||
|
|
88db79188c | ||
|
|
8a0329b23d | ||
|
|
02ebe59d2f | ||
|
|
6e8e053b88 | ||
|
|
fc3056b0e0 | ||
|
|
4274a8ed68 | ||
|
|
8b16cd1b36 | ||
|
|
bd49d6bd89 | ||
|
|
61fd6f1741 | ||
|
|
05d45d9aab | ||
|
|
612eb64a83 | ||
|
|
e0a9e62d84 | ||
|
|
5db5f2251f | ||
|
|
34fd9d29c8 | ||
|
|
5148e27448 | ||
|
|
c6d8476963 | ||
|
|
608e55c01f | ||
|
|
b8963d272a | ||
|
|
beaaed6613 | ||
|
|
6bbd8c9b16 | ||
|
|
872ffa02ce | ||
|
|
1d9fe0c03d | ||
|
|
5b2d36e976 | ||
|
|
547135f7d2 | ||
|
|
15f1416f52 | ||
|
|
b2709aa816 | ||
|
|
9775d4e74d | ||
|
|
f5661af1f4 | ||
|
|
7394fdc162 | ||
|
|
a4f133eb46 | ||
|
|
53007465cd | ||
|
|
e1a748016a | ||
|
|
b933202694 | ||
|
|
611bec38b4 | ||
|
|
89c7adfbcd | ||
|
|
4de64d9a43 | ||
|
|
deedf4fc8b | ||
|
|
e9e99956ad | ||
|
|
08b26f9d5d | ||
|
|
99ea06e22a | ||
|
|
49cf0c8a9a | ||
|
|
83ccf4928f | ||
|
|
28b0d34bff | ||
|
|
49cecf837b | ||
|
|
5a166d2455 | ||
|
|
6808d270a7 | ||
|
|
9dc68611a1 | ||
|
|
2877919639 | ||
|
|
76447019c0 | ||
|
|
e932f38160 | ||
|
|
9014835880 | ||
|
|
00328d04cd | ||
|
|
5b1850e161 | ||
|
|
60727656c9 | ||
|
|
372d021062 | ||
|
|
9c4421bfe0 | ||
|
|
5f85af76cd | ||
|
|
4c2565826f | ||
|
|
3e7fd80824 | ||
|
|
6699b4cb33 | ||
|
|
ae2d83c8aa | ||
|
|
3b0216ca7e | ||
|
|
0a0837ea02 | ||
|
|
a0aa350a08 | ||
|
|
1abfb175b5 | ||
|
|
a771695348 | ||
|
|
decfcb6c27 | ||
|
|
730913bec4 | ||
|
|
f8f037196e | ||
|
|
fe3e4edb04 | ||
|
|
364a4faa75 | ||
|
|
e2ffeab8fa | ||
|
|
331787fe43 | ||
|
|
9484a7237c | ||
|
|
04d834187b | ||
|
|
96063969ae | ||
|
|
cb1c8be870 | ||
|
|
33b2a94d90 | ||
|
|
ce3b024fea | ||
|
|
a02aa7586b | ||
|
|
5ea71da181 | ||
|
|
3ff0ff238a | ||
|
|
dda469d10e | ||
|
|
9f6e033c53 | ||
|
|
15f44adf3b | ||
|
|
e9483cb242 | ||
|
|
5243d8bedf | ||
|
|
ed731fd7a6 | ||
|
|
07f5422132 | ||
|
|
5aa1764848 | ||
|
|
4973ee555b | ||
|
|
d5107f2ef6 | ||
|
|
5b63b0b398 | ||
|
|
4bfccba4c0 | ||
|
|
5ddad8ebc2 | ||
|
|
b5921897d6 | ||
|
|
53a46b88b8 | ||
|
|
da977ccace | ||
|
|
7b9a2167ad | ||
|
|
fc16771355 | ||
|
|
3ef3fbfd0e | ||
|
|
415a0aaf75 | ||
|
|
5a4a9b570e | ||
|
|
2df60d6387 | ||
|
|
9c176013ab | ||
|
|
036d251e15 | ||
|
|
925060689a | ||
|
|
f0631d734e | ||
|
|
52b299315d | ||
|
|
0195e94aa7 | ||
|
|
75f0b2b82c | ||
|
|
f26f283c1f | ||
|
|
7c387b2aee | ||
|
|
071ecb284e | ||
|
|
03242942c2 | ||
|
|
a476927595 | ||
|
|
ec6e1704be | ||
|
|
d2f189607e | ||
|
|
c13777e68d | ||
|
|
fc577241bd | ||
|
|
bb8a0e596c | ||
|
|
2a63b703f9 | ||
|
|
bfeff78164 | ||
|
|
4826289020 | ||
|
|
0aebf37ef8 | ||
|
|
2fb63dcfb1 | ||
|
|
0adb7685f6 | ||
|
|
1cbe99a0d8 | ||
|
|
d1a09d0b95 | ||
|
|
7b00003958 | ||
|
|
4483bb147c | ||
|
|
fa83da6085 | ||
|
|
ef31c0c0da | ||
|
|
1392c16f12 | ||
|
|
d6393653e1 | ||
|
|
a75de51198 | ||
|
|
a21869ec9b | ||
|
|
f534e4ee37 | ||
|
|
9add661a5b | ||
|
|
76c885f080 | ||
|
|
f16e93bd3a | ||
|
|
05d2a96900 | ||
|
|
81948a5c29 | ||
|
|
5924154a62 | ||
|
|
354bfe58cd | ||
|
|
c5974a8575 | ||
|
|
c0275addb0 | ||
|
|
9c70c35669 | ||
|
|
c85baf7fd0 | ||
|
|
39e5778bd0 | ||
|
|
a3b77bb37f | ||
|
|
9d54c41a2b | ||
|
|
660cf0c1e4 | ||
|
|
3464fbb2e8 | ||
|
|
11020c4545 | ||
|
|
e93bf02e3a | ||
|
|
d51d6517be | ||
|
|
a629d7f048 | ||
|
|
5f6cc1281e | ||
|
|
683b0f5c48 | ||
|
|
42a80a41ca | ||
|
|
035fc69060 | ||
|
|
34baf44534 | ||
|
|
9dcb90a9cf | ||
|
|
c3448033de | ||
|
|
aee9b6a951 | ||
|
|
1af0aa3f57 | ||
|
|
35c9338220 | ||
|
|
2e8fa0f6c5 | ||
|
|
931aeda17f | ||
|
|
a037d24b0f | ||
|
|
75e5bec962 | ||
|
|
59c269c8d0 | ||
|
|
1fa556cd00 | ||
|
|
82e9ad8a20 | ||
|
|
541022cdc3 | ||
|
|
d893765b24 | ||
|
|
527521328f | ||
|
|
917b89e44f | ||
|
|
87862f3e23 | ||
|
|
10eed05d87 | ||
|
|
f5802fee31 | ||
|
|
1108b0264e | ||
|
|
cf9c8cbb4f | ||
|
|
4f060579ca | ||
|
|
1940c6e1ba | ||
|
|
f199ecf8e9 | ||
|
|
e754f6c234 | ||
|
|
d19dbbfe7e | ||
|
|
3a735ea0ce | ||
|
|
e319d19a54 | ||
|
|
3bdd551d40 | ||
|
|
4a7936a51d | ||
|
|
5f075e4936 | ||
|
|
76e00c2432 | ||
|
|
b46f3bf2c4 | ||
|
|
f7b4b782bf | ||
|
|
60c535e861 | ||
|
|
d59c522f7f | ||
|
|
9f798559cf | ||
|
|
f939e59463 | ||
|
|
50e89ad98b | ||
|
|
c0c5978028 | ||
|
|
abbeed394e | ||
|
|
f5b8c15388 | ||
|
|
f53b6b550f | ||
|
|
00e55b1874 | ||
|
|
90954dac49 | ||
|
|
6217523cc8 | ||
|
|
27ccd3dfa8 | ||
|
|
235f4f10ef | ||
|
|
d6ba3f3adf | ||
|
|
b453e2cf1a | ||
|
|
2d14e5682d | ||
|
|
945e5a2dc3 | ||
|
|
4b6a2685d0 | ||
|
|
1f58aebb2b | ||
|
|
6d70ced93a | ||
|
|
e76b6c3bde | ||
|
|
4630d175d7 | ||
|
|
27055b96e3 | ||
|
|
0ef96c0bca | ||
|
|
b2be4a7d67 | ||
|
|
a70df067bc | ||
|
|
2d92b08404 | ||
|
|
4bbc57b0dc | ||
|
|
756c14d988 | ||
|
|
b3b55210f7 | ||
|
|
58093a9438 | ||
|
|
ed33dd2127 | ||
|
|
accc53c5dd | ||
|
|
d4f9c97cca | ||
|
|
f731c1080d | ||
|
|
fd18185ef0 | ||
|
|
0efbbed5e2 | ||
|
|
bad350e49b | ||
|
|
172b93d07f | ||
|
|
ade8c162cd | ||
|
|
79e634316d | ||
|
|
e4cb8b71dd | ||
|
|
dfba6c7c91 | ||
|
|
f6eff090e7 | ||
|
|
e06a77af28 | ||
|
|
61a2c362b9 | ||
|
|
74973e73e6 | ||
|
|
cbcee037a7 | ||
|
|
de2e4a9c7f | ||
|
|
0ba0a5bcd8 | ||
|
|
70cc409402 | ||
|
|
160ca610ae | ||
|
|
2f1aa95f4c | ||
|
|
ac07ac5234 | ||
|
|
3eead128a6 | ||
|
|
4c22a73ff3 | ||
|
|
a78f58de92 | ||
|
|
fcda48903b | ||
|
|
3f9805ac56 | ||
|
|
2131fed0bb | ||
|
|
baa5d2fcac | ||
|
|
7cf9b76eb5 | ||
|
|
200648275e | ||
|
|
f4880d0519 | ||
|
|
375f992a0c | ||
|
|
a7584d62c7 | ||
|
|
74e6caf633 | ||
|
|
f1f531cbfa | ||
|
|
b5a275ad07 | ||
|
|
5051ad91ff | ||
|
|
06d6cb6d19 | ||
|
|
92116273b0 | ||
|
|
6169ff99a2 | ||
|
|
67f77d027a | ||
|
|
39e1a803a1 | ||
|
|
ba159e1a3e | ||
|
|
a60b77121a | ||
|
|
810f0104be | ||
|
|
07489fb405 | ||
|
|
82f0bdfc18 | ||
|
|
ae1c5342f2 | ||
|
|
66154b30c1 | ||
|
|
bf5d391d53 | ||
|
|
591ce0894e | ||
|
|
1c18563dfb | ||
|
|
b60e781767 | ||
|
|
ca54544b82 | ||
|
|
9c3ff71ce4 | ||
|
|
fd82ec7659 | ||
|
|
97ccb7df94 | ||
|
|
a818199b5a | ||
|
|
6fe1fa3455 | ||
|
|
aab95444a8 | ||
|
|
40f28be3b4 | ||
|
|
911d442340 | ||
|
|
d5594b03e3 | ||
|
|
23ccaacdee | ||
|
|
89f1ddf4d7 | ||
|
|
39a4297168 | ||
|
|
6cfd4637db | ||
|
|
544111846c | ||
|
|
79bdea0441 | ||
|
|
c056c4e79e | ||
|
|
19828e9070 | ||
|
|
8231c736ca | ||
|
|
85f639b1f0 | ||
|
|
c471b6d66c | ||
|
|
a363efccfb | ||
|
|
871a17a108 | ||
|
|
16a39b364c | ||
|
|
8803e11945 | ||
|
|
b1ca2cc2b6 | ||
|
|
91f79d2be0 | ||
|
|
9932fe5055 | ||
|
|
c296597427 | ||
|
|
97cb5bc12c | ||
|
|
7c596d6bf1 | ||
|
|
b68799e2d1 | ||
|
|
9a8f3d7bad | ||
|
|
a3d4db9fc1 | ||
|
|
9d0e762f36 | ||
|
|
8369330053 | ||
|
|
46a6fee81d | ||
|
|
b2c75130ce | ||
|
|
ef444f2a6f | ||
|
|
36f0871f69 | ||
|
|
5adf27d345 | ||
|
|
5e4c261332 | ||
|
|
6fb04e23ad | ||
|
|
2c850a612d | ||
|
|
e555c4d083 | ||
|
|
cb32cca6aa | ||
|
|
abf4cd71ba | ||
|
|
d66270eef0 | ||
|
|
ffb491a61f | ||
|
|
4ecba93a25 | ||
|
|
52ec1d09b8 | ||
|
|
3d2e2e2278 | ||
|
|
f9a9ece320 | ||
|
|
ffc46d6a48 | ||
|
|
ce458642af | ||
|
|
820d3ef426 | ||
|
|
145386b6a7 | ||
|
|
a708cf7f69 | ||
|
|
c70ebb6cce | ||
|
|
07ecd13554 | ||
|
|
a260b6eac4 | ||
|
|
0ab17e1ec8 | ||
|
|
d1a0cd1173 | ||
|
|
f1ff88f452 | ||
|
|
d92272ffa0 | ||
|
|
3955b973ef | ||
|
|
dfa43f3c5a | ||
|
|
259c5ef3d0 | ||
|
|
a1b59d4545 | ||
|
|
fcfa508cbc | ||
|
|
58a61051b9 | ||
|
|
a6766ef1c0 | ||
|
|
606b5ac5ab | ||
|
|
9acc463c7f | ||
|
|
c4ddd08b0a | ||
|
|
5c7dd10769 | ||
|
|
3fa86cb441 | ||
|
|
4a74ee0d72 | ||
|
|
8a8759b0d4 | ||
|
|
f259072136 | ||
|
|
3fd74292ef | ||
|
|
f37c4293df | ||
|
|
b9248553be | ||
|
|
475d434e98 | ||
|
|
05d568d1c1 | ||
|
|
51777c3f33 | ||
|
|
3767e9fae9 | ||
|
|
4bbfc8ccc5 | ||
|
|
531b8214c0 | ||
|
|
28b63bac38 | ||
|
|
5cab618bf7 | ||
|
|
fc64719bb8 | ||
|
|
3380f4d11c | ||
|
|
4bf030993a | ||
|
|
323a74eef3 | ||
|
|
bd4da4f365 | ||
|
|
f65f949a36 | ||
|
|
2864abd8c2 | ||
|
|
9bd2cb3c7e | ||
|
|
35cd277fcf | ||
|
|
ae7f7e9bd6 | ||
|
|
57b1932b5e | ||
|
|
e6818023a3 | ||
|
|
35a541f99b | ||
|
|
5fb00a947c | ||
|
|
6288f679b9 | ||
|
|
b88e63d133 | ||
|
|
a85255df5a | ||
|
|
15c02e9e91 | ||
|
|
ec35392cd1 | ||
|
|
b14b977bca | ||
|
|
54f55d44dc | ||
|
|
568dc1625e | ||
|
|
259b239e16 | ||
|
|
3033387ffc | ||
|
|
d500c29493 | ||
|
|
799d8003eb | ||
|
|
5d34af6ac5 | ||
|
|
dca5b9f197 | ||
|
|
75e075ef8e | ||
|
|
9895976128 | ||
|
|
133367ddb5 | ||
|
|
57964282ee | ||
|
|
51b07fc0c3 | ||
|
|
d8f33641a5 | ||
|
|
a7c7234589 | ||
|
|
e766759b8c | ||
|
|
f22f1971cb | ||
|
|
28a5806492 | ||
|
|
df98167706 | ||
|
|
06cc40055a | ||
|
|
66b47c08e6 | ||
|
|
40cb8db1fc | ||
|
|
2454a03c2b | ||
|
|
0a59a06121 | ||
|
|
a7191e8efb | ||
|
|
e1f4d791ae | ||
|
|
c1d28381e8 | ||
|
|
2fa8371bae | ||
|
|
a1cfdf1a5b | ||
|
|
806fcb6ed2 | ||
|
|
467b0fa988 | ||
|
|
a420d5b203 | ||
|
|
e9c7f5d664 | ||
|
|
c85f12fe2c | ||
|
|
13e5644c89 | ||
|
|
5be3aec7d4 | ||
|
|
5e25a4a00e | ||
|
|
810cf9ab2c | ||
|
|
eac029aef4 | ||
|
|
2a11de7571 | ||
|
|
12543be913 | ||
|
|
cfbf08dbf5 | ||
|
|
3649573ba1 | ||
|
|
0fdc02d5e9 | ||
|
|
0ffe8ef102 | ||
|
|
ce995812d4 | ||
|
|
cd22e1779d | ||
|
|
fbb50d8fb6 | ||
|
|
27172c2a19 | ||
|
|
f453dff438 | ||
|
|
a437a40eee | ||
|
|
70a173a16d | ||
|
|
7724fc74e5 | ||
|
|
6023c08554 | ||
|
|
2de56065af | ||
|
|
a5195920fa | ||
|
|
5676a13290 | ||
|
|
d11f0e864e | ||
|
|
df83fcc5b9 | ||
|
|
f21c756793 | ||
|
|
4b07ee2fa8 | ||
|
|
ae3a39ee65 | ||
|
|
e9f5bd4ac1 | ||
|
|
f5cf1ca08c | ||
|
|
1f4ad732fd | ||
|
|
37a1e67579 | ||
|
|
a372cbbf52 | ||
|
|
5637d37ee1 | ||
|
|
c370da2fef | ||
|
|
d168209721 | ||
|
|
ca0468b8d5 | ||
|
|
a67cf44453 | ||
|
|
039d26feeb | ||
|
|
a4bead1bde | ||
|
|
0d15024bd2 | ||
|
|
6509d726b3 | ||
|
|
a132f0f41d | ||
|
|
7c2ea3dcfd | ||
|
|
706c6d46da | ||
|
|
04915cc65a | ||
|
|
e2fb8827a7 | ||
|
|
10e7b66f38 | ||
|
|
05fda903c6 | ||
|
|
91e1eff763 | ||
|
|
2c4ffcfa7c | ||
|
|
34d63f3557 | ||
|
|
4bb47d7e01 | ||
|
|
a5613ebb10 | ||
|
|
ec80c2b9db | ||
|
|
a89418e33b | ||
|
|
0d88ff8dae | ||
|
|
4bdf9bff3a | ||
|
|
7fbb8838e7 | ||
|
|
1a2b45eebd | ||
|
|
366ea63209 | ||
|
|
6c0ad7fe1a | ||
|
|
ef9c90a43a | ||
|
|
239214ef92 | ||
|
|
65791a58e9 | ||
|
|
6e0f22323b | ||
|
|
4c8c35a25a | ||
|
|
a149f06f58 | ||
|
|
42f97f63d5 | ||
|
|
227652de2e | ||
|
|
dd205e849c | ||
|
|
b0057b130e | ||
|
|
05d994889d | ||
|
|
4b381049c3 | ||
|
|
33f3479569 | ||
|
|
6b940ed675 | ||
|
|
247be0c11f | ||
|
|
14b0e8875d | ||
|
|
bd51741b01 | ||
|
|
afd60b8a16 | ||
|
|
6e0659af4c | ||
|
|
6de1fa0878 | ||
|
|
61e00f1620 | ||
|
|
d64c043838 | ||
|
|
c8c75b38c3 | ||
|
|
2bdd0a0e8d | ||
|
|
dd3599f5b3 | ||
|
|
4131ad5016 | ||
|
|
4f74b3fafe | ||
|
|
177a487ead | ||
|
|
99a4966786 | ||
|
|
db9279a6e5 | ||
|
|
3036f43b75 | ||
|
|
f4560bd7d8 | ||
|
|
0d56127758 | ||
|
|
97b9ec5cc7 | ||
|
|
cdab3d0eff | ||
|
|
de991041c4 | ||
|
|
776c16cd49 | ||
|
|
d9f8746438 | ||
|
|
20d1c4d242 | ||
|
|
6edac37031 | ||
|
|
cea5a18a7a | ||
|
|
bf615303f1 | ||
|
|
ea043517c5 | ||
|
|
b84d9c5d55 | ||
|
|
063585f563 | ||
|
|
01304e807a | ||
|
|
d275b3fd08 | ||
|
|
66364354da | ||
|
|
48203aedf9 | ||
|
|
a6ca893ec5 | ||
|
|
d55f1163a2 | ||
|
|
80530012b8 | ||
|
|
d98a6adfb3 | ||
|
|
6c628afe5d | ||
|
|
abc99c7e69 | ||
|
|
fe25cd3bec | ||
|
|
ae3a35816e | ||
|
|
8ca4be5ac0 | ||
|
|
1c814946d5 | ||
|
|
1db59fc052 | ||
|
|
273a69258a | ||
|
|
3b0dc2195d | ||
|
|
bbb2539ace | ||
|
|
03cfe9bf62 | ||
|
|
e29a4d79ba | ||
|
|
4243bf9ba8 | ||
|
|
2eb51edfb6 | ||
|
|
715d564028 | ||
|
|
989b704efc | ||
|
|
7ae9627a79 | ||
|
|
097a1cc799 | ||
|
|
0bfaeb8521 | ||
|
|
625511d28b | ||
|
|
b6a58ee845 | ||
|
|
a349aed94c | ||
|
|
3db00534c2 | ||
|
|
82b96d1a14 | ||
|
|
b85ddd1a53 | ||
|
|
732f88ff51 | ||
|
|
c08139b812 | ||
|
|
a6a6e73b04 | ||
|
|
9971201004 | ||
|
|
e99b0f8052 | ||
|
|
7a59b2b25d | ||
|
|
b713b324f9 | ||
|
|
521e21072e | ||
|
|
f34845fd7d | ||
|
|
29ccadbd43 | ||
|
|
ffb4b395d0 | ||
|
|
19eba9526a | ||
|
|
09ed76904b | ||
|
|
22932241bd | ||
|
|
afc95d99cb | ||
|
|
5fde3c53b8 | ||
|
|
1135852f25 | ||
|
|
e892f0cb45 | ||
|
|
de56374c4d | ||
|
|
6512dbae1c | ||
|
|
3afda71349 | ||
|
|
568e5a9bb8 | ||
|
|
89e56ae279 | ||
|
|
339ac05443 | ||
|
|
9d92b8cc6d | ||
|
|
d9b3ba0ff2 | ||
|
|
4be6b11c1e | ||
|
|
6794da0738 | ||
|
|
5527170fab | ||
|
|
72cfa683cf | ||
|
|
e732eed98a | ||
|
|
5244642dee | ||
|
|
b329a44fef | ||
|
|
3a6b9f04f9 | ||
|
|
59f24df294 | ||
|
|
c93632421d | ||
|
|
97e0fd9f43 | ||
|
|
ea536c5537 | ||
|
|
970c906c97 | ||
|
|
fe738da633 | ||
|
|
5c559af936 | ||
|
|
bb80505b76 | ||
|
|
5e3da71ce4 | ||
|
|
a0cccb299e | ||
|
|
a560f6e9f6 | ||
|
|
95ae981698 | ||
|
|
e56974f4b2 | ||
|
|
fd28da2a3b | ||
|
|
257b35e4ae | ||
|
|
4398563b85 | ||
|
|
969eb67217 | ||
|
|
e23ace1bb0 | ||
|
|
0dfebbad9d | ||
|
|
f87f4bd8cc | ||
|
|
352caa85da | ||
|
|
8f61e9876f | ||
|
|
2ef333c66d | ||
|
|
c6ee44010c | ||
|
|
71d770e679 | ||
|
|
cf17b93201 | ||
|
|
08f284ce29 | ||
|
|
4336aeb0ad | ||
|
|
5fd3a45c64 | ||
|
|
77f8bfcf25 | ||
|
|
509a97e532 | ||
|
|
604683efd5 | ||
|
|
c731515b94 | ||
|
|
8d85158f91 | ||
|
|
0736f372dc | ||
|
|
fd19bb7cd5 | ||
|
|
0c2e9137a2 | ||
|
|
bf5a25a96f | ||
|
|
aa84f21fde | ||
|
|
b9de2b4b58 | ||
|
|
9754f2d1c5 | ||
|
|
f66fc06b4f | ||
|
|
79ceb56c60 | ||
|
|
a37210b22e | ||
|
|
ccf81ff7b9 | ||
|
|
a4c1a65f10 | ||
|
|
6bdea219bf | ||
|
|
02a82e1e59 | ||
|
|
d238b0b9f2 | ||
|
|
40026fbf53 | ||
|
|
4193818259 | ||
|
|
78840157ef | ||
|
|
f3d69a29b9 | ||
|
|
1ae6709b26 | ||
|
|
8cc44b3958 | ||
|
|
70e894c268 | ||
|
|
9ff3ab1a2b | ||
|
|
8167f6f232 | ||
|
|
de844e9b23 | ||
|
|
7214b71c29 | ||
|
|
be5df46803 | ||
|
|
25bd61558b | ||
|
|
41961de619 | ||
|
|
1ca3f6ef8a | ||
|
|
f97c94832a | ||
|
|
4ae7786362 | ||
|
|
d3d553ad5a | ||
|
|
4faab006e3 | ||
|
|
80621f598e | ||
|
|
eaf689fe2f | ||
|
|
211e3304f3 | ||
|
|
d4c3b70f15 | ||
|
|
7605df1bd9 | ||
|
|
f874941e4d | ||
|
|
b91ec48178 | ||
|
|
3c2f144795 | ||
|
|
437b2ab30a | ||
|
|
0271337f8e | ||
|
|
630a71c46c | ||
|
|
dcc2a5afe0 | ||
|
|
078e952f30 | ||
|
|
2d2fe4983c | ||
|
|
29ddc04f7b | ||
|
|
aac2da70cf | ||
|
|
f5cbe0c4fe | ||
|
|
ab28d0a9b3 | ||
|
|
6aaf4ed9d9 | ||
|
|
1b81a1f4a6 | ||
|
|
e838fe30de | ||
|
|
150329dd4a | ||
|
|
6d9779a497 | ||
|
|
130ece3d2e | ||
|
|
d63a794848 | ||
|
|
ba220abbbf | ||
|
|
3825575f70 | ||
|
|
8d69961130 | ||
|
|
740357d120 | ||
|
|
5638f0f24b | ||
|
|
c8a30e793a | ||
|
|
2264281e4d | ||
|
|
ce38d4ff6b | ||
|
|
59d7bce518 | ||
|
|
3c1e3cd38e | ||
|
|
a2eb0bf9fe | ||
|
|
74773ade62 | ||
|
|
3faf777db1 | ||
|
|
09e880a90d | ||
|
|
5d48ecf86a | ||
|
|
d5785e87e8 | ||
|
|
d4a43bf051 | ||
|
|
00d09aa01e | ||
|
|
9afdc55416 | ||
|
|
76c0432f96 | ||
|
|
4434796aab | ||
|
|
0faa24d5d3 | ||
|
|
2c942c8809 | ||
|
|
c15acc4ce3 | ||
|
|
b056610eaa | ||
|
|
8eb9fb1834 | ||
|
|
7ec518b41c | ||
|
|
dc15914a85 | ||
|
|
6c3b87c9b9 | ||
|
|
2fb31f5944 | ||
|
|
8be42e78de | ||
|
|
6d242ee6c3 | ||
|
|
6c910d2b5f | ||
|
|
3b22f59988 | ||
|
|
afdab0300e | ||
|
|
0caa56e618 | ||
|
|
e5dc843d6a | ||
|
|
26533c47e7 | ||
|
|
3efd1ee325 | ||
|
|
56a1367322 | ||
|
|
544aba53dc | ||
|
|
d68bbbf9a1 | ||
|
|
df3aeed291 | ||
|
|
489737274a | ||
|
|
867ba7b68f | ||
|
|
4c1fabffc3 | ||
|
|
6a52d03329 | ||
|
|
17f00e6fea | ||
|
|
c67bc33c23 | ||
|
|
bb80dcb4e4 | ||
|
|
8fff3e5389 | ||
|
|
233109d23e | ||
|
|
a6aa78e3b6 | ||
|
|
7536322e53 | ||
|
|
b690e3d149 | ||
|
|
aabf270144 | ||
|
|
61a4f15e53 | ||
|
|
de212322e2 | ||
|
|
cda18fb957 | ||
|
|
011ba5056a | ||
|
|
44c871270b | ||
|
|
9f6b0e1018 | ||
|
|
2d9293732b | ||
|
|
d4a131ad31 | ||
|
|
fa2316fb28 | ||
|
|
6e5d1fb613 | ||
|
|
e45f0f0299 | ||
|
|
62125d0284 | ||
|
|
d5ffede5ea | ||
|
|
1679a3f844 | ||
|
|
212bb33142 | ||
|
|
1d8c80c062 | ||
|
|
e8e11257d2 | ||
|
|
1611049623 | ||
|
|
7d195367a8 | ||
|
|
b4236b9a95 | ||
|
|
d2b1404907 | ||
|
|
88a4f25689 | ||
|
|
161dee89ec | ||
|
|
34af33607b | ||
|
|
5bb188a822 | ||
|
|
f11aab6c19 | ||
|
|
1f133dbcd0 | ||
|
|
60bb6f105d | ||
|
|
df4680ee09 | ||
|
|
879576b613 | ||
|
|
6aaab09601 | ||
|
|
5da42575fd | ||
|
|
7a105a1538 | ||
|
|
fe256d6a62 | ||
|
|
5f175141e1 | ||
|
|
983e2df065 | ||
|
|
7408d7bc95 | ||
|
|
1d9820a7c9 | ||
|
|
c536f7d342 | ||
|
|
6d9dfb5deb | ||
|
|
a3d469a101 | ||
|
|
16d5a70c08 | ||
|
|
b7e2d7fb8e | ||
|
|
fb5f7a336d | ||
|
|
78dc5f4bf4 | ||
|
|
45dbf5393f | ||
|
|
97ecb0a5d6 | ||
|
|
6f58e9e7bb | ||
|
|
0de19a09ad | ||
|
|
17a56189dc | ||
|
|
520f9801be | ||
|
|
03a6b0311f | ||
|
|
9fed1cde25 | ||
|
|
5c7b175e90 | ||
|
|
30b29de8ce | ||
|
|
a5f9331023 | ||
|
|
d8b9d8431e | ||
|
|
91a2ce2b3f | ||
|
|
4da1871567 | ||
|
|
e809f77461 | ||
|
|
1a922d41df | ||
|
|
050f8f3c81 | ||
|
|
5fc32c7b85 | ||
|
|
e96d23cc3f | ||
|
|
964fa69fb4 | ||
|
|
c34e2ab3e1 | ||
|
|
f1a33db800 | ||
|
|
820519b4f7 | ||
|
|
2e3b56c52f | ||
|
|
8f137cf49d | ||
|
|
34688852a4 | ||
|
|
de170ebdd2 | ||
|
|
e5ae1db49c | ||
|
|
151f28081a | ||
|
|
63035196af | ||
|
|
213a64b1ff | ||
|
|
e08d803a33 | ||
|
|
df1a939798 | ||
|
|
f259d81249 | ||
|
|
848f0db3d1 | ||
|
|
9e2d47eab5 | ||
|
|
589761bfd9 | ||
|
|
88fa103acb | ||
|
|
9849bc055c | ||
|
|
1cf75a7169 | ||
|
|
e297dff0d4 | ||
|
|
aafd7ed21f | ||
|
|
ab2c31aa8a | ||
|
|
18fde86a20 | ||
|
|
47111819e7 | ||
|
|
ddd3f7c196 | ||
|
|
1738f92ce2 | ||
|
|
074695b50c | ||
|
|
ba28bc94d3 | ||
|
|
da19a07943 | ||
|
|
95ac136720 | ||
|
|
ecced27853 | ||
|
|
e86aa6b541 | ||
|
|
91f74b44a0 | ||
|
|
35d8e28b8c | ||
|
|
26a6af4ab2 | ||
|
|
20785926e2 | ||
|
|
ecc500fc91 | ||
|
|
c22ac1e60a | ||
|
|
55d9aa2a4c | ||
|
|
1d391e68e5 | ||
|
|
0429c44d18 | ||
|
|
2c1bcaafc1 | ||
|
|
35891c74cd | ||
|
|
2ca6e67b37 | ||
|
|
66d0ee8156 | ||
|
|
6e72be54cb | ||
|
|
6138b060d7 | ||
|
|
308d661d7e | ||
|
|
4e106c2355 | ||
|
|
456160fa29 | ||
|
|
07edb998e4 | ||
|
|
b553ac58d3 | ||
|
|
2c26f43035 | ||
|
|
3e52f804a7 | ||
|
|
1b49844012 | ||
|
|
75b7583832 | ||
|
|
75d45e8907 | ||
|
|
d754eb74f7 | ||
|
|
b78bd5d6fd | ||
|
|
5d53344b75 | ||
|
|
7cd58bd534 | ||
|
|
9826bf67c2 | ||
|
|
350fe124d0 | ||
|
|
20aac83e5e | ||
|
|
9d1c822ba1 | ||
|
|
b8d46e2863 | ||
|
|
cd2f2d42a3 | ||
|
|
60252267d5 | ||
|
|
4bfab89292 | ||
|
|
1d3e8aedcd | ||
|
|
b25af641e2 | ||
|
|
75c41644c6 | ||
|
|
3e221f3b6a | ||
|
|
e7c3f8bf47 | ||
|
|
4c1dca73c4 | ||
|
|
0bbb6b91fe | ||
|
|
ee93d9b495 | ||
|
|
535abdc481 | ||
|
|
3684126250 | ||
|
|
bf8ac214a1 | ||
|
|
d3fc34c824 | ||
|
|
8769b5d1b5 | ||
|
|
59bb132dd7 | ||
|
|
8a53fa0aab | ||
|
|
71f42e405d | ||
|
|
64b89dd226 | ||
|
|
27d6b855b8 | ||
|
|
9c7b34d5e6 | ||
|
|
20c4f0dc10 | ||
|
|
7c166d85e1 | ||
|
|
093080894b | ||
|
|
76c0fa2fe2 | ||
|
|
ac3a17b178 | ||
|
|
9a2243da9f | ||
|
|
0f5aa9f8d9 | ||
|
|
673f7a82d1 | ||
|
|
c76b527b93 | ||
|
|
ded4f95537 | ||
|
|
87251878a5 | ||
|
|
3a14f363d9 | ||
|
|
84921f04cd | ||
|
|
8272386733 | ||
|
|
33988ed3fb | ||
|
|
b16475b8bd | ||
|
|
411b8e3cb6 | ||
|
|
848e26eec6 | ||
|
|
916da16523 | ||
|
|
d165c081f7 | ||
|
|
62e86f9507 | ||
|
|
992de7d66e | ||
|
|
46ab7bbcbe | ||
|
|
b04bced37f | ||
|
|
5b306f365e | ||
|
|
ce8950da43 | ||
|
|
0e1c7cd8ed | ||
|
|
fba6dd750d | ||
|
|
e73b6bc39e | ||
|
|
fa3cbbee67 | ||
|
|
029e52eb5f | ||
|
|
13914507e8 | ||
|
|
533f0213e3 | ||
|
|
13335cadc6 | ||
|
|
95d6dac055 | ||
|
|
2001d7f02a | ||
|
|
bae5b70023 | ||
|
|
8341d343d3 | ||
|
|
278a56e580 | ||
|
|
6ab44ccf0c | ||
|
|
b864791fa6 | ||
|
|
918898d6fe | ||
|
|
566e5dea57 | ||
|
|
5d1bfa18b1 | ||
|
|
800540ce7f | ||
|
|
74ee74365e | ||
|
|
75f6235111 | ||
|
|
fe415cbd77 | ||
|
|
dc69c0d3e5 | ||
|
|
40b3f39249 | ||
|
|
a9acc55735 | ||
|
|
9c07612274 | ||
|
|
3e87d88825 | ||
|
|
e280c0c5ca | ||
|
|
6614b56298 | ||
|
|
02c3894fc9 | ||
|
|
68f7dc9512 | ||
|
|
64f750a097 | ||
|
|
48bc18017e | ||
|
|
18d1bc56fd | ||
|
|
035fa3be3f | ||
|
|
f62723c274 | ||
|
|
aca59019c1 | ||
|
|
2186ea9a90 | ||
|
|
928f6e7009 | ||
|
|
1e4d07a52c | ||
|
|
64ed5fca3b | ||
|
|
4c7fc79843 | ||
|
|
153d77359f | ||
|
|
c8a2fb92d2 | ||
|
|
dcc252b371 | ||
|
|
846aadd7c6 | ||
|
|
3c604db234 | ||
|
|
cb3efb1c1d | ||
|
|
1423db35eb | ||
|
|
1fc579e907 | ||
|
|
827c4e31ee | ||
|
|
c2a1ed926e | ||
|
|
4f86c117c3 | ||
|
|
93817ba92f | ||
|
|
18153e0fcc | ||
|
|
3123f6444f | ||
|
|
cb2a7a88fc | ||
|
|
e530111283 | ||
|
|
4e97a3b3d5 | ||
|
|
332c4a1f98 | ||
|
|
8541b95d8b | ||
|
|
e4584e3f04 | ||
|
|
134c43ad9e | ||
|
|
e74b4b35b9 | ||
|
|
16e7194dfe | ||
|
|
168ec9092a | ||
|
|
914b6c757d | ||
|
|
48d10d701e | ||
|
|
6479e94c4f | ||
|
|
fb3a9f1f29 | ||
|
|
e9d7df8862 | ||
|
|
123de56f38 | ||
|
|
8627132d6a | ||
|
|
3ef9c4c626 | ||
|
|
aec03294d6 | ||
|
|
2e6e1f4060 | ||
|
|
07f1103784 | ||
|
|
ffc8f133c9 | ||
|
|
507f2a4c7c | ||
|
|
1c9e9b9367 | ||
|
|
4d81775f8d | ||
|
|
cf042931b6 | ||
|
|
f6a931599a | ||
|
|
1b17049e94 | ||
|
|
81c039d645 | ||
|
|
932b0ccf24 | ||
|
|
e245edc843 | ||
|
|
8494ed8ac3 | ||
|
|
371f14d2e4 | ||
|
|
3e5c7f62d0 | ||
|
|
1109fbfcc3 | ||
|
|
ff88f242fa | ||
|
|
bd3dd69ae1 | ||
|
|
06780c2805 | ||
|
|
e44e227af6 | ||
|
|
4ca06a9218 | ||
|
|
9e29761581 | ||
|
|
110c389d85 | ||
|
|
d856ed89ff | ||
|
|
fa747515e9 | ||
|
|
b15c9d7655 | ||
|
|
15c3ee4af2 | ||
|
|
748248deab | ||
|
|
70671ac672 | ||
|
|
f70f670ed3 | ||
|
|
4b685716d5 | ||
|
|
252c812125 | ||
|
|
69a437a1a8 | ||
|
|
b8b36b6248 | ||
|
|
28e24cb9d6 | ||
|
|
2a0609fdb8 | ||
|
|
b3233cab71 | ||
|
|
bf19f5b9c0 | ||
|
|
08a879bbb1 | ||
|
|
405a3eda60 | ||
|
|
49acfc496b | ||
|
|
a1932fa3dc | ||
|
|
87a8706299 | ||
|
|
92ec46147b | ||
|
|
cd514285d9 | ||
|
|
2bda7566b4 | ||
|
|
43488cb57b | ||
|
|
137fbb638b | ||
|
|
782bb11894 | ||
|
|
76ed8d58fa | ||
|
|
8204139df8 | ||
|
|
7926684930 | ||
|
|
73946a4ede | ||
|
|
aa88115d45 | ||
|
|
496c08b075 | ||
|
|
2388d1782f | ||
|
|
e0e1c59d41 | ||
|
|
f2cb6ce972 | ||
|
|
ed3535e9c9 | ||
|
|
62f1830197 | ||
|
|
2fb62fe8be | ||
|
|
355689ed19 | ||
|
|
75614fb13c | ||
|
|
5c4a864680 | ||
|
|
eaeff891d6 | ||
|
|
f0ab40d748 | ||
|
|
3243cbf039 | ||
|
|
eb171ecb21 | ||
|
|
e497af4c26 | ||
|
|
43b8941f7a | ||
|
|
0b16839d7f | ||
|
|
164ba46259 | ||
|
|
b174f7a023 | ||
|
|
c9ec9f14de | ||
|
|
597c071c3d | ||
|
|
f860f57363 | ||
|
|
91d05434ca | ||
|
|
5b0aba99bb | ||
|
|
87c7d1a5f4 | ||
|
|
d841d69bd4 | ||
|
|
512bf1d013 | ||
|
|
02bf5ada89 | ||
|
|
adbd58a949 | ||
|
|
a0959d2730 | ||
|
|
f455722bed | ||
|
|
735d23c9eb | ||
|
|
0fd6a23c78 | ||
|
|
fd73d8d67e | ||
|
|
347366e8d7 | ||
|
|
eb8d4abcbe | ||
|
|
86acccebb0 | ||
|
|
8f184f76fa | ||
|
|
1daabfa3e0 | ||
|
|
90b49106f0 | ||
|
|
1a5638426c | ||
|
|
8d4da009af | ||
|
|
89571d57bd | ||
|
|
d3b578fe8f | ||
|
|
d29d910ac6 | ||
|
|
5d4e06074a | ||
|
|
98522cf6e4 | ||
|
|
7cdb751606 | ||
|
|
4ffc90f963 | ||
|
|
8da6572074 | ||
|
|
ee64aad670 | ||
|
|
92cee2321f | ||
|
|
7f969b1252 | ||
|
|
a02e2e1fa1 | ||
|
|
d690e1b37a | ||
|
|
3300c2302c | ||
|
|
685470cf23 | ||
|
|
c545a959ac | ||
|
|
a7832ef40f | ||
|
|
3e941999d5 | ||
|
|
bebdfc259c | ||
|
|
d31a920eb7 | ||
|
|
ec87821bcd | ||
|
|
21df0e32c4 | ||
|
|
afaa235c75 | ||
|
|
8d97e7136f | ||
|
|
89ac422929 | ||
|
|
d8d55f032e | ||
|
|
c83d694c7a | ||
|
|
ea55650d45 | ||
|
|
ec1aee60a1 | ||
|
|
3a7a0918d3 | ||
|
|
8bf90714da | ||
|
|
d8b59925b0 | ||
|
|
d37fd6bea0 | ||
|
|
0f6263d82e | ||
|
|
e7c70945e6 | ||
|
|
095a936891 | ||
|
|
c49ce91fac | ||
|
|
dd52727055 | ||
|
|
b48068c63c | ||
|
|
c39d04e8a5 | ||
|
|
0eff8e4bc8 | ||
|
|
178551a467 | ||
|
|
720739e50a | ||
|
|
46d1537d8f | ||
|
|
63b2bb55a1 | ||
|
|
e7b41f9a4c | ||
|
|
dd0aed4614 | ||
|
|
b9b4f2bb7f | ||
|
|
3533d2a2cc | ||
|
|
26d9ef5398 | ||
|
|
06c210f5c8 | ||
|
|
a545c42047 | ||
|
|
da4b4de292 | ||
|
|
fd936e5bf3 | ||
|
|
a0f840bcf8 | ||
|
|
33d2a77e37 | ||
|
|
dc11340faf | ||
|
|
06d921d855 | ||
|
|
91b602341b | ||
|
|
ad853ca342 | ||
|
|
14fa3481b0 | ||
|
|
2b6fee0455 | ||
|
|
a48e6f82d1 | ||
|
|
1020904fe0 | ||
|
|
6aaced0c04 | ||
|
|
3646c0d0a3 | ||
|
|
44c8574f1b | ||
|
|
ea1ff65db7 | ||
|
|
85b7147927 | ||
|
|
6b54c342aa | ||
|
|
60720b04db | ||
|
|
323a593159 | ||
|
|
baef94f14a | ||
|
|
59b3cfee66 | ||
|
|
cbc85ca98f | ||
|
|
425c8cd1d3 | ||
|
|
1d7949ded6 | ||
|
|
2507170816 | ||
|
|
2c83425b42 | ||
|
|
80e00a80d5 | ||
|
|
1da281de8a | ||
|
|
98baab4d03 | ||
|
|
a3d5479878 | ||
|
|
a49dc04f5d | ||
|
|
d1c0c9739d | ||
|
|
7415b07586 | ||
|
|
441069aa76 | ||
|
|
8c5bf55b51 | ||
|
|
b6d6955b39 | ||
|
|
0d68b1a73e | ||
|
|
15b7c241ff | ||
|
|
de9c62617b | ||
|
|
a0e05115a3 | ||
|
|
023663b268 | ||
|
|
aaf58272f1 | ||
|
|
5ebaf5663d | ||
|
|
7dc3e6a08b | ||
|
|
5a5f817e59 | ||
|
|
b650320a34 | ||
|
|
424fd8e4d3 | ||
|
|
cfbf80fdfe | ||
|
|
9b8ced2803 | ||
|
|
630a1d42b8 | ||
|
|
b69ff6ca8a | ||
|
|
1a23b6178b | ||
|
|
de536d7305 | ||
|
|
6dcd33bbc5 | ||
|
|
c6df78eb81 | ||
|
|
d1babe27ec | ||
|
|
7596f62ca5 | ||
|
|
139e57f1eb | ||
|
|
e87d85b088 | ||
|
|
91b79b703c | ||
|
|
bdefa4a967 | ||
|
|
3883c509b9 | ||
|
|
b82efb6e3c | ||
|
|
a50e109043 | ||
|
|
8b5db12e1d | ||
|
|
f1f8163bb7 | ||
|
|
c0fac90b52 | ||
|
|
15717ddca0 | ||
|
|
a7ce9aaca5 | ||
|
|
d8df8e1033 | ||
|
|
440a35e491 | ||
|
|
dbbc6ed0bb | ||
|
|
86fbb383fd | ||
|
|
18f34b4f83 | ||
|
|
1c07a74bef | ||
|
|
2df93c2ceb | ||
|
|
6ca40afac0 | ||
|
|
36a8f044ae | ||
|
|
caed86d846 | ||
|
|
276e5453f1 | ||
|
|
459e36c027 | ||
|
|
0f81986684 | ||
|
|
bc54e536af | ||
|
|
acb57b3e9c | ||
|
|
725f8571bb | ||
|
|
b7c7c0e862 | ||
|
|
de0e30de57 | ||
|
|
3f671b918a | ||
|
|
b8b942cdae | ||
|
|
9492363b22 | ||
|
|
3ee144459f | ||
|
|
c0c80c0fdf | ||
|
|
0146a077e8 | ||
|
|
7c80b61666 | ||
|
|
a0fcf515cd | ||
|
|
1719ad81a4 | ||
|
|
51a9a7b75d | ||
|
|
d128f3e14e | ||
|
|
4498b89ac4 | ||
|
|
e576a58ead | ||
|
|
eb4375258e | ||
|
|
0cbc2001e2 | ||
|
|
6bf5dbabee | ||
|
|
6a89646e66 | ||
|
|
e91b0500c5 | ||
|
|
2a17361a90 | ||
|
|
1eca3a8603 | ||
|
|
86f37863a7 | ||
|
|
f3234a6b5e | ||
|
|
73a8c302e9 | ||
|
|
989f2d3001 | ||
|
|
2badcfa546 | ||
|
|
643cd87706 | ||
|
|
98c85441f8 | ||
|
|
1345f996da | ||
|
|
ff48f08241 | ||
|
|
b5f438aa0c | ||
|
|
384e14b32d | ||
|
|
a2266adb3f | ||
|
|
016e743653 | ||
|
|
00adf3631a | ||
|
|
09aef18999 | ||
|
|
1d86aac338 | ||
|
|
80173634a0 | ||
|
|
c9598b674c | ||
|
|
2a588d1e9a | ||
|
|
5a6c06c8a3 | ||
|
|
b2ef4e9619 | ||
|
|
9e9d6e45b4 | ||
|
|
6752457ad8 | ||
|
|
ddcb5cd4d3 | ||
|
|
a54b2db81b | ||
|
|
6740124364 | ||
|
|
157731e4f8 | ||
|
|
2dd1496ef4 | ||
|
|
d1e4e72693 | ||
|
|
77e8143290 | ||
|
|
7f791d4919 | ||
|
|
d7e0468776 | ||
|
|
f6c611bbba | ||
|
|
0990ac4fc1 | ||
|
|
e91f8f693b | ||
|
|
2a7dbda133 | ||
|
|
793e542312 | ||
|
|
240269eb25 | ||
|
|
c744dc8cc3 | ||
|
|
d596bdb454 | ||
|
|
bec54b4283 | ||
|
|
061b88f5b5 | ||
|
|
8704eff632 | ||
|
|
fb16f25b07 | ||
|
|
e8057a5c8a | ||
|
|
3c5edb6171 | ||
|
|
e36a191240 | ||
|
|
ecdfd65f50 | ||
|
|
4294081abb | ||
|
|
5218543c58 | ||
|
|
d8332a27e5 | ||
|
|
673658dfd2 | ||
|
|
6528d3d7da | ||
|
|
16af479b83 | ||
|
|
13187de97d | ||
|
|
32850f6770 | ||
|
|
4a7f4bde4a | ||
|
|
c518f373df | ||
|
|
0010119440 | ||
|
|
f4636fdca2 | ||
|
|
91065a6168 | ||
|
|
efa8d5c575 | ||
|
|
4108d7827a | ||
|
|
04998d0215 | ||
|
|
d0efa5d3fe | ||
|
|
c87e72e08e | ||
|
|
efb82847cb | ||
|
|
f37e267a5e | ||
|
|
69928219a3 | ||
|
|
5ccd40f530 | ||
|
|
8798340d48 | ||
|
|
e8d2959350 | ||
|
|
fdf8845a2f | ||
|
|
4073a7abc3 | ||
|
|
ffd9a34cf5 | ||
|
|
07226c6d21 | ||
|
|
b1bc7c1fc2 | ||
|
|
1b33f0cea9 | ||
|
|
8ece3b00f5 | ||
|
|
c9c58b65a6 | ||
|
|
66becbc4cc | ||
|
|
5b8612c919 | ||
|
|
430c22e06e | ||
|
|
76b62eda3a | ||
|
|
bc983162f3 | ||
|
|
4922598aee | ||
|
|
b2f8bb9990 | ||
|
|
9ee92fb9e9 | ||
|
|
f1d838de6b | ||
|
|
ec92a4cd34 | ||
|
|
b3b9788d37 | ||
|
|
67739e8e39 | ||
|
|
be3ed7d380 | ||
|
|
9b4d58cfe8 | ||
|
|
fb6a8d999c | ||
|
|
b2f6a06a1f | ||
|
|
f7da32702f | ||
|
|
219d2246fa | ||
|
|
979b5eb89c | ||
|
|
a58811b1bf | ||
|
|
be0e18d4b0 | ||
|
|
981bf1d56f | ||
|
|
fea6f0ce81 | ||
|
|
5859ac7a58 | ||
|
|
d2c2503cfa | ||
|
|
566833da6e | ||
|
|
d174602cc0 | ||
|
|
2a4caa856e | ||
|
|
46bc04f69f | ||
|
|
157962e42a | ||
|
|
16db28060c | ||
|
|
bb8fd5500d | ||
|
|
d0df105dda | ||
|
|
a061fb5421 | ||
|
|
fd17e5a4c0 | ||
|
|
cd8bc7a7a1 | ||
|
|
e22a586a41 | ||
|
|
5017c5a5f1 | ||
|
|
03cbab5267 | ||
|
|
2c22837d9f | ||
|
|
4d64df37f5 | ||
|
|
b224f1d78d | ||
|
|
52e018989d | ||
|
|
eb14193b23 | ||
|
|
001c2c88cd | ||
|
|
98ab83976e | ||
|
|
9cd5bf2992 | ||
|
|
e876712af5 | ||
|
|
9fc8d66601 | ||
|
|
12d86493bf | ||
|
|
c97cba69b9 | ||
|
|
63ed7a734b | ||
|
|
0e338ef453 | ||
|
|
d914b38f9f | ||
|
|
3ee00a4824 | ||
|
|
5198c69f6b | ||
|
|
40704c4549 | ||
|
|
83df59e5f1 | ||
|
|
246602e275 | ||
|
|
d3449609da | ||
|
|
a872058704 | ||
|
|
3033376028 | ||
|
|
712424c339 | ||
|
|
0bda636113 | ||
|
|
28092d6862 | ||
|
|
cecafb726c | ||
|
|
8418c21096 | ||
|
|
c4ace1972a | ||
|
|
862df1d2df | ||
|
|
487c1a58d6 | ||
|
|
c06c3d48d2 | ||
|
|
7d3ad5a639 | ||
|
|
03b2d02742 | ||
|
|
103ce44ba9 | ||
|
|
22219af133 | ||
|
|
7d7377ab15 | ||
|
|
af8fc53704 | ||
|
|
e80a5d82a4 | ||
|
|
2b73e745da | ||
|
|
e61a1080f7 | ||
|
|
464f336790 | ||
|
|
1dc6e085cc | ||
|
|
8594ff0c23 | ||
|
|
e58963410e | ||
|
|
1e0d118930 | ||
|
|
723e6dd13f | ||
|
|
e941af0905 | ||
|
|
24c8e29691 | ||
|
|
8911bdf966 | ||
|
|
0834759e1a | ||
|
|
15c56dfcb8 | ||
|
|
b98ad47618 | ||
|
|
4778c5f5e8 | ||
|
|
d041671dc5 | ||
|
|
bb8c0d264e | ||
|
|
c7da8c5fd3 | ||
|
|
5cab65d197 | ||
|
|
30789ff6e2 | ||
|
|
e6ece10716 | ||
|
|
ea7a255006 | ||
|
|
98df1f5312 | ||
|
|
b5bf627fb1 | ||
|
|
6104150b77 | ||
|
|
a13bae2f39 | ||
|
|
fd80e98207 | ||
|
|
f43b95f001 | ||
|
|
38802d3522 | ||
|
|
9f7813622d | ||
|
|
75d67207aa | ||
|
|
e596a8f731 | ||
|
|
5b0cc73792 | ||
|
|
2163d4465f | ||
|
|
8becf45714 | ||
|
|
2bf08787d8 | ||
|
|
853ead26ca | ||
|
|
0ccb6cb873 | ||
|
|
b8f7e4211c | ||
|
|
e46ff3de8b | ||
|
|
b581d0c44f | ||
|
|
0b613812f7 | ||
|
|
a02e08a879 | ||
|
|
4d066a762f | ||
|
|
109d7d87bd | ||
|
|
3df740702c | ||
|
|
8a30a65818 | ||
|
|
01703aff43 | ||
|
|
06bb6f7bff | ||
|
|
9d62931af9 | ||
|
|
e33738a876 | ||
|
|
f887f5dca3 | ||
|
|
257c16690a | ||
|
|
7114e88992 | ||
|
|
de7e869ca9 | ||
|
|
eaee9c9522 | ||
|
|
bee11a6d41 | ||
|
|
647e44147f | ||
|
|
4a5d46915d | ||
|
|
8ad19585cb | ||
|
|
951a33fae9 | ||
|
|
bcf174cd1e | ||
|
|
1e82909f58 | ||
|
|
33e83b8414 | ||
|
|
592c56cb20 | ||
|
|
710528c01a | ||
|
|
03cadc2604 | ||
|
|
dd73bb95a4 | ||
|
|
40e0a55378 | ||
|
|
269884d9f3 | ||
|
|
fcd548c313 | ||
|
|
140a8b6804 | ||
|
|
b5378c1296 | ||
|
|
e53d8fd4fa | ||
|
|
0dbde32ed4 | ||
|
|
1445d6ea8c | ||
|
|
5385431051 | ||
|
|
f14f4498fb | ||
|
|
d506fdb68c | ||
|
|
9c10186158 | ||
|
|
3eed51dbac | ||
|
|
1c1855f0c3 | ||
|
|
e0a277fa45 | ||
|
|
3d6c7171d2 | ||
|
|
fc2786f5e8 | ||
|
|
174dbb5e74 | ||
|
|
0fee90e4df | ||
|
|
0cced44491 | ||
|
|
f21f758591 | ||
|
|
68517c15f2 | ||
|
|
11ee142e4b | ||
|
|
51e9527d53 | ||
|
|
1e1d047e07 | ||
|
|
62f1e39e6e | ||
|
|
05756da495 | ||
|
|
fa35b2a66f | ||
|
|
268cd131dc | ||
|
|
26997ad5c3 | ||
|
|
ce1786f128 | ||
|
|
d2094e2b68 | ||
|
|
075b2df738 | ||
|
|
ec3c31a106 | ||
|
|
888057f64a | ||
|
|
3c6c4d9601 | ||
|
|
5e8bcf8faf | ||
|
|
0d6f2f93bf | ||
|
|
937b00cfcc | ||
|
|
0d4432720c | ||
|
|
0ec49643ee | ||
|
|
0d80ea4f4c | ||
|
|
d2b26124e4 | ||
|
|
343116ea24 | ||
|
|
10dc699b21 | ||
|
|
e2183c2214 | ||
|
|
4994064e6e | ||
|
|
015c5f07bc | ||
|
|
a40b9f4054 | ||
|
|
a0b6a3bed6 | ||
|
|
ee8d65977d | ||
|
|
b4ea11e55e | ||
|
|
b8d2ef1eb5 | ||
|
|
0efeffeaa3 | ||
|
|
9de5950f4d | ||
|
|
26488b793a | ||
|
|
7a86d272bb | ||
|
|
5a6c2dfcd5 | ||
|
|
4d780904d1 | ||
|
|
0a6fa65075 | ||
|
|
6440220640 | ||
|
|
4350c9a72b | ||
|
|
77feae0ab9 | ||
|
|
1261696ba2 | ||
|
|
6b35a0a527 | ||
|
|
fd33ff81c9 | ||
|
|
7e891ecb79 | ||
|
|
178b1e8bb0 | ||
|
|
12840f2428 | ||
|
|
9d50f03cb1 | ||
|
|
8c1688657a | ||
|
|
833cb99f41 | ||
|
|
bd5d84abcd | ||
|
|
d451ba9b6e | ||
|
|
14bd02a569 | ||
|
|
4beace1bb0 | ||
|
|
6996dfcd3b | ||
|
|
42c46d7d5c | ||
|
|
9b31ce83c5 | ||
|
|
cb5250527b | ||
|
|
0b160a6741 | ||
|
|
dff34a8ae2 | ||
|
|
8f780ad89e | ||
|
|
4624ef393d | ||
|
|
2ce8a890e2 | ||
|
|
90e0e9000e | ||
|
|
a6bb1c156d | ||
|
|
31db8161b5 | ||
|
|
c0d1448080 | ||
|
|
4e4f4e60b6 | ||
|
|
dcc83271af | ||
|
|
a38458c9be | ||
|
|
7934f65ae8 | ||
|
|
f0b73fd696 | ||
|
|
aea0cec061 | ||
|
|
7ac56b1a0c | ||
|
|
f5ed0b700f | ||
|
|
1ff3b83766 | ||
|
|
40eca1727e | ||
|
|
9505e68ef7 | ||
|
|
5847806a16 | ||
|
|
e427ea44aa | ||
|
|
8df8bf33a4 | ||
|
|
29d2b942e8 | ||
|
|
df5684a9f8 | ||
|
|
992cdb992a | ||
|
|
db0dc71319 | ||
|
|
2c871d1339 | ||
|
|
9673922ca1 | ||
|
|
d311870b61 | ||
|
|
8dd1ff593a | ||
|
|
0f64a769c2 | ||
|
|
a8d150db5c | ||
|
|
d7e6367ff3 | ||
|
|
7b84d8c3d5 | ||
|
|
b3f724c799 | ||
|
|
a7be6504a2 | ||
|
|
e025df0824 | ||
|
|
c3392d5386 | ||
|
|
1da5357df6 | ||
|
|
2c09e6a7c0 | ||
|
|
2a0740e135 | ||
|
|
ac65357c8a | ||
|
|
92e1847c59 | ||
|
|
0500994def | ||
|
|
07c255f7f8 | ||
|
|
da911bfeb8 | ||
|
|
578d673a4e | ||
|
|
198b3c9f1b | ||
|
|
f5c567eb90 | ||
|
|
8ca09f6384 | ||
|
|
c8e58a1e5b | ||
|
|
386dfe42d0 | ||
|
|
7445f43b1b | ||
|
|
d477874535 | ||
|
|
5b77e78662 | ||
|
|
4b0b8d4de2 | ||
|
|
da79386cc3 | ||
|
|
b7de47b6fb | ||
|
|
3434907f52 | ||
|
|
099adb3853 | ||
|
|
dd9b1c047c | ||
|
|
a4ba6d1444 | ||
|
|
6084bb15cf | ||
|
|
42b568952e | ||
|
|
ef28459b61 | ||
|
|
d3bac307bb | ||
|
|
7e488b0fa3 | ||
|
|
7d7a6191ce | ||
|
|
5c644b31ca | ||
|
|
7b4398dfee | ||
|
|
663418e943 | ||
|
|
969bec248a | ||
|
|
8f487d7d4e | ||
|
|
89ebce79b2 | ||
|
|
1ff8c908b8 | ||
|
|
34ce510fbd | ||
|
|
e966ef96e5 | ||
|
|
b05b38b269 | ||
|
|
39f29399e7 | ||
|
|
8e1f1ff2e6 | ||
|
|
680d6c20ca | ||
|
|
c886e7949e | ||
|
|
8cd4cc7d0d | ||
|
|
e0b972f6d6 | ||
|
|
25daa9f2da | ||
|
|
d0fb5c3bd5 | ||
|
|
608ab8f4ad | ||
|
|
520b12e56b | ||
|
|
e95643f198 | ||
|
|
3b1712345b | ||
|
|
5c8ffe961e | ||
|
|
7983e82b60 | ||
|
|
6effe47bcc | ||
|
|
77d35b61a9 | ||
|
|
285a97aaf8 | ||
|
|
205080a210 | ||
|
|
ad29f2477e | ||
|
|
bc998988c2 | ||
|
|
1072d1306b | ||
|
|
80b470cfd3 | ||
|
|
b8eda40937 | ||
|
|
3df2b4b7f8 | ||
|
|
6141b60294 | ||
|
|
e1cfb0cab6 | ||
|
|
9b9782ce94 | ||
|
|
5d9eb25e38 | ||
|
|
f4a518ce6b | ||
|
|
2719ae5df2 | ||
|
|
3656e6ef54 | ||
|
|
a545d7d8b1 | ||
|
|
68ee2bdcdc | ||
|
|
da654fdff5 | ||
|
|
3127f7a31b | ||
|
|
f561de200d | ||
|
|
d7f9d5a66f | ||
|
|
d85a063db8 | ||
|
|
d6bf935ceb | ||
|
|
0d6ff822e7 | ||
|
|
1c0cc8e91c | ||
|
|
c4fb7b7928 | ||
|
|
43a791db65 | ||
|
|
217311211a | ||
|
|
ca55890ad2 | ||
|
|
d6ecf5b8a9 | ||
|
|
e52edde11f | ||
|
|
2e514735ec | ||
|
|
3d32c30d2d | ||
|
|
05235f8385 | ||
|
|
cd28a75c86 | ||
|
|
34075738ea | ||
|
|
fb38573b7e | ||
|
|
8a2f45ec23 | ||
|
|
fee2eb9251 | ||
|
|
24035c4ae8 | ||
|
|
aa8215df34 | ||
|
|
eb78e3d640 | ||
|
|
f8201cd2bc | ||
|
|
f37b3ecd26 | ||
|
|
88c0b8a8f0 | ||
|
|
e6dba59ae6 | ||
|
|
a7bc6b4f36 | ||
|
|
cacc5ac803 | ||
|
|
46dc0f144b | ||
|
|
3cc5275592 | ||
|
|
a3955a1ba8 | ||
|
|
89dfaf1d5d | ||
|
|
e8bbc117e1 | ||
|
|
fc6246c5cb | ||
|
|
ce8a0cab2a | ||
|
|
b99f45874f | ||
|
|
b36b6c78a2 | ||
|
|
5232dc6485 | ||
|
|
b1d9fc6c9a | ||
|
|
0dfa378e38 | ||
|
|
80ded84f7a | ||
|
|
8394535725 | ||
|
|
adf780d25b | ||
|
|
749ae3deb3 | ||
|
|
3da0c07bcd | ||
|
|
2196b53075 | ||
|
|
a8340f37bb | ||
|
|
7b1710ee63 | ||
|
|
38b7d9724e | ||
|
|
2b1ed49e9a | ||
|
|
017cf9e464 | ||
|
|
781f0c843e | ||
|
|
e2bf474332 | ||
|
|
7e2f1c9a8b | ||
|
|
8e798dde48 | ||
|
|
c05ae6e94c | ||
|
|
ff28ea8fa8 | ||
|
|
7914e89212 | ||
|
|
558ff90e27 | ||
|
|
ee69653a83 | ||
|
|
2d7760e67c | ||
|
|
95339a8338 | ||
|
|
39b1435725 | ||
|
|
b1d3e258bd | ||
|
|
c915926e0f | ||
|
|
25203934e6 | ||
|
|
6ff7fa74e2 | ||
|
|
91305262f1 | ||
|
|
6d16b68f11 | ||
|
|
f22e4f1cc7 | ||
|
|
4b1b2878ea | ||
|
|
2851d12357 | ||
|
|
73968e4277 | ||
|
|
7a6ecd86c6 | ||
|
|
b11d5514b9 | ||
|
|
1ff2a08d19 | ||
|
|
d1efd62e7b | ||
|
|
366c95cd3c | ||
|
|
7e03f3958e | ||
|
|
e069184721 | ||
|
|
5182441cb3 | ||
|
|
0de55a8ff5 | ||
|
|
0900d7c764 | ||
|
|
8540e09ba7 | ||
|
|
6e301601f9 | ||
|
|
1bf0eab2d9 | ||
|
|
d560f656f4 | ||
|
|
0bc256aa23 | ||
|
|
ebc073a52e | ||
|
|
23503dc439 | ||
|
|
1f4985c7dd | ||
|
|
ed88d9e10d | ||
|
|
906196bac3 | ||
|
|
cb9751be04 | ||
|
|
09e03d579b | ||
|
|
9fcca2698e | ||
|
|
bba8cd9b58 | ||
|
|
c8bb30289a | ||
|
|
69f56c1eb7 | ||
|
|
adc8e23356 | ||
|
|
88005c6603 | ||
|
|
33ee4c36b4 | ||
|
|
1a142b7fe6 | ||
|
|
90373806c0 | ||
|
|
a47634bf49 | ||
|
|
e03e58323b | ||
|
|
ab1e31c0e7 | ||
|
|
aa5505d693 | ||
|
|
74f8f687cf | ||
|
|
d54500bad5 | ||
|
|
4966b4d58d | ||
|
|
b75a4667c2 | ||
|
|
14579a9320 | ||
|
|
1d92eff974 | ||
|
|
91274267e5 | ||
|
|
c49f0ede16 | ||
|
|
42a0f452b1 | ||
|
|
c24ab9831a | ||
|
|
506a68ee6a | ||
|
|
1291f792ab | ||
|
|
51cfb1903d | ||
|
|
1b1c15694a | ||
|
|
251f1941a9 | ||
|
|
625617bb20 | ||
|
|
f80f161886 | ||
|
|
4b4889d5f2 | ||
|
|
fee34ba257 | ||
|
|
c29ab25dd2 | ||
|
|
e0308a11c9 | ||
|
|
a738998c2c | ||
|
|
6be22c474d | ||
|
|
da19743ba5 |
@ -1,3 +1,9 @@
|
||||
# Windows has stack overflows when calling from Tauri, so we increase compiler size
|
||||
# Windows has stack overflows when calling from Tauri, so we increase the default stack size used by the compiler
|
||||
[target.'cfg(windows)']
|
||||
rustflags = ["-C", "link-args=/STACK:16777220"]
|
||||
rustflags = ["-C", "link-args=/STACK:16777220", "--cfg", "tokio_unstable"]
|
||||
|
||||
[target.x86_64-pc-windows-msvc]
|
||||
linker = "rust-lld"
|
||||
|
||||
[build]
|
||||
rustflags = ["--cfg", "tokio_unstable"]
|
||||
|
||||
1
.dockerignore
Symbolic link
@ -0,0 +1 @@
|
||||
.gitignore
|
||||
@ -1,13 +1,18 @@
|
||||
# Editor configuration, see http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
max_line_length = 100
|
||||
|
||||
[*.md]
|
||||
max_line_length = off
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.{rs,java,kts}]
|
||||
indent_size = 4
|
||||
35
.gitattributes
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
* text=auto eol=lf
|
||||
|
||||
# SQLx calculates a checksum of migration scripts at build time to compare
|
||||
# it with the checksum of the applied migration for the same version at
|
||||
# runtime, to know if the migration script has been changed, and thus the
|
||||
# DB schema went out of sync with the code.
|
||||
#
|
||||
# However, such checksum treats the script as a raw byte stream, taking
|
||||
# into account inconsequential differences like different line endings
|
||||
# in different OSes. When combined with Git's EOL conversion and mixed
|
||||
# native and cross-compilation scenarios, this leads to existing
|
||||
# migrations that didn't change having potentially different checksums
|
||||
# according to the environment they were built in, which can break the
|
||||
# migration system when deploying the Modrinth App, rendering it
|
||||
# unusable.
|
||||
#
|
||||
# The gitattribute above ensures that all text files are checked out
|
||||
# with LF line endings, but widely deployed app versions were built
|
||||
# without this attribute set, which left such line endings variable to
|
||||
# the platform. Thus, there is no perfect solution to this problem:
|
||||
# forcing CRLF here would break Linux and macOS users, forcing LF
|
||||
# breaks Windows users, and leaving it unspecified may still lead to
|
||||
# line ending differences when cross-compiling from Linux to Windows
|
||||
# or vice versa, or having Git configured with different line
|
||||
# conversion settings. Moreover, there is no `eol=native` attribute,
|
||||
# and using CI-only scripts to convert line endings would make the
|
||||
# builds differ between CI and most local environments. So, let's pick
|
||||
# the least bad option: let Git handle line endings using its
|
||||
# configuration by leaving it unspecified, which works fine as long as
|
||||
# people don't mess with Git's line ending settings, which is the vast
|
||||
# majority of cases.
|
||||
/packages/app-lib/migrations/20240711194701_init.sql !eol
|
||||
/packages/app-lib/migrations/20240813205023_drop-active-unique.sql !eol
|
||||
/packages/app-lib/migrations/20240930001852_disable-personalized-ads.sql !eol
|
||||
/packages/app-lib/migrations/20241222013857_feature-flags.sql !eol
|
||||
59
.github/ISSUE_TEMPLATE/1-app-bug.yml
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
name: 🎮 Modrinth App bug
|
||||
description: Report an issue in the Modrinth Launcher.
|
||||
labels: [bug, app]
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Please confirm the following.
|
||||
options:
|
||||
- label: I checked the [existing issues](https://github.com/modrinth/code/issues?q=is%3Aissue) for duplicate problems
|
||||
required: true
|
||||
- label: I have tried resolving the issue using the [support portal](https://support.modrinth.com)
|
||||
required: true
|
||||
- label: I have ensured my Modrinth App installation is up to date
|
||||
required: true
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: What version of the Modrinth App are you using?
|
||||
description: Find this in ⚙️ Settings (bottom right) -> After Modrinth App (bottom left)
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: oses
|
||||
attributes:
|
||||
label: What operating systems are you seeing the problem on?
|
||||
multiple: true
|
||||
options:
|
||||
- Windows
|
||||
- MacOS
|
||||
- Linux
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: A clear and concise description of what the bug is. Include screenshots if applicable.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Steps to reproduce the behavior.
|
||||
placeholder: |
|
||||
1. Go to '...'
|
||||
2. Click on '...'
|
||||
3. Scroll down to '...'
|
||||
4. See error
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected behavior
|
||||
description: A clear and concise description of what you expected to happen.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any other context about the problem here.
|
||||
validations:
|
||||
required: false
|
||||
52
.github/ISSUE_TEMPLATE/2-web-bug.yml
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
name: 🌐 Website bug (modrinth.com)
|
||||
description: Report an issue on the Modrinth website.
|
||||
labels: [bug, web]
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Please confirm the following.
|
||||
options:
|
||||
- label: I checked the [existing issues](https://github.com/modrinth/code/issues?q=is%3Aissue) for duplicate problems
|
||||
required: true
|
||||
- label: I have tried resolving the issue using the [support portal](https://support.modrinth.com)
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: browsers
|
||||
attributes:
|
||||
label: What browsers are you seeing the problem on?
|
||||
multiple: true
|
||||
options:
|
||||
- Chrome (including Arc, Brave, Opera, Vivaldi)
|
||||
- Microsoft Edge
|
||||
- Firefox
|
||||
- Safari
|
||||
- Other (please specify)
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: A clear and concise description of what the bug is. Include screenshots if applicable.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Steps to reproduce the behavior.
|
||||
placeholder: |
|
||||
1. Go to '...'
|
||||
2. Click on '...'
|
||||
3. Scroll down to '...'
|
||||
4. See error
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected behavior
|
||||
description: A clear and concise description of what you expected to happen.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any other context about the problem here.
|
||||
validations:
|
||||
required: false
|
||||
@ -1,11 +1,19 @@
|
||||
name: Bug report
|
||||
description: Create a report to help us improve Modrinth
|
||||
labels: [bug]
|
||||
name: 🛠️ API issue (api.modrinth.com)
|
||||
description: Report an issue regarding the Modrinth API.
|
||||
labels: [bug, backend]
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Please confirm the following.
|
||||
options:
|
||||
- label: I checked the [existing issues](https://github.com/modrinth/code/issues?q=is%3Aissue) for duplicate problems
|
||||
required: true
|
||||
- label: I have tried resolving the issue using the [support portal](https://support.modrinth.com)
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: A clear and concise description of what the bug is.
|
||||
description: A clear and concise description of what the bug is. Include screenshots if applicable.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
@ -25,13 +33,9 @@ body:
|
||||
description: A clear and concise description of what you expected to happen.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: System information
|
||||
description: Add any information about what OS you are on (like Windows or Mac), and what version of the app you are using.
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any other context about the problem here. This might include logs, screenshots, etc. The more the merrier!
|
||||
description: Add any other context about the problem here.
|
||||
validations:
|
||||
required: false
|
||||
@ -1,10 +1,28 @@
|
||||
name: Enhancement
|
||||
description: Suggest an enhancement for an existing Modrinth feature
|
||||
name: 💡 Feature Request
|
||||
description: Suggest an idea
|
||||
labels: [enhancement]
|
||||
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Please confirm the following.
|
||||
options:
|
||||
- label: I checked the [existing issues](https://github.com/modrinth/code/issues?q=is%3Aissue) for duplicate feature requests
|
||||
required: true
|
||||
- label: I have checked that this feature request is not on our [roadmap](https://roadmap.modrinth.com)
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: projects
|
||||
attributes:
|
||||
label: What parts of Modrinth is your feature request related too?
|
||||
multiple: true
|
||||
options:
|
||||
- App
|
||||
- Website
|
||||
- API
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Is your suggested enhancement related to a problem? Please describe.
|
||||
label: Is your suggested feature related to a problem? Please describe.
|
||||
description: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
validations:
|
||||
required: false
|
||||
18
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -1,16 +1,14 @@
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: Discord
|
||||
about: Ask questions on our Discord Server.
|
||||
- name: 🫶 Support Portal
|
||||
about: Get support using through our portal.
|
||||
url: https://support.modrinth.com
|
||||
- name: 💬 Chat
|
||||
about: Join our Discord server to chat about Modrinth.
|
||||
url: https://discord.modrinth.com
|
||||
- name: Roadmap
|
||||
- name: 🛣️ Roadmap
|
||||
about: View our Roadmap. Please do not open issues for items on our roadmap.
|
||||
url: https://roadmap.modrinth.com
|
||||
- name: Discussions (Feature requests)
|
||||
about: |
|
||||
Please use Issues for reporting bugs and suggesting enhancements to existing features.
|
||||
Suggestions for new features should be made as a Discussion.
|
||||
url: https://github.com/orgs/modrinth/discussions/categories/feature-requests
|
||||
- name: Documentation
|
||||
about: Useful documentation about Modrinth, its API, and how you can contribute.
|
||||
- name: 📚 Documentation
|
||||
about: Useful documentation about Modrinth's API
|
||||
url: https://docs.modrinth.com
|
||||
|
||||
BIN
.github/assets/api_cover.png
vendored
Normal file
|
After Width: | Height: | Size: 8.0 KiB |
BIN
.github/assets/app_cover.png
vendored
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
.github/assets/monorepo_cover.png
vendored
Normal file
|
After Width: | Height: | Size: 262 KiB |
BIN
.github/assets/web_cover.png
vendored
Normal file
|
After Width: | Height: | Size: 24 KiB |
44
.github/workflows/cli-build.yml
vendored
@ -1,44 +0,0 @@
|
||||
name: CLI Build + Lint
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./theseus_cli
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf
|
||||
|
||||
- name: Rust setup
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
components: rustfmt, clippy
|
||||
|
||||
- name: Rust cache
|
||||
uses: swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: './src-tauri -> target'
|
||||
|
||||
- uses: actions-rs/cargo@v1
|
||||
name: Build program
|
||||
with:
|
||||
command: build
|
||||
args: --bin theseus_cli
|
||||
|
||||
- name: Run Lint
|
||||
uses: actions-rs/clippy-check@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
args: --bin theseus_cli
|
||||
47
.github/workflows/daedalus-docker.yml
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
name: daedalus-docker-build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '**'
|
||||
paths:
|
||||
- .github/workflows/daedalus-docker.yml
|
||||
- 'apps/daedalus_client/**'
|
||||
- 'packages/daedalus/**'
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
paths:
|
||||
- .github/workflows/daedalus-docker.yml
|
||||
- 'apps/daedalus_client/**'
|
||||
- 'packages/daedalus/**'
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Fetch docker metadata
|
||||
id: docker_meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ghcr.io/modrinth/daedalus
|
||||
- name: Login to GitHub Images
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
file: ./apps/daedalus_client/Dockerfile
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.docker_meta.outputs.tags }}
|
||||
labels: ${{ steps.docker_meta.outputs.labels }}
|
||||
cache-from: type=registry,ref=ghcr.io/modrinth/daedalus:main
|
||||
cache-to: type=inline
|
||||
51
.github/workflows/daedalus-run.yml
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
name: Run Meta
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '*/5 * * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
run-docker:
|
||||
if: github.repository_owner == 'modrinth'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Log in to GitHub Container Registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Pull Docker image from GHCR
|
||||
run: docker pull ghcr.io/modrinth/daedalus:main
|
||||
|
||||
- name: Run Docker container
|
||||
env:
|
||||
BASE_URL: ${{ secrets.BASE_URL }}
|
||||
S3_ACCESS_TOKEN: ${{ secrets.S3_ACCESS_TOKEN }}
|
||||
S3_SECRET: ${{ secrets.S3_SECRET }}
|
||||
S3_URL: ${{ secrets.S3_URL }}
|
||||
S3_REGION: ${{ secrets.S3_REGION }}
|
||||
S3_BUCKET_NAME: ${{ secrets.S3_BUCKET_NAME }}
|
||||
CLOUDFLARE_INTEGRATION: ${{ secrets.CLOUDFLARE_INTEGRATION }}
|
||||
CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN }}
|
||||
CLOUDFLARE_ZONE_ID: ${{ secrets.CLOUDFLARE_ZONE_ID }}
|
||||
run: |
|
||||
docker run \
|
||||
--name daedalus \
|
||||
-e RUST_LOG=warn,daedalus_client=trace \
|
||||
-e BASE_URL=$BASE_URL \
|
||||
-e S3_ACCESS_TOKEN=$S3_ACCESS_TOKEN \
|
||||
-e S3_SECRET=$S3_SECRET \
|
||||
-e S3_URL=$S3_URL \
|
||||
-e S3_REGION=$S3_REGION \
|
||||
-e S3_BUCKET_NAME=$S3_BUCKET_NAME \
|
||||
-e CLOUDFLARE_INTEGRATION=$CLOUDFLARE_INTEGRATION \
|
||||
-e CLOUDFLARE_TOKEN=$CLOUDFLARE_TOKEN \
|
||||
-e CLOUDFLARE_ZONE_ID=$CLOUDFLARE_ZONE_ID \
|
||||
ghcr.io/modrinth/daedalus:main
|
||||
30
.github/workflows/frontend-pages.yml
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
name: Clear pages cache
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- prod
|
||||
|
||||
jobs:
|
||||
wait:
|
||||
if: github.repository_owner == 'modrinth'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
deployments: write
|
||||
steps:
|
||||
- name: Cloudflare Pages deployment
|
||||
uses: WalshyDev/cf-pages-await@v1
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
accountId: '9ddae624c98677d68d93df6e524a6061'
|
||||
project: 'frontend'
|
||||
commitHash: ${{ steps.push-changes.outputs.commit-hash }}
|
||||
- name: Purge cache
|
||||
if: github.ref == 'refs/heads/prod'
|
||||
run: |
|
||||
curl -X POST \
|
||||
-H "Authorization: Bearer ${{ secrets.CF_API_TOKEN }}" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data '{"hosts": ["modrinth.com", "www.modrinth.com"]}' \
|
||||
https://api.cloudflare.com/client/v4/zones/e39df17b9c4ef44cbce2646346ee6d33/purge_cache
|
||||
42
.github/workflows/gui-build.yml
vendored
@ -1,42 +0,0 @@
|
||||
name: GUI Build + Lint
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./theseus_gui
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.x
|
||||
- name: Install pnpm via corepack
|
||||
shell: bash
|
||||
run: |
|
||||
corepack enable
|
||||
corepack prepare --activate
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
shell: bash
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
- name: Setup pnpm cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
- name: Run Lint
|
||||
run: pnpm lint
|
||||
- name: Build
|
||||
run: pnpm build
|
||||
45
.github/workflows/labrinth-docker.yml
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
name: docker-build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '**'
|
||||
paths:
|
||||
- .github/workflows/labrinth-docker.yml
|
||||
- 'apps/labrinth/**'
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
paths:
|
||||
- .github/workflows/labrinth-docker.yml
|
||||
- 'apps/labrinth/**'
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Fetch docker metadata
|
||||
id: docker_meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ghcr.io/modrinth/labrinth
|
||||
- name: Login to GitHub Images
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
file: ./apps/labrinth/Dockerfile
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.docker_meta.outputs.tags }}
|
||||
labels: ${{ steps.docker_meta.outputs.labels }}
|
||||
cache-from: type=registry,ref=ghcr.io/modrinth/labrinth:main
|
||||
cache-to: type=inline
|
||||
109
.github/workflows/tauri-build.yml
vendored
@ -1,109 +0,0 @@
|
||||
name: 'Tauri GUI Build'
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
jobs:
|
||||
test-tauri:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [macos-latest, windows-latest, ubuntu-20.04, ubuntu-22.04]
|
||||
|
||||
runs-on: ${{ matrix.platform }}
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./theseus_gui
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Rust setup (mac)
|
||||
if: startsWith(matrix.platform, 'macos')
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
components: rustfmt, clippy
|
||||
targets: aarch64-apple-darwin
|
||||
|
||||
- name: Rust setup
|
||||
if: "!startsWith(matrix.platform, 'macos')"
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
components: rustfmt, clippy
|
||||
|
||||
- name: Rust cache
|
||||
uses: swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: './src-tauri -> target'
|
||||
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18.x
|
||||
- name: Install pnpm via corepack
|
||||
shell: bash
|
||||
run: |
|
||||
corepack enable
|
||||
corepack prepare --activate
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
shell: bash
|
||||
run: |
|
||||
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||
- name: Setup pnpm cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
|
||||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pnpm-store-
|
||||
|
||||
- name: install dependencies (ubuntu only)
|
||||
if: startsWith(matrix.platform, 'ubuntu')
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf libselinux1
|
||||
|
||||
- name: Install frontend dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: build app (macos)
|
||||
uses: tauri-apps/tauri-action@v0
|
||||
id: build_os_mac
|
||||
if: startsWith(matrix.platform, 'macos')
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }}
|
||||
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
||||
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
||||
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||
with:
|
||||
args: --target universal-apple-darwin
|
||||
|
||||
- name: build app
|
||||
uses: tauri-apps/tauri-action@v0
|
||||
id: build_os
|
||||
if: "!startsWith(matrix.platform, 'macos')"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||
|
||||
- name: upload ${{ matrix.platform }}
|
||||
uses: actions/upload-artifact@v3
|
||||
if: startsWith(matrix.platform, 'macos')
|
||||
with:
|
||||
name: ${{ matrix.platform }}
|
||||
path: "${{ join(fromJSON(steps.build_os_mac.outputs.artifactPaths), '\n') }}"
|
||||
|
||||
- name: upload ${{ matrix.platform }}
|
||||
uses: actions/upload-artifact@v3
|
||||
if: "!startsWith(matrix.platform, 'macos')"
|
||||
with:
|
||||
name: ${{ matrix.platform }}
|
||||
path: "${{ join(fromJSON(steps.build_os.outputs.artifactPaths), '\n') }}"
|
||||
152
.github/workflows/theseus-build.yml
vendored
Normal file
@ -0,0 +1,152 @@
|
||||
name: Modrinth App build
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
tags:
|
||||
- 'v*'
|
||||
paths:
|
||||
- .github/workflows/theseus-build.yml
|
||||
- 'apps/app/**'
|
||||
- 'apps/app-frontend/**'
|
||||
- 'packages/app-lib/**'
|
||||
- 'packages/app-macros/**'
|
||||
- 'packages/assets/**'
|
||||
- 'packages/ui/**'
|
||||
- 'packages/utils/**'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
sign-windows-binaries:
|
||||
description: Sign Windows binaries
|
||||
type: boolean
|
||||
default: true
|
||||
required: false
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [macos-latest, windows-latest, ubuntu-22.04]
|
||||
include:
|
||||
- platform: macos-latest
|
||||
artifact-target-name: universal-apple-darwin
|
||||
- platform: windows-latest
|
||||
artifact-target-name: x86_64-pc-windows-msvc
|
||||
- platform: ubuntu-22.04
|
||||
artifact-target-name: x86_64-unknown-linux-gnu
|
||||
|
||||
runs-on: ${{ matrix.platform }}
|
||||
|
||||
steps:
|
||||
- name: 📥 Check out code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: 🧰 Setup Rust toolchain
|
||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
rustflags: ''
|
||||
target: ${{ startsWith(matrix.platform, 'macos') && 'x86_64-apple-darwin' || '' }}
|
||||
|
||||
- name: 🧰 Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
|
||||
- name: 🧰 Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: .nvmrc
|
||||
cache: pnpm
|
||||
|
||||
- name: 🧰 Install Linux build dependencies
|
||||
if: startsWith(matrix.platform, 'ubuntu')
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -yq libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev
|
||||
|
||||
- name: 🧰 Setup Dasel
|
||||
uses: jaxxstorm/action-install-gh-release@v2.1.0
|
||||
with:
|
||||
repo: TomWright/dasel
|
||||
tag: v2.8.1
|
||||
extension-matching: disable
|
||||
rename-to: ${{ startsWith(matrix.platform, 'windows') && 'dasel.exe' || 'dasel' }}
|
||||
chmod: 0755
|
||||
|
||||
- name: ⚙️ Set application version and environment
|
||||
shell: bash
|
||||
run: |
|
||||
APP_VERSION="$(git describe --tags --always | sed -E 's/-([0-9]+)-(g[0-9a-fA-F]+)$/-canary+\1.\2/')"
|
||||
echo "Setting application version to $APP_VERSION"
|
||||
dasel put -f apps/app/Cargo.toml -t string -v "${APP_VERSION#v}" 'package.version'
|
||||
dasel put -f packages/app-lib/Cargo.toml -t string -v "${APP_VERSION#v}" 'package.version'
|
||||
dasel put -f apps/app-frontend/package.json -t string -v "${APP_VERSION#v}" 'version'
|
||||
|
||||
cp packages/app-lib/.env.prod packages/app-lib/.env
|
||||
|
||||
- name: 💨 Setup Turbo cache
|
||||
uses: rharkor/caching-for-turbo@v1.8
|
||||
|
||||
- name: 🧰 Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: ✍️ Set up Windows code signing
|
||||
if: startsWith(matrix.platform, 'windows')
|
||||
shell: bash
|
||||
run: |
|
||||
if [ '${{ startsWith(github.ref, 'refs/tags/v') || inputs.sign-windows-binaries }}' = 'true' ]; then
|
||||
choco install jsign --ignore-dependencies # GitHub runners come with a global Java installation already
|
||||
else
|
||||
dasel delete -f apps/app/tauri-release.conf.json 'bundle.windows.signCommand'
|
||||
fi
|
||||
|
||||
- name: 🔨 Build macOS app
|
||||
run: pnpm --filter=@modrinth/app run tauri build --target universal-apple-darwin --config tauri-release.conf.json
|
||||
if: startsWith(matrix.platform, 'macos')
|
||||
env:
|
||||
ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }}
|
||||
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
||||
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
||||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
||||
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||
|
||||
- name: 🔨 Build Linux app
|
||||
run: pnpm --filter=@modrinth/app run tauri build --config tauri-release.conf.json
|
||||
if: startsWith(matrix.platform, 'ubuntu')
|
||||
env:
|
||||
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||
|
||||
- name: 🔨 Build Windows app
|
||||
run: |
|
||||
[System.Convert]::FromBase64String("$env:DIGICERT_ONE_SIGNER_CLIENT_CERTIFICATE_BASE64") | Set-Content -Path signer-client-cert.p12 -AsByteStream
|
||||
$env:DIGICERT_ONE_SIGNER_CREDENTIALS = "$env:DIGICERT_ONE_SIGNER_API_KEY|$PWD\signer-client-cert.p12|$env:DIGICERT_ONE_SIGNER_CLIENT_CERTIFICATE_PASSWORD"
|
||||
$env:JAVA_HOME = "$env:JAVA_HOME_11_X64"
|
||||
pnpm --filter=@modrinth/app run tauri build --config tauri-release.conf.json --verbose --bundles 'nsis,updater'
|
||||
Remove-Item -Path signer-client-cert.p12 -ErrorAction SilentlyContinue
|
||||
if: startsWith(matrix.platform, 'windows')
|
||||
env:
|
||||
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||
DIGICERT_ONE_SIGNER_API_KEY: ${{ secrets.DIGICERT_ONE_SIGNER_API_KEY }}
|
||||
DIGICERT_ONE_SIGNER_CLIENT_CERTIFICATE_BASE64: ${{ secrets.DIGICERT_ONE_SIGNER_CLIENT_CERTIFICATE_BASE64 }}
|
||||
DIGICERT_ONE_SIGNER_CLIENT_CERTIFICATE_PASSWORD: ${{ secrets.DIGICERT_ONE_SIGNER_CLIENT_CERTIFICATE_PASSWORD }}
|
||||
|
||||
- name: 📤 Upload app bundles
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: App bundle (${{ matrix.artifact-target-name }})
|
||||
path: |
|
||||
target/release/bundle/appimage/Modrinth App_*.AppImage*
|
||||
target/release/bundle/deb/Modrinth App_*.deb*
|
||||
target/release/bundle/rpm/Modrinth App-*.rpm*
|
||||
target/universal-apple-darwin/release/bundle/macos/Modrinth App.app.tar.gz*
|
||||
target/universal-apple-darwin/release/bundle/dmg/Modrinth App_*.dmg*
|
||||
target/release/bundle/nsis/Modrinth App_*-setup.exe*
|
||||
target/release/bundle/nsis/Modrinth App_*-setup.nsis.zip*
|
||||
118
.github/workflows/theseus-release.yml
vendored
Normal file
@ -0,0 +1,118 @@
|
||||
name: Modrinth App release
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version-tag:
|
||||
description: Version tag to release to the wide public
|
||||
type: string
|
||||
required: true
|
||||
release-notes:
|
||||
description: Release notes to include in the Tauri version manifest
|
||||
default: A new release of the Modrinth App is available!
|
||||
type: string
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
release:
|
||||
name: Release Modrinth App
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
env:
|
||||
LINUX_X64_BUNDLE_ARTIFACT_NAME: App bundle (x86_64-unknown-linux-gnu)
|
||||
WINDOWS_X64_BUNDLE_ARTIFACT_NAME: App bundle (x86_64-pc-windows-msvc)
|
||||
MACOS_UNIVERSAL_BUNDLE_ARTIFACT_NAME: App bundle (universal-apple-darwin)
|
||||
LAUNCHER_FILES_BUCKET_BASE_URL: https://launcher-files.modrinth.com
|
||||
|
||||
steps:
|
||||
- name: 📥 Download Modrinth App artifacts
|
||||
uses: dawidd6/action-download-artifact@v11
|
||||
with:
|
||||
workflow: theseus-build.yml
|
||||
workflow_conclusion: success
|
||||
event: push
|
||||
branch: ${{ inputs.version-tag }}
|
||||
use_unzip: true
|
||||
|
||||
- name: 🛠️ Generate version manifest
|
||||
env:
|
||||
VERSION_TAG: ${{ inputs.version-tag }}
|
||||
RELEASE_NOTES: ${{ inputs.release-notes }}
|
||||
run: |
|
||||
# Reference: https://tauri.app/plugin/updater/#server-support
|
||||
jq -nc \
|
||||
--arg versionTag "${VERSION_TAG#v}" \
|
||||
--arg releaseNotes "$RELEASE_NOTES" \
|
||||
--rawfile macOsAarch64UpdateArtifactSignature "${MACOS_UNIVERSAL_BUNDLE_ARTIFACT_NAME}/universal-apple-darwin/release/bundle/macos/Modrinth App.app.tar.gz.sig" \
|
||||
--rawfile macOsX64UpdateArtifactSignature "${MACOS_UNIVERSAL_BUNDLE_ARTIFACT_NAME}/universal-apple-darwin/release/bundle/macos/Modrinth App.app.tar.gz.sig" \
|
||||
--rawfile linuxX64UpdateArtifactSignature "${LINUX_X64_BUNDLE_ARTIFACT_NAME}/release/bundle/appimage/Modrinth App_${VERSION_TAG#v}_amd64.AppImage.tar.gz.sig" \
|
||||
--rawfile windowsX64UpdateArtifactSignature "${WINDOWS_X64_BUNDLE_ARTIFACT_NAME}/release/bundle/nsis/Modrinth App_${VERSION_TAG#v}_x64-setup.nsis.zip.sig" \
|
||||
'{
|
||||
"version": $versionTag,
|
||||
"notes": $releaseNotes,
|
||||
"pub_date": now | todateiso8601,
|
||||
"platforms": {
|
||||
"darwin-aarch64": {
|
||||
"signature": $macOsAarch64UpdateArtifactSignature,
|
||||
"url": @uri "${{ env.LAUNCHER_FILES_BUCKET_BASE_URL }}/versions/\($versionTag)/macos/\("Modrinth App.app.tar.gz")",
|
||||
"install_urls": [@uri "${{ env.LAUNCHER_FILES_BUCKET_BASE_URL }}/versions/\($versionTag)/macos/\("Modrinth App_" + $versionTag + "_universal.dmg")"]
|
||||
},
|
||||
"darwin-x86_64": {
|
||||
"signature": $macOsX64UpdateArtifactSignature,
|
||||
"url": @uri "${{ env.LAUNCHER_FILES_BUCKET_BASE_URL }}/versions/\($versionTag)/macos/\("Modrinth App.app.tar.gz")",
|
||||
"install_urls": [@uri "${{ env.LAUNCHER_FILES_BUCKET_BASE_URL }}/versions/\($versionTag)/macos/\("Modrinth App_" + $versionTag + "_universal.dmg")"]
|
||||
},
|
||||
"linux-x86_64": {
|
||||
"signature": $linuxX64UpdateArtifactSignature,
|
||||
"url": @uri "${{ env.LAUNCHER_FILES_BUCKET_BASE_URL }}/versions/\($versionTag)/linux/\("Modrinth App_" + $versionTag + "_amd64.AppImage.tar.gz")",
|
||||
"install_urls": [
|
||||
@uri "${{ env.LAUNCHER_FILES_BUCKET_BASE_URL }}/versions/\($versionTag)/linux/\("Modrinth App_" + $versionTag + "_amd64.deb")",
|
||||
@uri "${{ env.LAUNCHER_FILES_BUCKET_BASE_URL }}/versions/\($versionTag)/linux/\("Modrinth App_" + $versionTag + "_amd64.AppImage")",
|
||||
@uri "${{ env.LAUNCHER_FILES_BUCKET_BASE_URL }}/versions/\($versionTag)/linux/\("Modrinth App-" + $versionTag + "-1.x86_64.rpm")"
|
||||
]
|
||||
},
|
||||
"windows-x86_64": {
|
||||
"signature": $windowsX64UpdateArtifactSignature,
|
||||
"url": @uri "${{ env.LAUNCHER_FILES_BUCKET_BASE_URL }}/versions/\($versionTag)/windows/\("Modrinth App_" + $versionTag + "_x64-setup.nsis.zip")",
|
||||
"install_urls": [@uri "${{ env.LAUNCHER_FILES_BUCKET_BASE_URL }}/versions/\($versionTag)/windows/\("Modrinth App_" + $versionTag + "_x64-setup.exe")"]
|
||||
}
|
||||
}
|
||||
}' > updates.json
|
||||
|
||||
echo "Generated manifest for version ${VERSION_TAG}:"
|
||||
cat updates.json
|
||||
|
||||
- name: 📤 Upload release artifacts
|
||||
env:
|
||||
VERSION_TAG: ${{ inputs.version-tag }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.LAUNCHER_FILES_BUCKET_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.LAUNCHER_FILES_BUCKET_SECRET_ACCESS_KEY }}
|
||||
AWS_BUCKET: ${{ secrets.LAUNCHER_FILES_BUCKET_NAME }}
|
||||
AWS_REGION: ${{ secrets.LAUNCHER_FILES_BUCKET_REGION }}
|
||||
AWS_ENDPOINT_URL: ${{ secrets.LAUNCHER_FILES_BUCKET_ENDPOINT_URL }}
|
||||
AWS_PAGER: ''
|
||||
# Work around incompatible checksum behavior with some S3-like object storage providers,
|
||||
# such as Cloudflare R2. See:
|
||||
# - https://developers.cloudflare.com/r2/examples/aws/aws-cli/
|
||||
# - https://developers.cloudflare.com/r2/examples/aws/aws-sdk-java/
|
||||
AWS_REQUEST_CHECKSUM_CALCULATION: when_required
|
||||
AWS_RESPONSE_CHECKSUM_VALIDATION: when_required
|
||||
run: |
|
||||
for macosBundleType in 'macos' 'dmg'; do
|
||||
aws s3 cp --recursive \
|
||||
"${MACOS_UNIVERSAL_BUNDLE_ARTIFACT_NAME}/universal-apple-darwin/release/bundle/${macosBundleType}" \
|
||||
"s3://${AWS_BUCKET}/versions/${VERSION_TAG#v}/macos"
|
||||
done
|
||||
|
||||
for linuxBundleType in 'appimage' 'deb' 'rpm'; do
|
||||
aws s3 cp --recursive \
|
||||
"${LINUX_X64_BUNDLE_ARTIFACT_NAME}/release/bundle/${linuxBundleType}" \
|
||||
"s3://${AWS_BUCKET}/versions/${VERSION_TAG#v}/linux"
|
||||
done
|
||||
|
||||
for windowsBundleType in 'nsis'; do
|
||||
aws s3 cp --recursive \
|
||||
"${WINDOWS_X64_BUNDLE_ARTIFACT_NAME}/release/bundle/${windowsBundleType}" \
|
||||
"s3://${AWS_BUCKET}/versions/${VERSION_TAG#v}/windows"
|
||||
done
|
||||
|
||||
aws s3 cp updates.json "s3://${AWS_BUCKET}"
|
||||
87
.github/workflows/turbo-ci.yml
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Lint and Test
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
env:
|
||||
# Ensure pnpm output is colored in GitHub Actions logs
|
||||
FORCE_COLOR: 3
|
||||
# Make cargo nextest successfully ignore projects without tests
|
||||
NEXTEST_NO_TESTS: pass
|
||||
|
||||
steps:
|
||||
- name: 📥 Check out code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: 🧰 Install build dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -yq libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev
|
||||
|
||||
- name: 🧰 Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
|
||||
- name: 🧰 Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: .nvmrc
|
||||
cache: pnpm
|
||||
|
||||
- name: 🧰 Setup Rust toolchain
|
||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
rustflags: ''
|
||||
components: clippy, rustfmt
|
||||
cache: false
|
||||
|
||||
- name: 🧰 Setup nextest
|
||||
uses: taiki-e/install-action@nextest
|
||||
|
||||
# cargo-binstall does not have pre-built binaries for sqlx-cli, so we fall
|
||||
# back to a cached cargo install
|
||||
- name: 🧰 Setup cargo-sqlx
|
||||
uses: taiki-e/cache-cargo-install-action@v2
|
||||
with:
|
||||
tool: sqlx-cli
|
||||
locked: false
|
||||
no-default-features: true
|
||||
features: rustls,postgres
|
||||
|
||||
- name: 💨 Setup Turbo cache
|
||||
uses: rharkor/caching-for-turbo@v1.8
|
||||
|
||||
- name: 🧰 Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: ⚙️ Start services
|
||||
run: docker compose up --wait
|
||||
|
||||
- name: ⚙️ Setup Labrinth environment and database
|
||||
working-directory: apps/labrinth
|
||||
run: |
|
||||
cp .env.local .env
|
||||
sqlx database setup
|
||||
|
||||
- name: ⚙️ Set app environment
|
||||
working-directory: packages/app-lib
|
||||
run: cp .env.staging .env
|
||||
|
||||
- name: 🔍 Lint and test
|
||||
run: pnpm run ci
|
||||
|
||||
- name: 🔍 Verify intl:extract has been run
|
||||
run: |
|
||||
pnpm intl:extract
|
||||
git diff --exit-code --color */*/src/locales/en-US/index.json
|
||||
163
.gitignore
vendored
@ -1,114 +1,63 @@
|
||||
/target
|
||||
node_modules/
|
||||
.svelte-kit/
|
||||
theseus_gui/build/
|
||||
theseus_gui/generated/
|
||||
WixTools
|
||||
.direnv/
|
||||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# compiled output
|
||||
dist
|
||||
tmp
|
||||
/out-tsc
|
||||
|
||||
# dependencies
|
||||
node_modules
|
||||
|
||||
# IDEs and editors
|
||||
/.idea
|
||||
.project
|
||||
.classpath
|
||||
.c9/
|
||||
*.launch
|
||||
.settings/
|
||||
*.sublime-workspace
|
||||
|
||||
# IDE - VSCode
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
|
||||
# misc
|
||||
/.sass-cache
|
||||
/connect.lock
|
||||
/coverage
|
||||
/libpeerconnection.log
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
testem.log
|
||||
/typings
|
||||
|
||||
# System Files
|
||||
.DS_Store
|
||||
.pnpm-debug.log
|
||||
Thumbs.db
|
||||
|
||||
minecraft
|
||||
config
|
||||
# Nuxt dev/build outputs
|
||||
.output
|
||||
.data
|
||||
.nuxt
|
||||
.nitro
|
||||
.cache
|
||||
|
||||
[#]*[#]
|
||||
# frontend generated files
|
||||
apps/frontend/src/generated
|
||||
|
||||
# TEMPORARY: ignore my test instance and metadata
|
||||
theseus_cli/foo
|
||||
.turbo
|
||||
target
|
||||
generated
|
||||
.env
|
||||
|
||||
### Intellij+all ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
# app testing dir
|
||||
app-playground-data/*
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
### Intellij+all Patch ###
|
||||
# Ignore everything but code style settings and run configurations
|
||||
# that are supposed to be shared within teams.
|
||||
|
||||
.idea/*
|
||||
|
||||
!.idea/codeStyles
|
||||
!.idea/runConfigurations
|
||||
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
|
||||
# MSVC Windows builds of rustc generate these, which store debugging information
|
||||
*.pdb
|
||||
|
||||
theseus.iml
|
||||
# soley because i need the PORT to be 3002 due to WSL stuff
|
||||
.env
|
||||
apps/frontend/.env
|
||||
|
||||
.astro
|
||||
|
||||
8
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
19
.idea/code.iml
generated
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/apps/daedalus_client/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/packages/daedalus/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/apps/app-playground/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/apps/app/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/apps/labrinth/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/apps/labrinth/tests" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/packages/app-lib/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/packages/ariadne/src" isTestSource="false" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
7
.idea/discord.xml
generated
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DiscordProjectSettings">
|
||||
<option name="show" value="PROJECT_FILES" />
|
||||
<option name="description" value="" />
|
||||
</component>
|
||||
</project>
|
||||
26
.idea/libraries/KotlinJavaRuntime.xml
generated
Normal file
@ -0,0 +1,26 @@
|
||||
<component name="libraryTable">
|
||||
<library name="KotlinJavaRuntime" type="repository">
|
||||
<properties maven-id="org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.8.0/kotlin-stdlib-jdk8-1.8.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.8.0/kotlin-stdlib-1.8.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-common/1.8.0/kotlin-stdlib-common-1.8.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.8.0/kotlin-stdlib-jdk7-1.8.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.8.0/kotlin-stdlib-jdk8-1.8.0-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.8.0/kotlin-stdlib-1.8.0-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-common/1.8.0/kotlin-stdlib-common-1.8.0-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0-javadoc.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.8.0/kotlin-stdlib-jdk7-1.8.0-javadoc.jar!/" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.8.0/kotlin-stdlib-jdk8-1.8.0-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib/1.8.0/kotlin-stdlib-1.8.0-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-common/1.8.0/kotlin-stdlib-common-1.8.0-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/annotations/13.0/annotations-13.0-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.8.0/kotlin-stdlib-jdk7-1.8.0-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/code.iml" filepath="$PROJECT_DIR$/.idea/code.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
12
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CommitMessageInspectionProfile">
|
||||
<profile version="1.0">
|
||||
<inspection_tool class="CommitFormat" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="CommitNamingConvention" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
</profile>
|
||||
</component>
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
2
.npmrc
Normal file
@ -0,0 +1,2 @@
|
||||
strict-peer-dependencies=false
|
||||
auto-install-peers=true
|
||||
13
.vscode/extensions.json
vendored
@ -1,12 +1,3 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"tauri-apps.tauri-vscode",
|
||||
"vunguyentuan.vscode-css-variables",
|
||||
"stylelint.vscode-stylelint",
|
||||
"eamodio.gitlens",
|
||||
"esbenp.prettier-vscode",
|
||||
"pivaszbs.svelte-autoimport",
|
||||
"svelte.svelte-vscode",
|
||||
"ardenivanov.svelte-intellisense"
|
||||
]
|
||||
}
|
||||
"recommendations": ["esbenp.prettier-vscode", "Vue.volar", "rust-lang.rust-analyzer"]
|
||||
}
|
||||
|
||||
160
.vscode/launch.json
vendored
@ -1,160 +0,0 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Debug unit tests in library 'theseus'",
|
||||
"cargo": {
|
||||
"args": [
|
||||
"test",
|
||||
"--no-run",
|
||||
"--lib",
|
||||
"--package=theseus"
|
||||
],
|
||||
"filter": {
|
||||
"name": "theseus",
|
||||
"kind": "lib"
|
||||
}
|
||||
},
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Debug executable 'theseus_cli'",
|
||||
"cargo": {
|
||||
"args": [
|
||||
"build",
|
||||
"--bin=theseus_cli",
|
||||
"--package=theseus_cli"
|
||||
],
|
||||
"filter": {
|
||||
"name": "theseus_cli",
|
||||
"kind": "bin"
|
||||
}
|
||||
},
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Debug unit tests in executable 'theseus_cli'",
|
||||
"cargo": {
|
||||
"args": [
|
||||
"test",
|
||||
"--no-run",
|
||||
"--bin=theseus_cli",
|
||||
"--package=theseus_cli"
|
||||
],
|
||||
"filter": {
|
||||
"name": "theseus_cli",
|
||||
"kind": "bin"
|
||||
}
|
||||
},
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Debug executable 'theseus_playground'",
|
||||
"cargo": {
|
||||
"args": [
|
||||
"build",
|
||||
"--bin=theseus_playground",
|
||||
"--package=theseus_playground"
|
||||
],
|
||||
"filter": {
|
||||
"name": "theseus_playground",
|
||||
"kind": "bin"
|
||||
}
|
||||
},
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Debug unit tests in executable 'theseus_playground'",
|
||||
"cargo": {
|
||||
"args": [
|
||||
"test",
|
||||
"--no-run",
|
||||
"--bin=theseus_playground",
|
||||
"--package=theseus_playground"
|
||||
],
|
||||
"filter": {
|
||||
"name": "theseus_playground",
|
||||
"kind": "bin"
|
||||
}
|
||||
},
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Debug executable 'theseus_gui'",
|
||||
"cargo": {
|
||||
"args": [
|
||||
"build",
|
||||
"--bin=theseus_gui",
|
||||
"--package=theseus_gui"
|
||||
],
|
||||
"filter": {
|
||||
"name": "theseus_gui",
|
||||
"kind": "bin"
|
||||
}
|
||||
},
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Debug unit tests in executable 'theseus_gui'",
|
||||
"cargo": {
|
||||
"args": [
|
||||
"test",
|
||||
"--no-run",
|
||||
"--bin=theseus_gui",
|
||||
"--package=theseus_gui"
|
||||
],
|
||||
"filter": {
|
||||
"name": "theseus_gui",
|
||||
"kind": "bin"
|
||||
}
|
||||
},
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Tauri Development Debug",
|
||||
"cargo": {
|
||||
"args": [
|
||||
"build",
|
||||
"--manifest-path=./theseus_gui/src-tauri/Cargo.toml",
|
||||
"--no-default-features"
|
||||
]
|
||||
},
|
||||
"preLaunchTask": "ui:dev"
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Tauri Production Debug",
|
||||
"cargo": {
|
||||
"args": ["build", "--release", "--manifest-path=.theseus_gui/src-tauri/Cargo.toml"]
|
||||
},
|
||||
"preLaunchTask": "ui:build"
|
||||
}
|
||||
]
|
||||
}
|
||||
67
.vscode/settings.json
vendored
@ -1,60 +1,9 @@
|
||||
{
|
||||
"cssVariables.lookupFiles": [
|
||||
"**/*.postcss",
|
||||
"**/node_modules/omorphia/**/*.postcss"
|
||||
],
|
||||
"cssVariables.blacklistFolders": [
|
||||
"**/.git",
|
||||
"**/.svn",
|
||||
"**/.hg",
|
||||
"**/CVS",
|
||||
"**/.DS_Store",
|
||||
"**/.git",
|
||||
"**/bower_components",
|
||||
"**/tmp",
|
||||
"**/dist",
|
||||
"**/tests"
|
||||
],
|
||||
"gitlens.showWelcomeOnInstall": false,
|
||||
"gitlens.showWhatsNewAfterUpgrades": false,
|
||||
"gitlens.plusFeatures.enabled": false,
|
||||
"gitlens.currentLine.enabled": false,
|
||||
"gitlens.currentLine.pullRequests.enabled": false,
|
||||
"gitlens.currentLine.scrollable": true,
|
||||
"gitlens.codeLens.enabled": false,
|
||||
"gitlens.hovers.enabled": false,
|
||||
"CSSNavigation.activeCSSFileExtensions": [
|
||||
"css",
|
||||
"postcss"
|
||||
],
|
||||
"CSSNavigation.activeHTMLFileExtensions": [
|
||||
"html",
|
||||
"svelte",
|
||||
"js",
|
||||
"ts"
|
||||
],
|
||||
"CSSNavigation.excludeGlobPatterns": [
|
||||
"**/bower_components/**",
|
||||
"**/vendor/**",
|
||||
"**/coverage/**"
|
||||
],
|
||||
"CSSNavigation.alwaysIncludeGlobPatterns": [
|
||||
"./theseus_gui/node_modules/omorphia/**/*.postcss"
|
||||
],
|
||||
"html-css-class-completion.HTMLLanguages": [
|
||||
"html",
|
||||
"svelte"
|
||||
],
|
||||
"html-css-class-completion.includeGlobPattern": "**/*.{postcss,svelte}",
|
||||
"html-css-class-completion.CSSLanguages": [
|
||||
"postcss",
|
||||
],
|
||||
"svelte.enable-ts-plugin": true,
|
||||
"svelte.ask-to-enable-ts-plugin": false,
|
||||
"svelte.plugin.css.diagnostics.enable": false,
|
||||
"svelte.plugin.svelte.diagnostics.enable": false,
|
||||
"rust-analyzer.linkedProjects": [
|
||||
"./theseus/Cargo.toml"
|
||||
],
|
||||
"rust-analyzer.showUnlinkedFileNotification": false,
|
||||
}
|
||||
"prettier.endOfLine": "lf",
|
||||
"editor.formatOnSave": true,
|
||||
"eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"],
|
||||
"editor.detectIndentation": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit"
|
||||
}
|
||||
}
|
||||
|
||||
32
.vscode/tasks.json
vendored
@ -1,32 +0,0 @@
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "ui:dev",
|
||||
"type": "shell",
|
||||
// `dev` keeps running in the background
|
||||
// ideally you should also configure a `problemMatcher`
|
||||
// see https://code.visualstudio.com/docs/editor/tasks#_can-a-background-task-be-used-as-a-prelaunchtask-in-launchjson
|
||||
"isBackground": true,
|
||||
// change this to your `beforeDevCommand`:
|
||||
"command": "yarn",
|
||||
"args": ["dev"],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/theseus_gui"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "ui:build",
|
||||
"type": "shell",
|
||||
// change this to your `beforeBuildCommand`:
|
||||
"command": "yarn",
|
||||
"args": ["build"],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/theseus_gui"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
14
COPYING.md
@ -1,13 +1,13 @@
|
||||
# Copying
|
||||
# Copying Guidelines
|
||||
|
||||
The source code of the theseus repository is licensed under the GNU General Public License, Version 3 only, which is provided in the file [LICENSE](./LICENSE). However, some files listed below are licensed under a different license.
|
||||
All packages in this repository are licensed under their respective licenses. For more information, refer to the LICENSE file in each package.
|
||||
|
||||
## Modrinth logo
|
||||
For detailed information, consult each package's COPYING.md file, if available.
|
||||
|
||||
Any files depicting the Modrinth branding, including the wrench-in-labyrinth logo, the landing image, and variations thereof, are licensed as follows:
|
||||
## Modrinth Branding
|
||||
|
||||
> All rights reserved. © 2020-2023 Rinth, Inc.
|
||||
The use of Modrinth branding elements, including but not limited to the wrench-in-labyrinth logo, the landing image, and any variations thereof, is strictly prohibited without explicit written permission from Rinth, Inc. This includes trademarks, logos, or other branding elements.
|
||||
|
||||
This includes, but may not be limited to, the following files:
|
||||
All rights reserved. © 2020-2024 Rinth, Inc.
|
||||
|
||||
- theseus_gui/src-tauri/icons/*
|
||||
If you fork this repository, you must remove all Modrinth branding assets from your fork.
|
||||
|
||||
9453
Cargo.lock
generated
254
Cargo.toml
@ -1,28 +1,240 @@
|
||||
[workspace]
|
||||
|
||||
resolver = "2"
|
||||
members = [
|
||||
"theseus",
|
||||
"theseus_cli",
|
||||
"theseus_playground",
|
||||
"theseus_gui/src-tauri",
|
||||
"theseus_macros"
|
||||
"apps/app",
|
||||
"apps/app-playground",
|
||||
"apps/daedalus_client",
|
||||
"apps/labrinth",
|
||||
"packages/app-lib",
|
||||
"packages/ariadne",
|
||||
"packages/daedalus",
|
||||
]
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 0
|
||||
debug = true
|
||||
debug-assertions = true
|
||||
overflow-checks = true
|
||||
lto = false
|
||||
panic = 'unwind'
|
||||
incremental = true
|
||||
codegen-units = 256
|
||||
rpath = false
|
||||
[workspace.package]
|
||||
edition = "2024"
|
||||
|
||||
[workspace.dependencies]
|
||||
actix-cors = "0.7.1"
|
||||
actix-files = "0.6.6"
|
||||
actix-http = "3.11.0"
|
||||
actix-multipart = "0.7.2"
|
||||
actix-rt = "2.10.0"
|
||||
actix-web = "4.11.0"
|
||||
actix-web-prom = "0.10.0"
|
||||
actix-ws = "0.3.0"
|
||||
argon2 = { version = "0.5.3", features = ["std"] }
|
||||
ariadne = { path = "packages/ariadne" }
|
||||
async_zip = "0.0.17"
|
||||
async-compression = { version = "0.4.25", default-features = false }
|
||||
async-recursion = "1.1.1"
|
||||
async-stripe = { version = "0.41.0", default-features = false, features = [
|
||||
"runtime-tokio-hyper-rustls",
|
||||
] }
|
||||
async-trait = "0.1.88"
|
||||
async-tungstenite = { version = "0.29.1", default-features = false, features = [
|
||||
"futures-03-sink",
|
||||
] }
|
||||
async-walkdir = "2.1.0"
|
||||
base64 = "0.22.1"
|
||||
bitflags = "2.9.1"
|
||||
bytemuck = "1.23.0"
|
||||
bytes = "1.10.1"
|
||||
censor = "0.3.0"
|
||||
chardetng = "0.1.17"
|
||||
chrono = "0.4.41"
|
||||
clap = "4.5.40"
|
||||
clickhouse = "0.13.3"
|
||||
color-thief = "0.2.2"
|
||||
console-subscriber = "0.4.1"
|
||||
daedalus = { path = "packages/daedalus" }
|
||||
dashmap = "6.1.0"
|
||||
data-url = "0.3.1"
|
||||
deadpool-redis = "0.21.1"
|
||||
dirs = "6.0.0"
|
||||
discord-rich-presence = "0.2.5"
|
||||
dotenv-build = "0.1.1"
|
||||
dotenvy = "0.15.7"
|
||||
dunce = "1.0.5"
|
||||
either = "1.15.0"
|
||||
encoding_rs = "0.8.35"
|
||||
enumset = "1.1.6"
|
||||
flate2 = "1.1.2"
|
||||
fs4 = { version = "0.13.1", default-features = false }
|
||||
futures = { version = "0.3.31", default-features = false }
|
||||
futures-util = "0.3.31"
|
||||
hashlink = "0.10.0"
|
||||
heck = "0.5.0"
|
||||
hex = "0.4.3"
|
||||
hickory-resolver = "0.25.2"
|
||||
hmac = "0.12.1"
|
||||
hyper = "1.6.0"
|
||||
hyper-rustls = { version = "0.27.7", default-features = false, features = [
|
||||
"http1",
|
||||
"native-tokio",
|
||||
"ring",
|
||||
"tls12",
|
||||
] }
|
||||
hyper-util = "0.1.14"
|
||||
iana-time-zone = "0.1.63"
|
||||
image = { version = "0.25.6", default-features = false, features = ["rayon"] }
|
||||
indexmap = "2.9.0"
|
||||
indicatif = "0.17.11"
|
||||
itertools = "0.14.0"
|
||||
jemalloc_pprof = "0.7.0"
|
||||
json-patch = { version = "4.0.0", default-features = false }
|
||||
lettre = { version = "0.11.17", default-features = false, features = [
|
||||
"builder",
|
||||
"hostname",
|
||||
"pool",
|
||||
"ring",
|
||||
"rustls",
|
||||
"rustls-native-certs",
|
||||
"smtp-transport",
|
||||
] }
|
||||
maxminddb = "0.26.0"
|
||||
meilisearch-sdk = { version = "0.28.0", default-features = false }
|
||||
murmur2 = "0.1.0"
|
||||
native-dialog = "0.9.0"
|
||||
notify = { version = "8.0.0", default-features = false }
|
||||
notify-debouncer-mini = { version = "0.6.0", default-features = false }
|
||||
p256 = "0.13.2"
|
||||
paste = "1.0.15"
|
||||
phf = { version = "0.12.1", features = ["macros"] }
|
||||
png = "0.17.16"
|
||||
prometheus = "0.14.0"
|
||||
quartz_nbt = "0.2.9"
|
||||
quick-xml = "0.37.5"
|
||||
rand = "=0.8.5" # Locked on 0.8 until argon2 and p256 update to 0.9
|
||||
rand_chacha = "=0.3.1" # Locked on 0.3 until we can update rand to 0.9
|
||||
redis = "=0.31.0" # Locked on 0.31 until deadpool-redis updates to 0.32
|
||||
regex = "1.11.1"
|
||||
reqwest = { version = "0.12.20", default-features = false }
|
||||
rgb = "0.8.50"
|
||||
rust_decimal = { version = "1.37.2", features = [
|
||||
"serde-with-float",
|
||||
"serde-with-str",
|
||||
] }
|
||||
rust_iso3166 = "0.1.14"
|
||||
rust-s3 = { version = "0.35.1", default-features = false, features = [
|
||||
"fail-on-err",
|
||||
"tags",
|
||||
"tokio-rustls-tls",
|
||||
] }
|
||||
rusty-money = "0.4.1"
|
||||
sentry = { version = "0.41.0", default-features = false, features = [
|
||||
"backtrace",
|
||||
"contexts",
|
||||
"debug-images",
|
||||
"panic",
|
||||
"reqwest",
|
||||
"rustls",
|
||||
] }
|
||||
sentry-actix = "0.41.0"
|
||||
serde = "1.0.219"
|
||||
serde_bytes = "0.11.17"
|
||||
serde_cbor = "0.11.2"
|
||||
serde_ini = "0.2.0"
|
||||
serde_json = "1.0.140"
|
||||
serde_with = "3.13.0"
|
||||
serde-xml-rs = "0.8.1" # Also an XML (de)serializer, consider dropping yaserde in favor of this
|
||||
sha1 = "0.10.6"
|
||||
sha1_smol = { version = "1.0.1", features = ["std"] }
|
||||
sha2 = "0.10.9"
|
||||
spdx = "0.10.8"
|
||||
sqlx = { version = "0.8.6", default-features = false }
|
||||
sysinfo = { version = "0.35.2", default-features = false }
|
||||
tar = "0.4.44"
|
||||
tauri = "2.6.1"
|
||||
tauri-build = "2.3.0"
|
||||
tauri-plugin-deep-link = "2.4.0"
|
||||
tauri-plugin-dialog = "2.3.0"
|
||||
tauri-plugin-http = "2.5.0"
|
||||
tauri-plugin-opener = "2.4.0"
|
||||
tauri-plugin-os = "2.3.0"
|
||||
tauri-plugin-single-instance = "2.3.0"
|
||||
tauri-plugin-updater = { version = "2.9.0", default-features = false, features = [
|
||||
"rustls-tls",
|
||||
"zip",
|
||||
] }
|
||||
tauri-plugin-window-state = "2.3.0"
|
||||
tempfile = "3.20.0"
|
||||
theseus = { path = "packages/app-lib" }
|
||||
thiserror = "2.0.12"
|
||||
tikv-jemalloc-ctl = "0.6.0"
|
||||
tikv-jemallocator = "0.6.0"
|
||||
tokio = "1.45.1"
|
||||
tokio-stream = "0.1.17"
|
||||
tokio-util = "0.7.15"
|
||||
totp-rs = "5.7.0"
|
||||
tracing = "0.1.41"
|
||||
tracing-actix-web = "0.7.18"
|
||||
tracing-error = "0.2.1"
|
||||
tracing-subscriber = "0.3.19"
|
||||
url = "2.5.4"
|
||||
urlencoding = "2.1.3"
|
||||
uuid = "1.17.0"
|
||||
validator = "0.20.0"
|
||||
webp = { version = "0.3.0", default-features = false }
|
||||
whoami = "1.6.0"
|
||||
winreg = "0.55.0"
|
||||
woothee = "0.13.0"
|
||||
yaserde = "0.12.0"
|
||||
zip = { version = "4.2.0", default-features = false, features = [
|
||||
"bzip2",
|
||||
"deflate",
|
||||
"deflate64",
|
||||
"zstd",
|
||||
] }
|
||||
zxcvbn = "3.1.0"
|
||||
|
||||
[workspace.lints.clippy]
|
||||
bool_to_int_with_if = "warn"
|
||||
borrow_as_ptr = "warn"
|
||||
cfg_not_test = "warn"
|
||||
clear_with_drain = "warn"
|
||||
cloned_instead_of_copied = "warn"
|
||||
collection_is_never_read = "warn"
|
||||
dbg_macro = "warn"
|
||||
default_trait_access = "warn"
|
||||
explicit_iter_loop = "warn"
|
||||
filter_map_next = "warn"
|
||||
flat_map_option = "warn"
|
||||
format_push_string = "warn"
|
||||
get_unwrap = "warn"
|
||||
large_include_file = "warn"
|
||||
large_stack_arrays = "warn"
|
||||
manual_assert = "warn"
|
||||
manual_instant_elapsed = "warn"
|
||||
manual_is_variant_and = "warn"
|
||||
manual_let_else = "warn"
|
||||
map_unwrap_or = "warn"
|
||||
match_bool = "warn"
|
||||
needless_collect = "warn"
|
||||
negative_feature_names = "warn"
|
||||
non_std_lazy_statics = "warn"
|
||||
pathbuf_init_then_push = "warn"
|
||||
read_zero_byte_vec = "warn"
|
||||
redundant_clone = "warn"
|
||||
redundant_feature_names = "warn"
|
||||
redundant_type_annotations = "warn"
|
||||
todo = "warn"
|
||||
unnested_or_patterns = "warn"
|
||||
wildcard_dependencies = "warn"
|
||||
|
||||
[workspace.lints.rust]
|
||||
# Turn warnings into errors by default
|
||||
warnings = "deny"
|
||||
|
||||
[patch.crates-io]
|
||||
wry = { git = "https://github.com/modrinth/wry", rev = "21db186" }
|
||||
|
||||
# Optimize for speed and reduce size on release builds
|
||||
[profile.release]
|
||||
panic = "abort" # Strip expensive panic clean-up logic
|
||||
codegen-units = 1 # Compile crates one after another so the compiler can optimize better
|
||||
lto = true # Enables link to optimizations
|
||||
opt-level = "s" # Optimize for binary size
|
||||
strip = true # Remove debug symbols
|
||||
opt-level = "s" # Optimize for binary size
|
||||
strip = true # Remove debug symbols
|
||||
lto = true # Enables link to optimizations
|
||||
panic = "abort" # Strip expensive panic clean-up logic
|
||||
codegen-units = 1 # Compile crates one after another so the compiler can optimize better
|
||||
|
||||
[profile.dev.package.sqlx-macros]
|
||||
opt-level = 3
|
||||
|
||||
44
README.md
@ -1,9 +1,39 @@
|
||||
# theseus
|
||||
A game launcher which can be used as a CLI, GUI, and a library for creating and playing modrinth projects
|
||||
# 
|
||||
|
||||
Theseus aims to provide three components:
|
||||
- A library (theseus)
|
||||
- A CLI (theseus-cli)
|
||||
- A GUI (theseus-gui)
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
Feel free to contribute!
|
||||
## Modrinth Monorepo
|
||||
|
||||
Welcome to the Modrinth Monorepo, the primary codebase for the Modrinth web interface and app. It contains  lines of code and has  contributors!
|
||||
|
||||
If you're not a developer and you've stumbled upon this repository, you can access the web interface on the [Modrinth website](https://modrinth.com) and download the latest release of the app [here](https://modrinth.com/app).
|
||||
|
||||
## Development
|
||||
|
||||
This repository contains two primary packages. For detailed development information, please refer to their respective READMEs:
|
||||
|
||||
- [Web Interface](apps/frontend/README.md)
|
||||
- [Desktop App](apps/app/README.md)
|
||||
|
||||
## Contributing
|
||||
|
||||
We welcome contributions! Before submitting any contributions, please read our [contributing guidelines](https://docs.modrinth.com/contributing/getting-started/).
|
||||
|
||||
If you plan to fork this repository for your own purposes, please review our [copying guidelines](COPYING.md).
|
||||
|
||||
## Security
|
||||
|
||||
If you discover a security vulnerability within our codebase, please follow our [responsible disclosure guidelines](https://modrinth.com/legal/security).
|
||||
|
||||
## Support
|
||||
|
||||
If you need help with the Modrinth web interface or app, please visit our [support page](https://support.modrinth.com). For general inquiries, you can also join our [Discord server](https://discord.modrinth.com).
|
||||
|
||||
## License
|
||||
|
||||
All packages in this repository are licensed under their respective licenses. Refer to the LICENSE file in each package for more information.
|
||||
|
||||
2
apps/app-frontend/.prettierignore
Normal file
@ -0,0 +1,2 @@
|
||||
**/dist
|
||||
*.gltf
|
||||
13
apps/app-frontend/COPYING.md
Normal file
@ -0,0 +1,13 @@
|
||||
# Copying
|
||||
|
||||
The source code of the theseus repository is licensed under the GNU General Public License, Version 3 only, which is provided in the file [LICENSE](./LICENSE). However, some files listed below are licensed under a different license.
|
||||
|
||||
## Modrinth logo
|
||||
|
||||
The use of Modrinth branding elements, including but not limited to the wrench-in-labyrinth logo, the landing image, and any variations thereof, is strictly prohibited without explicit written permission from Rinth, Inc. This includes trademarks, logos, or other branding elements.
|
||||
|
||||
> All rights reserved. © 2020-2023 Rinth, Inc.
|
||||
|
||||
This includes, but may not be limited to, the following files:
|
||||
|
||||
- theseus_gui/src-tauri/icons/\*
|
||||
22
apps/app-frontend/eslint.config.mjs
Normal file
@ -0,0 +1,22 @@
|
||||
import { createConfigForNuxt } from '@nuxt/eslint-config/flat'
|
||||
import { fixupPluginRules } from '@eslint/compat'
|
||||
import turboPlugin from 'eslint-plugin-turbo'
|
||||
|
||||
export default createConfigForNuxt().append([
|
||||
{
|
||||
name: 'turbo',
|
||||
plugins: {
|
||||
turbo: fixupPluginRules(turboPlugin),
|
||||
},
|
||||
rules: {
|
||||
'turbo/no-undeclared-env-vars': 'error',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'modrinth',
|
||||
rules: {
|
||||
'vue/html-self-closing': 'off',
|
||||
'vue/multi-word-component-names': 'off',
|
||||
},
|
||||
},
|
||||
])
|
||||
@ -1,10 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<!doctype html>
|
||||
<html lang="en" class="dark-mode">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Modrinth App</title>
|
||||
|
||||
<link rel="stylesheet" href="/src/assets/stylesheets/global.scss" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
64
apps/app-frontend/package.json
Normal file
@ -0,0 +1,64 @@
|
||||
{
|
||||
"name": "@modrinth/app-frontend",
|
||||
"private": true,
|
||||
"version": "1.0.0-local",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vue-tsc --noEmit && vite build",
|
||||
"tsc:check": "vue-tsc --noEmit",
|
||||
"lint": "eslint . && prettier --check .",
|
||||
"fix": "eslint . --fix && prettier --write .",
|
||||
"intl:extract": "formatjs extract \"src/**/*.{vue,ts,tsx,js,jsx,mts,cts,mjs,cjs}\" --ignore \"**/*.d.ts\" --ignore node_modules --out-file src/locales/en-US/index.json --format crowdin --preserve-whitespace",
|
||||
"test": "vue-tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@geometrically/minecraft-motd-parser": "^1.1.4",
|
||||
"@modrinth/assets": "workspace:*",
|
||||
"@modrinth/ui": "workspace:*",
|
||||
"@modrinth/utils": "workspace:*",
|
||||
"@sentry/vue": "^8.27.0",
|
||||
"@tauri-apps/api": "^2.5.0",
|
||||
"@tauri-apps/plugin-dialog": "^2.2.1",
|
||||
"@tauri-apps/plugin-http": "^2.5.0",
|
||||
"@tauri-apps/plugin-opener": "^2.2.6",
|
||||
"@tauri-apps/plugin-os": "^2.2.1",
|
||||
"@tauri-apps/plugin-updater": "^2.7.1",
|
||||
"@tauri-apps/plugin-window-state": "^2.2.2",
|
||||
"@types/three": "^0.172.0",
|
||||
"@vintl/vintl": "^4.4.1",
|
||||
"@vueuse/core": "^11.1.0",
|
||||
"dayjs": "^1.11.10",
|
||||
"floating-vue": "^5.2.2",
|
||||
"ofetch": "^1.3.4",
|
||||
"pinia": "^2.1.7",
|
||||
"posthog-js": "^1.158.2",
|
||||
"three": "^0.172.0",
|
||||
"vite-svg-loader": "^5.1.0",
|
||||
"vue": "^3.5.13",
|
||||
"vue-multiselect": "3.0.0",
|
||||
"vue-router": "4.3.0",
|
||||
"vue-virtual-scroller": "v2.0.0-beta.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/compat": "^1.1.1",
|
||||
"@formatjs/cli": "^6.2.12",
|
||||
"@nuxt/eslint-config": "^0.5.6",
|
||||
"@taijased/vue-render-tracker": "^1.0.7",
|
||||
"@vitejs/plugin-vue": "^5.0.4",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"eslint": "^9.9.1",
|
||||
"eslint-config-custom": "workspace:*",
|
||||
"eslint-plugin-turbo": "^2.5.4",
|
||||
"postcss": "^8.4.39",
|
||||
"prettier": "^3.2.5",
|
||||
"sass": "^1.74.1",
|
||||
"tailwindcss": "^3.4.4",
|
||||
"tsconfig": "workspace:*",
|
||||
"typescript": "^5.5.4",
|
||||
"vite": "^5.4.6",
|
||||
"vue-tsc": "^2.1.6"
|
||||
},
|
||||
"packageManager": "pnpm@9.4.0",
|
||||
"web-types": "../../web-types.json"
|
||||
}
|
||||
6
apps/app-frontend/postcss.config.js
Normal file
@ -0,0 +1,6 @@
|
||||
export default {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
891
apps/app-frontend/src/App.vue
Normal file
@ -0,0 +1,891 @@
|
||||
<script setup>
|
||||
import { computed, onMounted, onUnmounted, ref, watch, provide } from 'vue'
|
||||
import { RouterView, useRoute, useRouter } from 'vue-router'
|
||||
import {
|
||||
ArrowBigUpDashIcon,
|
||||
ChangeSkinIcon,
|
||||
CompassIcon,
|
||||
DownloadIcon,
|
||||
HomeIcon,
|
||||
LeftArrowIcon,
|
||||
LibraryIcon,
|
||||
LogInIcon,
|
||||
LogOutIcon,
|
||||
MaximizeIcon,
|
||||
MinimizeIcon,
|
||||
PlusIcon,
|
||||
RestoreIcon,
|
||||
RightArrowIcon,
|
||||
SettingsIcon,
|
||||
WorldIcon,
|
||||
XIcon,
|
||||
NewspaperIcon,
|
||||
} from '@modrinth/assets'
|
||||
import {
|
||||
Avatar,
|
||||
Button,
|
||||
ButtonStyled,
|
||||
Notifications,
|
||||
OverflowMenu,
|
||||
NewsArticleCard,
|
||||
} from '@modrinth/ui'
|
||||
import { useLoading, useTheming } from '@/store/state'
|
||||
import ModrinthAppLogo from '@/assets/modrinth_app.svg?component'
|
||||
import AccountsCard from '@/components/ui/AccountsCard.vue'
|
||||
import InstanceCreationModal from '@/components/ui/InstanceCreationModal.vue'
|
||||
import { get } from '@/helpers/settings.ts'
|
||||
import Breadcrumbs from '@/components/ui/Breadcrumbs.vue'
|
||||
import RunningAppBar from '@/components/ui/RunningAppBar.vue'
|
||||
import SplashScreen from '@/components/ui/SplashScreen.vue'
|
||||
import ErrorModal from '@/components/ui/ErrorModal.vue'
|
||||
import ModrinthLoadingIndicator from '@/components/LoadingIndicatorBar.vue'
|
||||
import { handleError, useNotifications } from '@/store/notifications.js'
|
||||
import { command_listener, warning_listener } from '@/helpers/events.js'
|
||||
import { type } from '@tauri-apps/plugin-os'
|
||||
import { getOS, isDev, restartApp } from '@/helpers/utils.js'
|
||||
import { debugAnalytics, initAnalytics, optOutAnalytics, trackEvent } from '@/helpers/analytics'
|
||||
import { getCurrentWindow } from '@tauri-apps/api/window'
|
||||
import { getVersion } from '@tauri-apps/api/app'
|
||||
import URLConfirmModal from '@/components/ui/URLConfirmModal.vue'
|
||||
import { create_profile_and_install_from_file } from './helpers/pack'
|
||||
import { useError } from '@/store/error.js'
|
||||
import { useCheckDisableMouseover } from '@/composables/macCssFix.js'
|
||||
import ModInstallModal from '@/components/ui/install_flow/ModInstallModal.vue'
|
||||
import IncompatibilityWarningModal from '@/components/ui/install_flow/IncompatibilityWarningModal.vue'
|
||||
import InstallConfirmModal from '@/components/ui/install_flow/InstallConfirmModal.vue'
|
||||
import { useInstall } from '@/store/install.js'
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
import { get_opening_command, initialize_state } from '@/helpers/state'
|
||||
import { saveWindowState, StateFlags } from '@tauri-apps/plugin-window-state'
|
||||
import { renderString } from '@modrinth/utils'
|
||||
import { useFetch } from '@/helpers/fetch.js'
|
||||
import { check } from '@tauri-apps/plugin-updater'
|
||||
import NavButton from '@/components/ui/NavButton.vue'
|
||||
import { cancelLogin, get as getCreds, login, logout } from '@/helpers/mr_auth.js'
|
||||
import { get_user } from '@/helpers/cache.js'
|
||||
import AppSettingsModal from '@/components/ui/modal/AppSettingsModal.vue'
|
||||
import AuthGrantFlowWaitModal from '@/components/ui/modal/AuthGrantFlowWaitModal.vue'
|
||||
import PromotionWrapper from '@/components/ui/PromotionWrapper.vue'
|
||||
import { hide_ads_window, init_ads_window } from '@/helpers/ads.js'
|
||||
import FriendsList from '@/components/ui/friends/FriendsList.vue'
|
||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||
import QuickInstanceSwitcher from '@/components/ui/QuickInstanceSwitcher.vue'
|
||||
import { get_available_capes, get_available_skins } from './helpers/skins'
|
||||
import { generateSkinPreviews } from './helpers/rendering/batch-skin-renderer'
|
||||
|
||||
const themeStore = useTheming()
|
||||
|
||||
const news = ref([])
|
||||
|
||||
const urlModal = ref(null)
|
||||
|
||||
const offline = ref(!navigator.onLine)
|
||||
window.addEventListener('offline', () => {
|
||||
offline.value = true
|
||||
})
|
||||
window.addEventListener('online', () => {
|
||||
offline.value = false
|
||||
})
|
||||
|
||||
const showOnboarding = ref(false)
|
||||
const nativeDecorations = ref(false)
|
||||
|
||||
const os = ref('')
|
||||
|
||||
const stateInitialized = ref(false)
|
||||
|
||||
const criticalErrorMessage = ref()
|
||||
|
||||
const isMaximized = ref(false)
|
||||
|
||||
onMounted(async () => {
|
||||
await useCheckDisableMouseover()
|
||||
|
||||
document.querySelector('body').addEventListener('click', handleClick)
|
||||
document.querySelector('body').addEventListener('auxclick', handleAuxClick)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
document.querySelector('body').removeEventListener('click', handleClick)
|
||||
document.querySelector('body').removeEventListener('auxclick', handleAuxClick)
|
||||
})
|
||||
|
||||
async function setupApp() {
|
||||
stateInitialized.value = true
|
||||
const {
|
||||
native_decorations,
|
||||
theme,
|
||||
telemetry,
|
||||
collapsed_navigation,
|
||||
advanced_rendering,
|
||||
onboarded,
|
||||
default_page,
|
||||
toggle_sidebar,
|
||||
developer_mode,
|
||||
feature_flags,
|
||||
} = await get()
|
||||
|
||||
if (default_page === 'Library') {
|
||||
await router.push('/library')
|
||||
}
|
||||
|
||||
os.value = await getOS()
|
||||
const dev = await isDev()
|
||||
const version = await getVersion()
|
||||
showOnboarding.value = !onboarded
|
||||
|
||||
nativeDecorations.value = native_decorations
|
||||
if (os.value !== 'MacOS') await getCurrentWindow().setDecorations(native_decorations)
|
||||
|
||||
themeStore.setThemeState(theme)
|
||||
themeStore.collapsedNavigation = collapsed_navigation
|
||||
themeStore.advancedRendering = advanced_rendering
|
||||
themeStore.toggleSidebar = toggle_sidebar
|
||||
themeStore.devMode = developer_mode
|
||||
themeStore.featureFlags = feature_flags
|
||||
|
||||
isMaximized.value = await getCurrentWindow().isMaximized()
|
||||
|
||||
await getCurrentWindow().onResized(async () => {
|
||||
isMaximized.value = await getCurrentWindow().isMaximized()
|
||||
})
|
||||
|
||||
initAnalytics()
|
||||
if (!telemetry) {
|
||||
optOutAnalytics()
|
||||
}
|
||||
if (dev) debugAnalytics()
|
||||
trackEvent('Launched', { version, dev, onboarded })
|
||||
|
||||
if (!dev) document.addEventListener('contextmenu', (event) => event.preventDefault())
|
||||
|
||||
const osType = await type()
|
||||
if (osType === 'macos') {
|
||||
document.getElementsByTagName('html')[0].classList.add('mac')
|
||||
} else {
|
||||
document.getElementsByTagName('html')[0].classList.add('windows')
|
||||
}
|
||||
|
||||
await warning_listener((e) =>
|
||||
notificationsWrapper.value.addNotification({
|
||||
title: 'Warning',
|
||||
text: e.message,
|
||||
type: 'warn',
|
||||
}),
|
||||
)
|
||||
|
||||
useFetch(
|
||||
`https://api.modrinth.com/appCriticalAnnouncement.json?version=${version}`,
|
||||
'criticalAnnouncements',
|
||||
true,
|
||||
)
|
||||
.then((response) => response.json())
|
||||
.then((res) => {
|
||||
if (res && res.header && res.body) {
|
||||
criticalErrorMessage.value = res
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
console.log(
|
||||
`No critical announcement found at https://api.modrinth.com/appCriticalAnnouncement.json?version=${version}`,
|
||||
)
|
||||
})
|
||||
|
||||
useFetch(`https://modrinth.com/news/feed/articles.json`, 'news', true)
|
||||
.then((response) => response.json())
|
||||
.then((res) => {
|
||||
if (res && res.articles) {
|
||||
// Format expected by NewsArticleCard component.
|
||||
news.value = res.articles
|
||||
.map((article) => ({
|
||||
...article,
|
||||
path: article.link,
|
||||
thumbnail: article.thumbnail,
|
||||
title: article.title,
|
||||
summary: article.summary,
|
||||
date: article.date,
|
||||
}))
|
||||
.slice(0, 4)
|
||||
}
|
||||
})
|
||||
|
||||
get_opening_command().then(handleCommand)
|
||||
checkUpdates()
|
||||
fetchCredentials()
|
||||
|
||||
try {
|
||||
const skins = (await get_available_skins()) ?? []
|
||||
const capes = (await get_available_capes()) ?? []
|
||||
generateSkinPreviews(skins, capes)
|
||||
} catch (error) {
|
||||
console.warn('Failed to generate skin previews in app setup.', error)
|
||||
}
|
||||
}
|
||||
|
||||
const stateFailed = ref(false)
|
||||
initialize_state()
|
||||
.then(() => {
|
||||
setupApp().catch((err) => {
|
||||
stateFailed.value = true
|
||||
console.error(err)
|
||||
error.showError(err, null, false, 'state_init')
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
stateFailed.value = true
|
||||
console.error('Failed to initialize app', err)
|
||||
error.showError(err, null, false, 'state_init')
|
||||
})
|
||||
|
||||
const handleClose = async () => {
|
||||
await saveWindowState(StateFlags.ALL)
|
||||
await getCurrentWindow().close()
|
||||
}
|
||||
|
||||
const router = useRouter()
|
||||
router.afterEach((to, from, failure) => {
|
||||
trackEvent('PageView', { path: to.path, fromPath: from.path, failed: failure })
|
||||
})
|
||||
const route = useRoute()
|
||||
|
||||
const loading = useLoading()
|
||||
loading.setEnabled(false)
|
||||
|
||||
const notifications = useNotifications()
|
||||
const notificationsWrapper = ref()
|
||||
|
||||
const error = useError()
|
||||
const errorModal = ref()
|
||||
|
||||
const install = useInstall()
|
||||
const modInstallModal = ref()
|
||||
const installConfirmModal = ref()
|
||||
const incompatibilityWarningModal = ref()
|
||||
|
||||
const credentials = ref()
|
||||
|
||||
const modrinthLoginFlowWaitModal = ref()
|
||||
|
||||
async function fetchCredentials() {
|
||||
const creds = await getCreds().catch(handleError)
|
||||
if (creds && creds.user_id) {
|
||||
creds.user = await get_user(creds.user_id).catch(handleError)
|
||||
}
|
||||
credentials.value = creds
|
||||
}
|
||||
|
||||
async function signIn() {
|
||||
modrinthLoginFlowWaitModal.value.show()
|
||||
|
||||
try {
|
||||
await login()
|
||||
await fetchCredentials()
|
||||
} catch (error) {
|
||||
if (
|
||||
typeof error === 'object' &&
|
||||
typeof error['message'] === 'string' &&
|
||||
error.message.includes('Login canceled')
|
||||
) {
|
||||
// Not really an error due to being a result of user interaction, show nothing
|
||||
} else {
|
||||
handleError(error)
|
||||
}
|
||||
} finally {
|
||||
modrinthLoginFlowWaitModal.value.hide()
|
||||
}
|
||||
}
|
||||
|
||||
async function logOut() {
|
||||
await logout().catch(handleError)
|
||||
await fetchCredentials()
|
||||
}
|
||||
|
||||
const MIDAS_BITFLAG = 1 << 0
|
||||
const hasPlus = computed(
|
||||
() =>
|
||||
credentials.value &&
|
||||
credentials.value.user &&
|
||||
(credentials.value.user.badges & MIDAS_BITFLAG) === MIDAS_BITFLAG,
|
||||
)
|
||||
|
||||
const sidebarToggled = ref(true)
|
||||
|
||||
themeStore.$subscribe(() => {
|
||||
sidebarToggled.value = !themeStore.toggleSidebar
|
||||
})
|
||||
|
||||
const forceSidebar = computed(
|
||||
() => route.path.startsWith('/browse') || route.path.startsWith('/project'),
|
||||
)
|
||||
const sidebarVisible = computed(() => sidebarToggled.value || forceSidebar.value)
|
||||
const showAd = computed(() => !(!sidebarVisible.value || hasPlus.value))
|
||||
|
||||
watch(
|
||||
showAd,
|
||||
() => {
|
||||
if (!showAd.value) {
|
||||
hide_ads_window(true)
|
||||
} else {
|
||||
init_ads_window(true)
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
invoke('show_window')
|
||||
|
||||
notifications.setNotifs(notificationsWrapper.value)
|
||||
|
||||
error.setErrorModal(errorModal.value)
|
||||
|
||||
install.setIncompatibilityWarningModal(incompatibilityWarningModal)
|
||||
install.setInstallConfirmModal(installConfirmModal)
|
||||
install.setModInstallModal(modInstallModal)
|
||||
})
|
||||
|
||||
const accounts = ref(null)
|
||||
provide('accountsCard', accounts)
|
||||
|
||||
command_listener(handleCommand)
|
||||
async function handleCommand(e) {
|
||||
if (!e) return
|
||||
|
||||
if (e.event === 'RunMRPack') {
|
||||
// RunMRPack should directly install a local mrpack given a path
|
||||
if (e.path.endsWith('.mrpack')) {
|
||||
await create_profile_and_install_from_file(e.path).catch(handleError)
|
||||
trackEvent('InstanceCreate', {
|
||||
source: 'CreationModalFileDrop',
|
||||
})
|
||||
}
|
||||
} else {
|
||||
// Other commands are URL-based (deep linking)
|
||||
urlModal.value.show(e)
|
||||
}
|
||||
}
|
||||
|
||||
const updateAvailable = ref(false)
|
||||
async function checkUpdates() {
|
||||
const update = await check()
|
||||
updateAvailable.value = !!update
|
||||
|
||||
setTimeout(
|
||||
() => {
|
||||
checkUpdates()
|
||||
},
|
||||
5 * 1000 * 60,
|
||||
)
|
||||
}
|
||||
|
||||
function handleClick(e) {
|
||||
let target = e.target
|
||||
while (target != null) {
|
||||
if (target.matches('a')) {
|
||||
if (
|
||||
target.href &&
|
||||
['http://', 'https://', 'mailto:', 'tel:'].some((v) => target.href.startsWith(v)) &&
|
||||
!target.classList.contains('router-link-active') &&
|
||||
!target.href.startsWith('http://localhost') &&
|
||||
!target.href.startsWith('https://tauri.localhost') &&
|
||||
!target.href.startsWith('http://tauri.localhost')
|
||||
) {
|
||||
openUrl(target.href)
|
||||
}
|
||||
e.preventDefault()
|
||||
break
|
||||
}
|
||||
target = target.parentElement
|
||||
}
|
||||
}
|
||||
|
||||
function handleAuxClick(e) {
|
||||
// disables middle click -> new tab
|
||||
if (e.button === 1) {
|
||||
e.preventDefault()
|
||||
// instead do a left click
|
||||
const event = new MouseEvent('click', {
|
||||
view: window,
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
})
|
||||
e.target.dispatchEvent(event)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<SplashScreen v-if="!stateFailed" ref="splashScreen" data-tauri-drag-region />
|
||||
<div id="teleports"></div>
|
||||
<div v-if="stateInitialized" class="app-grid-layout experimental-styles-within relative">
|
||||
<Suspense>
|
||||
<AppSettingsModal ref="settingsModal" />
|
||||
</Suspense>
|
||||
<Suspense>
|
||||
<AuthGrantFlowWaitModal ref="modrinthLoginFlowWaitModal" @flow-cancel="cancelLogin" />
|
||||
</Suspense>
|
||||
<Suspense>
|
||||
<InstanceCreationModal ref="installationModal" />
|
||||
</Suspense>
|
||||
<div
|
||||
class="app-grid-navbar bg-bg-raised flex flex-col p-[0.5rem] pt-0 gap-[0.5rem] w-[--left-bar-width]"
|
||||
>
|
||||
<NavButton v-tooltip.right="'Home'" to="/">
|
||||
<HomeIcon />
|
||||
</NavButton>
|
||||
<NavButton v-if="themeStore.featureFlags.worlds_tab" v-tooltip.right="'Worlds'" to="/worlds">
|
||||
<WorldIcon />
|
||||
</NavButton>
|
||||
<NavButton
|
||||
v-tooltip.right="'Discover content'"
|
||||
to="/browse/modpack"
|
||||
:is-primary="() => route.path.startsWith('/browse') && !route.query.i"
|
||||
:is-subpage="(route) => route.path.startsWith('/project') && !route.query.i"
|
||||
>
|
||||
<CompassIcon />
|
||||
</NavButton>
|
||||
<NavButton v-tooltip.right="'Skins (Beta)'" to="/skins">
|
||||
<ChangeSkinIcon />
|
||||
</NavButton>
|
||||
<NavButton
|
||||
v-tooltip.right="'Library'"
|
||||
to="/library"
|
||||
:is-subpage="
|
||||
() =>
|
||||
route.path.startsWith('/instance') ||
|
||||
((route.path.startsWith('/browse') || route.path.startsWith('/project')) &&
|
||||
route.query.i)
|
||||
"
|
||||
>
|
||||
<LibraryIcon />
|
||||
</NavButton>
|
||||
<div class="h-px w-6 mx-auto my-2 bg-button-bg"></div>
|
||||
<suspense>
|
||||
<QuickInstanceSwitcher />
|
||||
</suspense>
|
||||
<NavButton
|
||||
v-tooltip.right="'Create new instance'"
|
||||
:to="() => $refs.installationModal.show()"
|
||||
:disabled="offline"
|
||||
>
|
||||
<PlusIcon />
|
||||
</NavButton>
|
||||
<div class="flex flex-grow"></div>
|
||||
<NavButton v-if="updateAvailable" v-tooltip.right="'Install update'" :to="() => restartApp()">
|
||||
<DownloadIcon />
|
||||
</NavButton>
|
||||
<NavButton v-tooltip.right="'Settings'" :to="() => $refs.settingsModal.show()">
|
||||
<SettingsIcon />
|
||||
</NavButton>
|
||||
<ButtonStyled v-if="credentials" type="transparent" circular>
|
||||
<OverflowMenu
|
||||
:options="[
|
||||
{
|
||||
id: 'sign-out',
|
||||
action: () => logOut(),
|
||||
color: 'danger',
|
||||
},
|
||||
]"
|
||||
direction="left"
|
||||
>
|
||||
<Avatar
|
||||
:src="credentials.user.avatar_url"
|
||||
:alt="credentials.user.username"
|
||||
size="32px"
|
||||
circle
|
||||
/>
|
||||
<template #sign-out> <LogOutIcon /> Sign out </template>
|
||||
</OverflowMenu>
|
||||
</ButtonStyled>
|
||||
<NavButton v-else v-tooltip.right="'Sign in'" :to="() => signIn()">
|
||||
<LogInIcon />
|
||||
<template #label>Sign in</template>
|
||||
</NavButton>
|
||||
</div>
|
||||
<div data-tauri-drag-region class="app-grid-statusbar bg-bg-raised h-[--top-bar-height] flex">
|
||||
<div data-tauri-drag-region class="flex p-3">
|
||||
<ModrinthAppLogo class="h-full w-auto text-contrast pointer-events-none" />
|
||||
<div class="flex items-center gap-1 ml-3">
|
||||
<button
|
||||
class="cursor-pointer p-0 m-0 text-contrast border-none outline-none bg-button-bg rounded-full flex items-center justify-center w-6 h-6 hover:brightness-75 transition-all"
|
||||
@click="router.back()"
|
||||
>
|
||||
<LeftArrowIcon />
|
||||
</button>
|
||||
<button
|
||||
class="cursor-pointer p-0 m-0 text-contrast border-none outline-none bg-button-bg rounded-full flex items-center justify-center w-6 h-6 hover:brightness-75 transition-all"
|
||||
@click="router.forward()"
|
||||
>
|
||||
<RightArrowIcon />
|
||||
</button>
|
||||
</div>
|
||||
<Breadcrumbs class="pt-[2px]" />
|
||||
</div>
|
||||
<section class="flex ml-auto items-center">
|
||||
<ButtonStyled
|
||||
v-if="!forceSidebar && themeStore.toggleSidebar"
|
||||
:type="sidebarToggled ? 'standard' : 'transparent'"
|
||||
circular
|
||||
>
|
||||
<button
|
||||
class="mr-3 transition-transform"
|
||||
:class="{ 'rotate-180': !sidebarToggled }"
|
||||
@click="sidebarToggled = !sidebarToggled"
|
||||
>
|
||||
<RightArrowIcon />
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<div class="flex mr-3">
|
||||
<Suspense>
|
||||
<RunningAppBar />
|
||||
</Suspense>
|
||||
</div>
|
||||
<section v-if="!nativeDecorations" class="window-controls" data-tauri-drag-region-exclude>
|
||||
<Button class="titlebar-button" icon-only @click="() => getCurrentWindow().minimize()">
|
||||
<MinimizeIcon />
|
||||
</Button>
|
||||
<Button
|
||||
class="titlebar-button"
|
||||
icon-only
|
||||
@click="() => getCurrentWindow().toggleMaximize()"
|
||||
>
|
||||
<RestoreIcon v-if="isMaximized" />
|
||||
<MaximizeIcon v-else />
|
||||
</Button>
|
||||
<Button class="titlebar-button close" icon-only @click="handleClose">
|
||||
<XIcon />
|
||||
</Button>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="stateInitialized"
|
||||
class="app-contents experimental-styles-within"
|
||||
:class="{ 'sidebar-enabled': sidebarVisible }"
|
||||
>
|
||||
<div class="app-viewport flex-grow router-view">
|
||||
<div
|
||||
class="loading-indicator-container h-8 fixed z-50"
|
||||
:style="{
|
||||
top: 'calc(var(--top-bar-height))',
|
||||
left: 'calc(var(--left-bar-width))',
|
||||
width: 'calc(100% - var(--left-bar-width) - var(--right-bar-width))',
|
||||
}"
|
||||
>
|
||||
<ModrinthLoadingIndicator />
|
||||
</div>
|
||||
<div
|
||||
v-if="themeStore.featureFlags.page_path"
|
||||
class="absolute bottom-0 left-0 m-2 bg-tooltip-bg text-tooltip-text font-semibold rounded-full px-2 py-1 text-xs z-50"
|
||||
>
|
||||
{{ route.fullPath }}
|
||||
</div>
|
||||
<div
|
||||
id="background-teleport-target"
|
||||
class="absolute h-full -z-10 rounded-tl-[--radius-xl] overflow-hidden"
|
||||
:style="{
|
||||
width: 'calc(100% - var(--right-bar-width))',
|
||||
}"
|
||||
></div>
|
||||
<div
|
||||
v-if="criticalErrorMessage"
|
||||
class="m-6 mb-0 flex flex-col border-red bg-bg-red rounded-2xl border-2 border-solid p-4 gap-1 font-semibold text-contrast"
|
||||
>
|
||||
<h1 class="m-0 text-lg font-extrabold">{{ criticalErrorMessage.header }}</h1>
|
||||
<div
|
||||
class="markdown-body text-primary"
|
||||
v-html="renderString(criticalErrorMessage.body ?? '')"
|
||||
></div>
|
||||
</div>
|
||||
<RouterView v-slot="{ Component }">
|
||||
<template v-if="Component">
|
||||
<Suspense @pending="loading.startLoading()" @resolve="loading.stopLoading()">
|
||||
<component :is="Component"></component>
|
||||
</Suspense>
|
||||
</template>
|
||||
</RouterView>
|
||||
</div>
|
||||
<div
|
||||
class="app-sidebar mt-px shrink-0 flex flex-col border-0 border-l-[1px] border-[--brand-gradient-border] border-solid overflow-auto"
|
||||
:class="{ 'has-plus': hasPlus }"
|
||||
>
|
||||
<div
|
||||
class="app-sidebar-scrollable flex-grow shrink overflow-y-auto relative"
|
||||
:class="{ 'pb-12': !hasPlus }"
|
||||
>
|
||||
<div id="sidebar-teleport-target" class="sidebar-teleport-content"></div>
|
||||
<div class="sidebar-default-content" :class="{ 'sidebar-enabled': sidebarVisible }">
|
||||
<div class="p-4 border-0 border-b-[1px] border-[--brand-gradient-border] border-solid">
|
||||
<h3 class="text-lg m-0">Playing as</h3>
|
||||
<suspense>
|
||||
<AccountsCard ref="accounts" mode="small" />
|
||||
</suspense>
|
||||
</div>
|
||||
<div class="p-4 border-0 border-b-[1px] border-[--brand-gradient-border] border-solid">
|
||||
<suspense>
|
||||
<FriendsList :credentials="credentials" :sign-in="() => signIn()" />
|
||||
</suspense>
|
||||
</div>
|
||||
<div v-if="news && news.length > 0" class="pt-4 flex flex-col items-center">
|
||||
<h3 class="px-4 text-lg m-0 text-left w-full">News</h3>
|
||||
<div class="px-4 pt-2 space-y-4 flex flex-col items-center w-full">
|
||||
<NewsArticleCard
|
||||
v-for="(item, index) in news"
|
||||
:key="`news-${index}`"
|
||||
:article="item"
|
||||
/>
|
||||
<ButtonStyled color="brand" size="large">
|
||||
<a href="https://modrinth.com/news" target="_blank" class="my-4">
|
||||
<NewspaperIcon /> View all news
|
||||
</a>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="showAd">
|
||||
<a
|
||||
href="https://modrinth.plus?app"
|
||||
class="absolute bottom-[250px] w-full flex justify-center items-center gap-1 px-4 py-3 text-purple font-medium hover:underline z-10"
|
||||
target="_blank"
|
||||
>
|
||||
<ArrowBigUpDashIcon class="text-2xl" /> Upgrade to Modrinth+
|
||||
</a>
|
||||
<PromotionWrapper />
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<URLConfirmModal ref="urlModal" />
|
||||
<Notifications ref="notificationsWrapper" sidebar />
|
||||
<ErrorModal ref="errorModal" />
|
||||
<ModInstallModal ref="modInstallModal" />
|
||||
<IncompatibilityWarningModal ref="incompatibilityWarningModal" />
|
||||
<InstallConfirmModal ref="installConfirmModal" />
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.window-controls {
|
||||
z-index: 20;
|
||||
display: none;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
.titlebar-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: all ease-in-out 0.1s;
|
||||
background-color: transparent;
|
||||
color: var(--color-base);
|
||||
height: 100%;
|
||||
width: 3rem;
|
||||
position: relative;
|
||||
box-shadow: none;
|
||||
|
||||
&:last-child {
|
||||
padding-right: 0.75rem;
|
||||
width: 3.75rem;
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
border-radius: 999999px;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
aspect-ratio: 1 / 1;
|
||||
margin-block: auto;
|
||||
position: absolute;
|
||||
background-color: transparent;
|
||||
scale: 0.9;
|
||||
transition: all ease-in-out 0.2s;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
&.close {
|
||||
&:hover,
|
||||
&:active {
|
||||
color: var(--color-accent-contrast);
|
||||
|
||||
&::before {
|
||||
background-color: var(--color-red);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:active {
|
||||
color: var(--color-contrast);
|
||||
|
||||
&::before {
|
||||
background-color: var(--color-button-bg);
|
||||
scale: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.app-grid-layout,
|
||||
.app-contents {
|
||||
--top-bar-height: 3rem;
|
||||
--left-bar-width: 4rem;
|
||||
--right-bar-width: 300px;
|
||||
}
|
||||
|
||||
.app-grid-layout {
|
||||
display: grid;
|
||||
grid-template: 'status status' 'nav dummy';
|
||||
grid-template-columns: auto 1fr;
|
||||
grid-template-rows: auto 1fr;
|
||||
position: relative;
|
||||
//z-index: 0;
|
||||
background-color: var(--color-raised-bg);
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.app-grid-navbar {
|
||||
grid-area: nav;
|
||||
}
|
||||
|
||||
.app-grid-statusbar {
|
||||
grid-area: status;
|
||||
}
|
||||
|
||||
[data-tauri-drag-region] {
|
||||
-webkit-app-region: drag;
|
||||
}
|
||||
|
||||
[data-tauri-drag-region-exclude] {
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
.app-contents {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
left: var(--left-bar-width);
|
||||
top: var(--top-bar-height);
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: calc(100vh - var(--top-bar-height));
|
||||
background-color: var(--color-bg);
|
||||
border-top-left-radius: var(--radius-xl);
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 0px;
|
||||
// transition: grid-template-columns 0.4s ease-in-out;
|
||||
|
||||
&.sidebar-enabled {
|
||||
grid-template-columns: 1fr 300px;
|
||||
}
|
||||
}
|
||||
|
||||
.loading-indicator-container {
|
||||
border-top-left-radius: var(--radius-xl);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.app-sidebar {
|
||||
overflow: visible;
|
||||
width: 300px;
|
||||
position: relative;
|
||||
height: calc(100vh - var(--top-bar-height));
|
||||
background: var(--brand-gradient-bg);
|
||||
|
||||
--color-button-bg: var(--brand-gradient-button);
|
||||
--color-button-bg-hover: var(--brand-gradient-border);
|
||||
--color-divider: var(--brand-gradient-border);
|
||||
--color-divider-dark: var(--brand-gradient-border);
|
||||
}
|
||||
|
||||
.app-sidebar::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 250px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 5rem;
|
||||
background: var(--brand-gradient-fade-out-color);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.app-sidebar.has-plus::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.app-sidebar::before {
|
||||
content: '';
|
||||
box-shadow: -15px 0 15px -15px rgba(0, 0, 0, 0.2) inset;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: -2rem;
|
||||
width: 2rem;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.app-viewport {
|
||||
flex-grow: 1;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.app-contents::before {
|
||||
z-index: 1;
|
||||
content: '';
|
||||
position: fixed;
|
||||
left: var(--left-bar-width);
|
||||
top: var(--top-bar-height);
|
||||
right: calc(-1 * var(--left-bar-width));
|
||||
bottom: calc(-1 * var(--left-bar-width));
|
||||
border-radius: var(--radius-xl);
|
||||
box-shadow:
|
||||
1px 1px 15px rgba(0, 0, 0, 0.2) inset,
|
||||
inset 1px 1px 1px rgba(255, 255, 255, 0.23);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.sidebar-teleport-content {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
.sidebar-default-content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sidebar-teleport-content:empty + .sidebar-default-content.sidebar-enabled {
|
||||
display: contents;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.mac {
|
||||
.app-grid-statusbar {
|
||||
padding-left: 5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.windows {
|
||||
.fake-appbar {
|
||||
height: 2.5rem !important;
|
||||
}
|
||||
|
||||
.window-controls {
|
||||
display: flex !important;
|
||||
}
|
||||
|
||||
.info-card {
|
||||
right: 8rem;
|
||||
}
|
||||
|
||||
.profile-card {
|
||||
right: 8rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style src="vue-multiselect/dist/vue-multiselect.css"></style>
|
||||
|
Before Width: | Height: | Size: 952 B After Width: | Height: | Size: 952 B |
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
BIN
apps/app-frontend/src/assets/external/gdlauncher.png
vendored
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 901 B After Width: | Height: | Size: 901 B |
|
Before Width: | Height: | Size: 757 B After Width: | Height: | Size: 757 B |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 718 B After Width: | Height: | Size: 718 B |
|
Before Width: | Height: | Size: 962 B After Width: | Height: | Size: 962 B |
|
Before Width: | Height: | Size: 257 B After Width: | Height: | Size: 257 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 415 B After Width: | Height: | Size: 415 B |
|
Before Width: | Height: | Size: 274 B After Width: | Height: | Size: 274 B |
|
Before Width: | Height: | Size: 706 B After Width: | Height: | Size: 706 B |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 924 B After Width: | Height: | Size: 924 B |
|
Before Width: | Height: | Size: 881 B After Width: | Height: | Size: 881 B |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
BIN
apps/app-frontend/src/assets/font/minecraft_font.ttf
Normal file
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 315 B After Width: | Height: | Size: 315 B |
|
Before Width: | Height: | Size: 427 B After Width: | Height: | Size: 427 B |
@ -1,14 +1,9 @@
|
||||
export { default as ServerIcon } from './server.svg'
|
||||
export { default as MinimizeIcon } from './minimize.svg'
|
||||
export { default as MaximizeIcon } from './maximize.svg'
|
||||
export { default as SwapIcon } from './arrow-left-right.svg'
|
||||
export { default as ToggleIcon } from './toggle.svg'
|
||||
export { default as PackageIcon } from './package.svg'
|
||||
export { default as VersionIcon } from './milestone.svg'
|
||||
export { default as MoreIcon } from './more.svg'
|
||||
export { default as TextInputIcon } from './text-cursor-input.svg'
|
||||
export { default as AddProjectImage } from './add-project.svg'
|
||||
export { default as NewInstanceImage } from './new-instance.svg'
|
||||
export { default as MenuIcon } from './menu.svg'
|
||||
export { default as BugIcon } from './bug.svg'
|
||||
export { default as ChatIcon } from './messages-square.svg'
|
||||
|
Before Width: | Height: | Size: 326 B After Width: | Height: | Size: 326 B |
|
Before Width: | Height: | Size: 359 B After Width: | Height: | Size: 359 B |
|
Before Width: | Height: | Size: 322 B After Width: | Height: | Size: 322 B |
|
Before Width: | Height: | Size: 315 B After Width: | Height: | Size: 315 B |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 461 B After Width: | Height: | Size: 461 B |
|
Before Width: | Height: | Size: 405 B After Width: | Height: | Size: 405 B |
|
Before Width: | Height: | Size: 449 B After Width: | Height: | Size: 449 B |
|
Before Width: | Height: | Size: 309 B After Width: | Height: | Size: 309 B |
BIN
apps/app-frontend/src/assets/loading/cube.png
Normal file
|
After Width: | Height: | Size: 270 KiB |
28
apps/app-frontend/src/assets/modrinth_app.svg
Normal file
|
After Width: | Height: | Size: 12 KiB |
24
apps/app-frontend/src/assets/modrinth_servers.svg
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:serif="http://www.serif.com/" version="1.1" viewBox="0 0 1793 199">
|
||||
<g>
|
||||
<g id="Layer_1">
|
||||
<g id="green" fill="var(--color-brand)">
|
||||
<path d="M1184.1,166.6c-8,0-15.6-1-22.9-3.1s-13.1-4.6-17.4-7.6l8.5-16.9c4.3,2.7,9.4,5,15.3,6.8,5.9,1.8,11.9,2.7,17.8,2.7s12.1-.9,15.2-2.8c3.1-1.9,4.7-4.5,4.7-7.7s-1.1-4.6-3.2-6c-2.1-1.4-4.9-2.4-8.4-3.1-3.4-.7-7.3-1.4-11.5-2-4.2-.6-8.4-1.4-12.6-2.4-4.2-1-8-2.5-11.5-4.5-3.4-2-6.2-4.6-8.4-7.9-2.1-3.3-3.2-7.7-3.2-13.2s1.7-11.3,5.2-15.8c3.4-4.5,8.3-7.9,14.5-10.3,6.2-2.4,13.6-3.7,22.2-3.7s12.9.7,19.4,2.1c6.5,1.4,11.9,3.4,16.2,6.1l-8.5,16.9c-4.5-2.7-9.1-4.6-13.6-5.6-4.6-1-9.1-1.5-13.6-1.5-6.8,0-11.8,1-15,3-3.3,2-4.9,4.6-4.9,7.7s1.1,5,3.2,6.4c2.1,1.4,4.9,2.6,8.4,3.4,3.4.8,7.3,1.5,11.5,2,4.2.5,8.4,1.3,12.6,2.4,4.2,1.1,8,2.5,11.5,4.4,3.5,1.8,6.3,4.4,8.5,7.7,2.1,3.3,3.2,7.7,3.2,13s-1.8,11.1-5.3,15.5c-3.5,4.4-8.5,7.8-14.9,10.2-6.4,2.4-14.1,3.7-23,3.7Z"/>
|
||||
<path d="M1291.1,166.6c-10.6,0-19.8-2.1-27.7-6.3-7.9-4.2-14-10-18.3-17.4-4.3-7.4-6.5-15.7-6.5-25.1s2.1-17.9,6.3-25.2c4.2-7.3,10-13,17.5-17.2,7.4-4.2,15.9-6.2,25.4-6.2s17.5,2,24.8,6.1c7.2,4,12.9,9.7,17.1,17.1,4.2,7.4,6.2,16,6.2,26s0,2,0,3.2c0,1.2-.2,2.3-.3,3.4h-79.3v-14.8h67.5l-8.7,4.6c.1-5.5-1-10.3-3.4-14.4-2.4-4.2-5.6-7.4-9.7-9.8-4.1-2.4-8.8-3.6-14.2-3.6s-10.2,1.2-14.3,3.6c-4.1,2.4-7.3,5.7-9.6,9.9-2.3,4.2-3.5,9.2-3.5,14.9v3.6c0,5.7,1.3,10.7,3.9,15.1,2.6,4.4,6.3,7.8,11,10.2,4.7,2.4,10.2,3.6,16.4,3.6s10.2-.8,14.4-2.5c4.3-1.7,8.1-4.3,11.4-7.8l11.9,13.7c-4.3,5-9.6,8.8-16.1,11.5-6.5,2.7-13.9,4-22.2,4Z"/>
|
||||
<path d="M1357.2,165.3v-95.1h21.2v26.2l-2.5-7.7c2.8-6.4,7.3-11.3,13.4-14.6,6.1-3.3,13.7-5,22.9-5v21.2c-1-.2-1.8-.4-2.7-.4-.8,0-1.7,0-2.5,0-8.4,0-15.1,2.5-20.1,7.4-5,4.9-7.5,12.3-7.5,22v46.1h-22.3Z"/>
|
||||
<path d="M1460,165.3l-40.8-95.1h23.2l35.1,83.9h-11.4l36.3-83.9h21.4l-40.8,95.1h-23Z"/>
|
||||
<path d="M1579.6,166.6c-10.6,0-19.8-2.1-27.7-6.3-7.9-4.2-14-10-18.3-17.4-4.3-7.4-6.5-15.7-6.5-25.1s2.1-17.9,6.3-25.2c4.2-7.3,10-13,17.5-17.2,7.4-4.2,15.9-6.2,25.4-6.2s17.5,2,24.8,6.1c7.2,4,12.9,9.7,17.1,17.1,4.2,7.4,6.2,16,6.2,26s0,2,0,3.2c0,1.2-.2,2.3-.3,3.4h-79.3v-14.8h67.5l-8.7,4.6c.1-5.5-1-10.3-3.4-14.4-2.4-4.2-5.6-7.4-9.7-9.8-4.1-2.4-8.8-3.6-14.2-3.6s-10.2,1.2-14.3,3.6c-4.1,2.4-7.3,5.7-9.6,9.9-2.3,4.2-3.5,9.2-3.5,14.9v3.6c0,5.7,1.3,10.7,3.9,15.1,2.6,4.4,6.3,7.8,11,10.2,4.7,2.4,10.2,3.6,16.4,3.6s10.2-.8,14.4-2.5c4.3-1.7,8.1-4.3,11.4-7.8l11.9,13.7c-4.3,5-9.6,8.8-16.1,11.5-6.5,2.7-13.9,4-22.2,4Z"/>
|
||||
<path d="M1645.7,165.3v-95.1h21.2v26.2l-2.5-7.7c2.8-6.4,7.3-11.3,13.4-14.6,6.1-3.3,13.7-5,22.9-5v21.2c-1-.2-1.8-.4-2.7-.4-.8,0-1.7,0-2.5,0-8.4,0-15.1,2.5-20.1,7.4-5,4.9-7.5,12.3-7.5,22v46.1h-22.3Z"/>
|
||||
<path d="M1749.9,166.6c-8,0-15.6-1-22.9-3.1s-13.1-4.6-17.4-7.6l8.5-16.9c4.3,2.7,9.4,5,15.3,6.8,5.9,1.8,11.9,2.7,17.8,2.7s12.1-.9,15.2-2.8c3.1-1.9,4.7-4.5,4.7-7.7s-1.1-4.6-3.2-6c-2.1-1.4-4.9-2.4-8.4-3.1-3.4-.7-7.3-1.4-11.5-2-4.2-.6-8.4-1.4-12.6-2.4-4.2-1-8-2.5-11.5-4.5-3.4-2-6.2-4.6-8.4-7.9-2.1-3.3-3.2-7.7-3.2-13.2s1.7-11.3,5.2-15.8c3.4-4.5,8.3-7.9,14.5-10.3,6.2-2.4,13.6-3.7,22.2-3.7s12.9.7,19.4,2.1c6.5,1.4,11.9,3.4,16.2,6.1l-8.5,16.9c-4.5-2.7-9.1-4.6-13.6-5.6-4.6-1-9.1-1.5-13.6-1.5-6.8,0-11.8,1-15,3-3.3,2-4.9,4.6-4.9,7.7s1.1,5,3.2,6.4c2.1,1.4,4.9,2.6,8.4,3.4,3.4.8,7.3,1.5,11.5,2,4.2.5,8.4,1.3,12.6,2.4,4.2,1.1,8,2.5,11.5,4.4,3.5,1.8,6.3,4.4,8.5,7.7,2.1,3.3,3.2,7.7,3.2,13s-1.8,11.1-5.3,15.5c-3.5,4.4-8.5,7.8-14.9,10.2-6.4,2.4-14.1,3.7-23,3.7Z"/>
|
||||
<g>
|
||||
<path d="M9.8,143l63.4-38.1-5.8-15.3,18.1-18.6,22.9-4.9,6.6,8.2-10.6,10.7-9.2,2.9-6.6,6.8,3.2,9,6.5,6.9,9.2-2.5,6.6-7.2,14.3-4.5,4.3,9.6-14.8,18.1-24.8,7.8-11.1-12.4-63.6,38.2c-3-3.9-6.5-9.4-8.8-14.7ZM192.8,65.4l-50.4,13.6c2.8,7.4,3.7,11.7,4.5,16.5l50.3-13.6c-.8-5.4-2.2-10.8-4.4-16.5Z" fill-rule="evenodd"/>
|
||||
<path d="M17.3,106.5c3.6,42.1,38.9,75.2,82,75.2s60.7-18.9,74-46.3l16.4,5.7c-15.8,34.1-50.3,57.9-90.4,57.9S3.6,158.2,0,106.5h17.3ZM.3,89.4C5.3,39.2,47.8,0,99.3,0s99.5,44.6,99.5,99.5-1.1,17.4-3.3,25.5l-16.3-5.7c1.6-6.5,2.4-13.1,2.4-19.8,0-45.4-36.9-82.3-82.3-82.3S22.6,48.7,17.6,89.4H.3Z" fill-rule="evenodd"/>
|
||||
<path d="M99,51.6c-26.4,0-47.9,21.5-47.9,48s21.5,48,48,48,2.7,0,4-.2l4.8,16.8c-2.9.4-5.8.6-8.8.6-36,0-65.2-29.2-65.2-65.2S63.1,34.4,99,34.4s1.8,0,2.7,0l-2.7,17.1ZM118.6,37.4c26.4,8.3,45.6,33,45.6,62.2s-16.4,50.2-39.8,60l-4.8-16.7c16.2-7.7,27.4-24.2,27.4-43.3s-13-38.1-31.1-44.9l2.7-17.2Z" fill-rule="evenodd"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="black" fill="currentColor">
|
||||
<path d="M354.8,69.2c12,0,21.7,3.4,28.6,10.4,7,7.2,10.6,17.5,10.6,31.5v54.8h-22.4v-51.9c0-8.4-1.8-14.7-5.5-19-3.8-4.1-8.9-6.3-15.9-6.3s-13.6,2.5-18.1,7.3c-4.5,5-6.8,12.2-6.8,21.3v48.5h-22.4v-51.9c0-8.4-1.8-14.7-5.5-19-3.8-4.1-8.9-6.3-15.9-6.3s-13.6,2.5-18.1,7.3c-4.5,4.8-6.8,12-6.8,21.3v48.5h-22.4v-95.6h21.3v12.2c3.6-4.3,8.1-7.5,13.4-9.8,5.4-2.3,11.3-3.4,17.9-3.4s13.6,1.3,19.2,3.9c5.5,2.9,9.8,6.8,13.1,12,3.9-5,8.9-8.9,15.2-11.8,6.3-2.7,13.1-4.1,20.6-4.1ZM466,167.2c-9.7,0-18.4-2.1-26.1-6.3-7.6-4-13.8-10.1-18.1-17.5-4.5-7.3-6.6-15.7-6.6-25.2s2.1-17.9,6.6-25.2c4.3-7.4,10.6-13.4,18.1-17.4,7.7-4.1,16.5-6.3,26.1-6.3s18.6,2.1,26.3,6.3c7.7,4.1,13.8,10,18.3,17.4,4.3,7.3,6.4,15.7,6.4,25.2s-2.1,17.9-6.4,25.2c-4.5,7.5-10.6,13.4-18.3,17.5-7.7,4.1-16.5,6.3-26.3,6.3h0ZM466,148c8.2,0,15-2.7,20.4-8.2,5.4-5.5,8.1-12.7,8.1-21.7s-2.7-16.1-8.1-21.7c-5.4-5.5-12.2-8.2-20.4-8.2s-15,2.7-20.2,8.2c-5.4,5.5-8.1,12.7-8.1,21.7s2.7,16.1,8.1,21.7c5.2,5.5,12,8.2,20.2,8.2ZM631.5,33.1v132.8h-21.5v-12.3c-3.7,4.4-8.3,7.9-13.6,10.2-5.5,2.3-11.5,3.4-18.1,3.4s-17.4-2-24.7-6.1c-7.3-4.1-13.2-9.8-17.4-17.4-4.1-7.3-6.3-15.9-6.3-25.6s2.1-18.3,6.3-25.6c4.1-7.3,10-13.1,17.4-17.2,7.3-4.1,15.6-6.1,24.7-6.1s12.2,1.1,17.4,3.2c5.2,2.1,9.8,5.4,13.4,9.7v-49h22.4ZM581.1,148c5.4,0,10.2-1.3,14.5-3.8,4.3-2.3,7.7-5.9,10.2-10.4,2.5-4.5,3.8-9.8,3.8-15.7s-1.3-11.3-3.8-15.7c-2.5-4.5-5.9-8.1-10.2-10.6-4.3-2.3-9.1-3.6-14.5-3.6s-10.2,1.3-14.5,3.6c-4.3,2.5-7.7,6.1-10.2,10.6-2.5,4.5-3.8,9.8-3.8,15.7s1.3,11.3,3.8,15.7c2.5,4.5,5.9,8.1,10.2,10.4,4.3,2.5,9.1,3.8,14.5,3.8ZM681.6,84.3c6.4-10,17.7-15,34-15v21.3c-1.7-.3-3.4-.5-5.2-.5-8.8,0-15.6,2.5-20.4,7.5-4.8,5.2-7.3,12.5-7.3,22v46.4h-22.4v-95.6h21.3v14h0ZM734.1,70.3h22.4v95.6h-22.4v-95.6ZM745.4,54.6c-4.1,0-7.5-1.3-10.2-3.9-2.7-2.4-4.2-5.9-4.1-9.5,0-3.8,1.4-7,4.1-9.7,2.7-2.5,6.1-3.8,10.2-3.8s7.5,1.3,10.2,3.6c2.7,2.5,4.1,5.5,4.1,9.3s-1.3,7.2-3.9,9.8c-2.7,2.7-6.3,4.1-10.4,4.1ZM839.5,69.2c12,0,21.7,3.6,29,10.6,7.3,7,10.9,17.5,10.9,31.3v54.8h-22.4v-51.9c0-8.4-2-14.7-5.9-19-3.9-4.1-9.5-6.3-16.8-6.3s-14.7,2.5-19.5,7.3c-4.8,5-7.2,12.2-7.2,21.5v48.3h-22.4v-95.6h21.3v12.3c3.8-4.5,8.4-7.7,14-10,5.5-2.3,12-3.4,19-3.4ZM964.8,160.7c-2.8,2.2-6,3.9-9.5,4.8-3.9,1.1-7.9,1.6-12,1.6-10.6,0-18.6-2.7-24.3-8.2-5.7-5.5-8.6-13.4-8.6-24v-46h-15.7v-17.9h15.7v-21.8h22.4v21.8h25.6v17.9h-25.6v45.5c0,4.7,1.1,8.2,3.4,10.6,2.3,2.5,5.5,3.8,9.8,3.8s9.1-1.3,12.5-3.9l6.3,15.9ZM1036.9,69.2c12,0,21.7,3.6,29,10.6,7.3,7,10.9,17.5,10.9,31.3v54.8h-22.4v-51.9c0-8.4-2-14.7-5.9-19-3.9-4.1-9.5-6.3-16.8-6.3s-14.7,2.5-19.5,7.3c-4.8,5-7.2,12.2-7.2,21.5v48.3h-22.4V33.1h22.4v48.3c3.8-3.9,8.2-7,13.8-9.1,5.4-2,11.5-3,18.1-3Z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.0 KiB |
BIN
apps/app-frontend/src/assets/sad-modrinth-bot.webp
Normal file
|
After Width: | Height: | Size: 163 KiB |
BIN
apps/app-frontend/src/assets/skins/herobrine.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
apps/app-frontend/src/assets/skins/steve.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
@ -1,5 +1,45 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@font-face {
|
||||
font-family: 'bundled-minecraft-font-mrapp';
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 400;
|
||||
src: url('https://cdn-raw.modrinth.com/fonts/minecraft/regular.otf') format('opentype');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'bundled-minecraft-font-mrapp';
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
font-weight: 400;
|
||||
src: url('https://cdn-raw.modrinth.com/fonts/minecraft/italic.otf') format('opentype');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'bundled-minecraft-font-mrapp';
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 600;
|
||||
src: url('https://cdn-raw.modrinth.com/fonts/minecraft/bold.otf') format('opentype');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'bundled-minecraft-font-mrapp';
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
font-weight: 600;
|
||||
src: url('https://cdn-raw.modrinth.com/fonts/minecraft/bold-italic.otf') format('opentype');
|
||||
}
|
||||
|
||||
.font-minecraft {
|
||||
font-family: 'bundled-minecraft-font-mrapp', monospace;
|
||||
}
|
||||
|
||||
:root {
|
||||
font-family: var(--font-standard);
|
||||
font-family: var(--font-standard, sans-serif), sans-serif;
|
||||
color-scheme: dark;
|
||||
--view-width: calc(100% - 5rem);
|
||||
--expanded-view-width: calc(100% - 13rem);
|
||||
@ -69,55 +109,32 @@ input {
|
||||
}
|
||||
}
|
||||
|
||||
.mac {
|
||||
.nav-container {
|
||||
padding-top: calc(var(--gap-md) + 1.75rem);
|
||||
}
|
||||
|
||||
.account-card,
|
||||
.card-section {
|
||||
top: calc(var(--gap-md) + 1.75rem);
|
||||
}
|
||||
}
|
||||
|
||||
.windows {
|
||||
.fake-appbar {
|
||||
height: 2.5rem !important;
|
||||
}
|
||||
|
||||
.window-controls {
|
||||
display: flex !important;
|
||||
}
|
||||
|
||||
.info-card {
|
||||
right: 8rem;
|
||||
}
|
||||
|
||||
.profile-card {
|
||||
right: 8rem;
|
||||
}
|
||||
}
|
||||
|
||||
* {
|
||||
scrollbar-width: auto;
|
||||
scrollbar-color: var(--color-button-bg) var(--color-bg);
|
||||
scrollbar-color: var(--color-scrollbar) var(--color-bg);
|
||||
}
|
||||
|
||||
/* Chrome, Edge, and Safari */
|
||||
*::-webkit-scrollbar {
|
||||
width: var(--gap-md);
|
||||
border: 3px solid var(--color-bg);
|
||||
width: 16px;
|
||||
border: 3px solid transparent;
|
||||
opacity: 0.5;
|
||||
transition: opacity 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-track {
|
||||
background: var(--color-bg);
|
||||
border: 3px solid var(--color-bg);
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-thumb {
|
||||
background-color: var(--color-button-bg);
|
||||
background-color: var(--color-scrollbar);
|
||||
border-radius: var(--radius-lg);
|
||||
border: 3px solid var(--color-bg);
|
||||
border: 5px solid transparent;
|
||||
background-clip: content-box;
|
||||
}
|
||||
|
||||
.highlighted {
|
||||
@ -135,3 +152,9 @@ img {
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
|
||||
.card-shadow {
|
||||
box-shadow: var(--shadow-card);
|
||||
}
|
||||
|
||||
@import '@modrinth/assets/omorphia.scss';
|
||||
@ -9,19 +9,16 @@ import {
|
||||
TrashIcon,
|
||||
StopCircleIcon,
|
||||
EyeIcon,
|
||||
Card,
|
||||
DropdownSelect,
|
||||
SearchIcon,
|
||||
XIcon,
|
||||
Button,
|
||||
formatCategoryHeader,
|
||||
ModalConfirm,
|
||||
} from 'omorphia'
|
||||
} from '@modrinth/assets'
|
||||
import { Button, DropdownSelect } from '@modrinth/ui'
|
||||
import { formatCategoryHeader } from '@modrinth/utils'
|
||||
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||
import dayjs from 'dayjs'
|
||||
import { useTheming } from '@/store/theme.js'
|
||||
import { duplicate, remove } from '@/helpers/profile.js'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue'
|
||||
|
||||
const props = defineProps({
|
||||
instances: {
|
||||
@ -38,14 +35,13 @@ const props = defineProps({
|
||||
const instanceOptions = ref(null)
|
||||
const instanceComponents = ref(null)
|
||||
|
||||
const themeStore = useTheming()
|
||||
const currentDeleteInstance = ref(null)
|
||||
const confirmModal = ref(null)
|
||||
|
||||
async function deleteProfile() {
|
||||
if (currentDeleteInstance.value) {
|
||||
instanceComponents.value = instanceComponents.value.filter(
|
||||
(x) => x.instance.path !== currentDeleteInstance.value
|
||||
(x) => x.instance.path !== currentDeleteInstance.value,
|
||||
)
|
||||
await remove(currentDeleteInstance.value).catch(handleError)
|
||||
}
|
||||
@ -88,7 +84,7 @@ const handleRightClick = (event, profilePathId) => {
|
||||
color: 'primary',
|
||||
},
|
||||
...baseOptions,
|
||||
]
|
||||
],
|
||||
)
|
||||
}
|
||||
|
||||
@ -124,52 +120,41 @@ const handleOptionsClick = async (args) => {
|
||||
}
|
||||
|
||||
const search = ref('')
|
||||
const group = ref('Category')
|
||||
const filters = ref('All profiles')
|
||||
const group = ref('Group')
|
||||
const sortBy = ref('Name')
|
||||
|
||||
const filteredResults = computed(() => {
|
||||
let instances = props.instances.filter((instance) => {
|
||||
return instance.metadata.name.toLowerCase().includes(search.value.toLowerCase())
|
||||
const instances = props.instances.filter((instance) => {
|
||||
return instance.name.toLowerCase().includes(search.value.toLowerCase())
|
||||
})
|
||||
|
||||
if (sortBy.value === 'Name') {
|
||||
instances.sort((a, b) => {
|
||||
return a.metadata.name.localeCompare(b.metadata.name)
|
||||
return a.name.localeCompare(b.name)
|
||||
})
|
||||
}
|
||||
|
||||
if (sortBy.value === 'Game version') {
|
||||
instances.sort((a, b) => {
|
||||
return a.metadata.game_version.localeCompare(b.metadata.game_version)
|
||||
return a.game_version.localeCompare(b.game_version, undefined, { numeric: true })
|
||||
})
|
||||
}
|
||||
|
||||
if (sortBy.value === 'Last played') {
|
||||
instances.sort((a, b) => {
|
||||
return dayjs(b.metadata.last_played ?? 0).diff(dayjs(a.metadata.last_played ?? 0))
|
||||
return dayjs(b.last_played ?? 0).diff(dayjs(a.last_played ?? 0))
|
||||
})
|
||||
}
|
||||
|
||||
if (sortBy.value === 'Date created') {
|
||||
instances.sort((a, b) => {
|
||||
return dayjs(b.metadata.date_created).diff(dayjs(a.metadata.date_created))
|
||||
return dayjs(b.date_created).diff(dayjs(a.date_created))
|
||||
})
|
||||
}
|
||||
|
||||
if (sortBy.value === 'Date modified') {
|
||||
instances.sort((a, b) => {
|
||||
return dayjs(b.metadata.date_modified).diff(dayjs(a.metadata.date_modified))
|
||||
})
|
||||
}
|
||||
|
||||
if (filters.value === 'Custom instances') {
|
||||
instances = instances.filter((instance) => {
|
||||
return !instance.metadata?.linked_data
|
||||
})
|
||||
} else if (filters.value === 'Downloaded modpacks') {
|
||||
instances = instances.filter((instance) => {
|
||||
return instance.metadata?.linked_data?.modrinth_modpack
|
||||
return dayjs(b.date_modified).diff(dayjs(a.date_modified))
|
||||
})
|
||||
}
|
||||
|
||||
@ -177,7 +162,7 @@ const filteredResults = computed(() => {
|
||||
|
||||
if (group.value === 'Loader') {
|
||||
instances.forEach((instance) => {
|
||||
const loader = formatCategoryHeader(instance.metadata.loader)
|
||||
const loader = formatCategoryHeader(instance.loader)
|
||||
if (!instanceMap.has(loader)) {
|
||||
instanceMap.set(loader, [])
|
||||
}
|
||||
@ -186,19 +171,19 @@ const filteredResults = computed(() => {
|
||||
})
|
||||
} else if (group.value === 'Game version') {
|
||||
instances.forEach((instance) => {
|
||||
if (!instanceMap.has(instance.metadata.game_version)) {
|
||||
instanceMap.set(instance.metadata.game_version, [])
|
||||
if (!instanceMap.has(instance.game_version)) {
|
||||
instanceMap.set(instance.game_version, [])
|
||||
}
|
||||
|
||||
instanceMap.get(instance.metadata.game_version).push(instance)
|
||||
instanceMap.get(instance.game_version).push(instance)
|
||||
})
|
||||
} else if (group.value === 'Category') {
|
||||
} else if (group.value === 'Group') {
|
||||
instances.forEach((instance) => {
|
||||
if (instance.metadata.groups.length === 0) {
|
||||
instance.metadata.groups.push('None')
|
||||
if (instance.groups.length === 0) {
|
||||
instance.groups.push('None')
|
||||
}
|
||||
|
||||
for (const category of instance.metadata.groups) {
|
||||
for (const category of instance.groups) {
|
||||
if (!instanceMap.has(category)) {
|
||||
instanceMap.set(category, [])
|
||||
}
|
||||
@ -228,59 +213,53 @@ const filteredResults = computed(() => {
|
||||
instanceMap.set(entry[0], entry[1])
|
||||
})
|
||||
}
|
||||
// default sorting would do 1.20.4 < 1.8.9 because 2 < 8
|
||||
// localeCompare with numeric=true puts 1.8.9 < 1.20.4 because 8 < 20
|
||||
if (group.value === 'Game version') {
|
||||
const sortedEntries = [...instanceMap.entries()].sort((a, b) => {
|
||||
return a[0].localeCompare(b[0], undefined, { numeric: true })
|
||||
})
|
||||
instanceMap.clear()
|
||||
sortedEntries.forEach((entry) => {
|
||||
instanceMap.set(entry[0], entry[1])
|
||||
})
|
||||
}
|
||||
|
||||
return instanceMap
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<ModalConfirm
|
||||
ref="confirmModal"
|
||||
title="Are you sure you want to delete this instance?"
|
||||
description="If you proceed, all data for your instance will be removed. You will not be able to recover it."
|
||||
:has-to-type="false"
|
||||
proceed-label="Delete"
|
||||
:noblur="!themeStore.advancedRendering"
|
||||
@proceed="deleteProfile"
|
||||
/>
|
||||
<Card class="header">
|
||||
<div class="iconified-input">
|
||||
<div class="flex gap-2">
|
||||
<div class="iconified-input flex-1">
|
||||
<SearchIcon />
|
||||
<input v-model="search" type="text" placeholder="Search" class="search-input" />
|
||||
<Button @click="() => (search = '')">
|
||||
<input v-model="search" type="text" placeholder="Search" />
|
||||
<Button class="r-btn" @click="() => (search = '')">
|
||||
<XIcon />
|
||||
</Button>
|
||||
</div>
|
||||
<div class="labeled_button">
|
||||
<span>Sort by</span>
|
||||
<DropdownSelect
|
||||
v-model="sortBy"
|
||||
class="sort-dropdown"
|
||||
name="Sort Dropdown"
|
||||
:options="['Name', 'Last played', 'Date created', 'Date modified', 'Game version']"
|
||||
placeholder="Select..."
|
||||
/>
|
||||
</div>
|
||||
<div class="labeled_button">
|
||||
<span>Filter by</span>
|
||||
<DropdownSelect
|
||||
v-model="filters"
|
||||
class="filter-dropdown"
|
||||
name="Filter Dropdown"
|
||||
:options="['All profiles', 'Custom instances', 'Downloaded modpacks']"
|
||||
placeholder="Select..."
|
||||
/>
|
||||
</div>
|
||||
<div class="labeled_button">
|
||||
<span>Group by</span>
|
||||
<DropdownSelect
|
||||
v-model="group"
|
||||
class="group-dropdown"
|
||||
name="Group Dropdown"
|
||||
:options="['Category', 'Loader', 'Game version', 'None']"
|
||||
placeholder="Select..."
|
||||
/>
|
||||
</div>
|
||||
</Card>
|
||||
<DropdownSelect
|
||||
v-slot="{ selected }"
|
||||
v-model="sortBy"
|
||||
name="Sort Dropdown"
|
||||
class="max-w-[16rem]"
|
||||
:options="['Name', 'Last played', 'Date created', 'Date modified', 'Game version']"
|
||||
placeholder="Select..."
|
||||
>
|
||||
<span class="font-semibold text-primary">Sort by: </span>
|
||||
<span class="font-semibold text-secondary">{{ selected }}</span>
|
||||
</DropdownSelect>
|
||||
<DropdownSelect
|
||||
v-slot="{ selected }"
|
||||
v-model="group"
|
||||
class="max-w-[16rem]"
|
||||
name="Group Dropdown"
|
||||
:options="['Group', 'Loader', 'Game version', 'None']"
|
||||
placeholder="Select..."
|
||||
>
|
||||
<span class="font-semibold text-primary">Group by: </span>
|
||||
<span class="font-semibold text-secondary">{{ selected }}</span>
|
||||
</DropdownSelect>
|
||||
</div>
|
||||
<div
|
||||
v-for="instanceSection in Array.from(filteredResults, ([key, value]) => ({
|
||||
key,
|
||||
@ -303,6 +282,14 @@ const filteredResults = computed(() => {
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
<ConfirmModalWrapper
|
||||
ref="confirmModal"
|
||||
title="Are you sure you want to delete this instance?"
|
||||
description="If you proceed, all data for your instance will be removed. You will not be able to recover it."
|
||||
:has-to-type="false"
|
||||
proceed-label="Delete"
|
||||
@proceed="deleteProfile"
|
||||
/>
|
||||
<ContextMenu ref="instanceOptions" @option-clicked="handleOptionsClick">
|
||||
<template #play> <PlayIcon /> Play </template>
|
||||
<template #stop> <StopCircleIcon /> Stop </template>
|
||||
@ -320,7 +307,6 @@ const filteredResults = computed(() => {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
width: 100%;
|
||||
padding: 1rem;
|
||||
|
||||
.divider {
|
||||
display: flex;
|
||||
@ -388,9 +374,9 @@ const filteredResults = computed(() => {
|
||||
|
||||
.instances {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
|
||||
grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
|
||||
width: 100%;
|
||||
gap: 1rem;
|
||||
gap: 0.75rem;
|
||||
margin-right: auto;
|
||||
scroll-behavior: smooth;
|
||||
overflow-y: auto;
|
||||
141
apps/app-frontend/src/components/LoadingIndicatorBar.vue
Normal file
@ -0,0 +1,141 @@
|
||||
<script setup>
|
||||
import { computed, onBeforeUnmount, ref, watch } from 'vue'
|
||||
import { useLoading } from '@/store/state.js'
|
||||
|
||||
const props = defineProps({
|
||||
throttle: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
duration: {
|
||||
type: Number,
|
||||
default: 1000,
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 2,
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: 'var(--loading-bar-gradient)',
|
||||
},
|
||||
})
|
||||
|
||||
const indicator = useLoadingIndicator({
|
||||
duration: props.duration,
|
||||
throttle: props.throttle,
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => indicator.clear)
|
||||
|
||||
const loading = useLoading()
|
||||
|
||||
watch(loading, (newValue) => {
|
||||
if (newValue.barEnabled) {
|
||||
if (newValue.loading) {
|
||||
indicator.start()
|
||||
} else {
|
||||
indicator.finish()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function useLoadingIndicator(opts) {
|
||||
const progress = ref(0)
|
||||
const isLoading = ref(false)
|
||||
const step = computed(() => 10000 / opts.duration)
|
||||
|
||||
let _timer = null
|
||||
let _throttle = null
|
||||
|
||||
function start() {
|
||||
clear()
|
||||
progress.value = 0
|
||||
if (opts.throttle) {
|
||||
_throttle = setTimeout(() => {
|
||||
isLoading.value = true
|
||||
_startTimer()
|
||||
}, opts.throttle)
|
||||
} else {
|
||||
isLoading.value = true
|
||||
_startTimer()
|
||||
}
|
||||
}
|
||||
|
||||
function finish() {
|
||||
progress.value = 100
|
||||
_hide()
|
||||
}
|
||||
|
||||
function clear() {
|
||||
clearInterval(_timer)
|
||||
clearTimeout(_throttle)
|
||||
_timer = null
|
||||
_throttle = null
|
||||
}
|
||||
|
||||
function _increase(num) {
|
||||
progress.value = Math.min(100, progress.value + num)
|
||||
}
|
||||
|
||||
function _hide() {
|
||||
clear()
|
||||
setTimeout(() => {
|
||||
isLoading.value = false
|
||||
setTimeout(() => {
|
||||
progress.value = 0
|
||||
}, 400)
|
||||
}, 500)
|
||||
}
|
||||
|
||||
function _startTimer() {
|
||||
_timer = setInterval(() => {
|
||||
_increase(step.value)
|
||||
}, 100)
|
||||
}
|
||||
|
||||
return { progress, isLoading, start, finish, clear }
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="loading-indicator-bar"
|
||||
:style="{
|
||||
'--_width': `${indicator.progress.value}%`,
|
||||
'--_height': `${indicator.isLoading.value ? props.height : 0}px`,
|
||||
'--_opacity': `${indicator.isLoading.value ? 1 : 0}`,
|
||||
top: `0`,
|
||||
right: `0`,
|
||||
left: `${props.offsetWidth}`,
|
||||
pointerEvents: 'none',
|
||||
width: `var(--_width)`,
|
||||
height: `var(--_height)`,
|
||||
borderRadius: `var(--_height)`,
|
||||
// opacity: `var(--_opacity)`,
|
||||
background: `${props.color}`,
|
||||
backgroundSize: `${(100 / indicator.progress.value) * 100}% auto`,
|
||||
transition: 'width 0.1s ease-in-out, height 0.1s ease-out',
|
||||
zIndex: 6,
|
||||
}"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss" scoped>
|
||||
.loading-indicator-bar::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: var(--_width);
|
||||
bottom: 0;
|
||||
background-image: radial-gradient(80% 100% at 20% 0%, var(--color-brand) 0%, transparent 80%);
|
||||
opacity: calc(var(--_opacity) * 0.1);
|
||||
z-index: 5;
|
||||
transition:
|
||||
width 0.1s ease-in-out,
|
||||
opacity 0.1s ease-out;
|
||||
}
|
||||
</style>
|
||||
@ -10,28 +10,22 @@ import {
|
||||
StopCircleIcon,
|
||||
ExternalIcon,
|
||||
EyeIcon,
|
||||
ChevronRightIcon,
|
||||
ModalConfirm,
|
||||
} from 'omorphia'
|
||||
} from '@modrinth/assets'
|
||||
import ConfirmModalWrapper from '@/components/ui/modal/ConfirmModalWrapper.vue'
|
||||
import Instance from '@/components/ui/Instance.vue'
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||
import ProjectCard from '@/components/ui/ProjectCard.vue'
|
||||
import InstallConfirmModal from '@/components/ui/InstallConfirmModal.vue'
|
||||
import ModInstallModal from '@/components/ui/ModInstallModal.vue'
|
||||
import {
|
||||
get_all_running_profile_paths,
|
||||
get_uuids_by_profile_path,
|
||||
kill_by_uuid,
|
||||
} from '@/helpers/process.js'
|
||||
import { get_by_profile_path } from '@/helpers/process.js'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import { duplicate, remove, run } from '@/helpers/profile.js'
|
||||
import { duplicate, kill, remove, run } from '@/helpers/profile.js'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { showProfileInFolder } from '@/helpers/utils.js'
|
||||
import { useFetch } from '@/helpers/fetch.js'
|
||||
import { install as pack_install } from '@/helpers/pack.js'
|
||||
import { useTheming } from '@/store/state.js'
|
||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { handleSevereError } from '@/store/error.js'
|
||||
import { install as installVersion } from '@/store/install.js'
|
||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||
import { HeadingLink } from '@modrinth/ui'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
@ -50,18 +44,17 @@ const props = defineProps({
|
||||
})
|
||||
|
||||
const actualInstances = computed(() =>
|
||||
props.instances.filter((x) => x && x.instances && x.instances[0])
|
||||
props.instances.filter(
|
||||
(x) => (x && x.instances && x.instances[0] && x.show === undefined) || x.show,
|
||||
),
|
||||
)
|
||||
|
||||
const modsRow = ref(null)
|
||||
const instanceOptions = ref(null)
|
||||
const instanceComponents = ref(null)
|
||||
const rows = ref(null)
|
||||
const confirmModal = ref(null)
|
||||
const deleteConfirmModal = ref(null)
|
||||
const modInstallModal = ref(null)
|
||||
|
||||
const themeStore = useTheming()
|
||||
const currentDeleteInstance = ref(null)
|
||||
|
||||
async function deleteProfile() {
|
||||
@ -89,23 +82,24 @@ const handleInstanceRightClick = async (event, passedInstance) => {
|
||||
},
|
||||
]
|
||||
|
||||
const running = await get_all_running_profile_paths().catch(handleError)
|
||||
const runningProcesses = await get_by_profile_path(passedInstance.path).catch(handleError)
|
||||
|
||||
const options = running.includes(passedInstance.path)
|
||||
? [
|
||||
{
|
||||
name: 'stop',
|
||||
color: 'danger',
|
||||
},
|
||||
...baseOptions,
|
||||
]
|
||||
: [
|
||||
{
|
||||
name: 'play',
|
||||
color: 'primary',
|
||||
},
|
||||
...baseOptions,
|
||||
]
|
||||
const options =
|
||||
runningProcesses.length > 0
|
||||
? [
|
||||
{
|
||||
name: 'stop',
|
||||
color: 'danger',
|
||||
},
|
||||
...baseOptions,
|
||||
]
|
||||
: [
|
||||
{
|
||||
name: 'play',
|
||||
color: 'primary',
|
||||
},
|
||||
...baseOptions,
|
||||
]
|
||||
|
||||
instanceOptions.value.showMenu(event, passedInstance, options)
|
||||
}
|
||||
@ -129,24 +123,24 @@ const handleProjectClick = (event, passedInstance) => {
|
||||
const handleOptionsClick = async (args) => {
|
||||
switch (args.option) {
|
||||
case 'play':
|
||||
await run(args.item.path).catch(handleError)
|
||||
mixpanel_track('InstanceStart', {
|
||||
loader: args.item.metadata.loader,
|
||||
game_version: args.item.metadata.game_version,
|
||||
await run(args.item.path).catch((err) =>
|
||||
handleSevereError(err, { profilePath: args.item.path }),
|
||||
)
|
||||
trackEvent('InstanceStart', {
|
||||
loader: args.item.loader,
|
||||
game_version: args.item.game_version,
|
||||
})
|
||||
break
|
||||
case 'stop':
|
||||
for (const u of await get_uuids_by_profile_path(args.item.path).catch(handleError)) {
|
||||
await kill_by_uuid(u).catch(handleError)
|
||||
}
|
||||
mixpanel_track('InstanceStop', {
|
||||
loader: args.item.metadata.loader,
|
||||
game_version: args.item.metadata.game_version,
|
||||
await kill(args.item.path).catch(handleError)
|
||||
trackEvent('InstanceStop', {
|
||||
loader: args.item.loader,
|
||||
game_version: args.item.game_version,
|
||||
})
|
||||
break
|
||||
case 'add_content':
|
||||
await router.push({
|
||||
path: `/browse/${args.item.metadata.loader === 'vanilla' ? 'datapack' : 'mod'}`,
|
||||
path: `/browse/${args.item.loader === 'vanilla' ? 'datapack' : 'mod'}`,
|
||||
query: { i: args.item.path },
|
||||
})
|
||||
break
|
||||
@ -169,84 +163,100 @@ const handleOptionsClick = async (args) => {
|
||||
await navigator.clipboard.writeText(args.item.path)
|
||||
break
|
||||
case 'install': {
|
||||
const versions = await useFetch(
|
||||
`https://staging-api.modrinth.com/v2/project/${args.item.project_id}/version`,
|
||||
'project versions'
|
||||
)
|
||||
await installVersion(args.item.project_id, null, null, 'ProjectCardContextMenu')
|
||||
|
||||
if (args.item.project_type === 'modpack') {
|
||||
await pack_install(
|
||||
args.item.project_id,
|
||||
versions[0].id,
|
||||
args.item.title,
|
||||
args.item.icon_url
|
||||
)
|
||||
} else {
|
||||
modInstallModal.value.show(args.item.project_id, versions)
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'open_link':
|
||||
window.__TAURI_INVOKE__('tauri', {
|
||||
__tauriModule: 'Shell',
|
||||
message: {
|
||||
cmd: 'open',
|
||||
path: `https://modrinth.com/${args.item.project_type}/${args.item.slug}`,
|
||||
},
|
||||
})
|
||||
openUrl(`https://modrinth.com/${args.item.project_type}/${args.item.slug}`)
|
||||
break
|
||||
case 'copy_link':
|
||||
await navigator.clipboard.writeText(
|
||||
`https://modrinth.com/${args.item.project_type}/${args.item.slug}`
|
||||
`https://modrinth.com/${args.item.project_type}/${args.item.slug}`,
|
||||
)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
const maxInstancesPerCompactRow = ref(1)
|
||||
const maxInstancesPerRow = ref(1)
|
||||
const maxProjectsPerRow = ref(1)
|
||||
|
||||
const calculateCardsPerRow = () => {
|
||||
if (rows.value.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
// Calculate how many cards fit in one row
|
||||
const containerWidth = rows.value[0].clientWidth
|
||||
// Convert container width from pixels to rem
|
||||
const containerWidthInRem =
|
||||
containerWidth / parseFloat(getComputedStyle(document.documentElement).fontSize)
|
||||
maxInstancesPerRow.value = Math.floor((containerWidthInRem + 1) / 11)
|
||||
maxProjectsPerRow.value = Math.floor((containerWidthInRem + 1) / 19)
|
||||
|
||||
maxInstancesPerCompactRow.value = Math.floor((containerWidthInRem + 0.75) / 18.75)
|
||||
maxInstancesPerRow.value = Math.floor((containerWidthInRem + 0.75) / 20.75)
|
||||
maxProjectsPerRow.value = Math.floor((containerWidthInRem + 0.75) / 18.75)
|
||||
|
||||
if (maxInstancesPerRow.value < 5) {
|
||||
maxInstancesPerRow.value *= 2
|
||||
}
|
||||
if (maxInstancesPerCompactRow.value < 5) {
|
||||
maxInstancesPerCompactRow.value *= 2
|
||||
}
|
||||
if (maxProjectsPerRow.value < 3) {
|
||||
maxProjectsPerRow.value *= 2
|
||||
}
|
||||
}
|
||||
|
||||
const rowContainer = ref(null)
|
||||
const resizeObserver = ref(null)
|
||||
|
||||
onMounted(() => {
|
||||
calculateCardsPerRow()
|
||||
resizeObserver.value = new ResizeObserver(calculateCardsPerRow)
|
||||
if (rowContainer.value) {
|
||||
resizeObserver.value.observe(rowContainer.value)
|
||||
}
|
||||
window.addEventListener('resize', calculateCardsPerRow)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', calculateCardsPerRow)
|
||||
if (rowContainer.value) {
|
||||
resizeObserver.value.unobserve(rowContainer.value)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ModalConfirm
|
||||
<ConfirmModalWrapper
|
||||
ref="deleteConfirmModal"
|
||||
title="Are you sure you want to delete this instance?"
|
||||
description="If you proceed, all data for your instance will be removed. You will not be able to recover it."
|
||||
:has-to-type="false"
|
||||
proceed-label="Delete"
|
||||
:noblur="!themeStore.advancedRendering"
|
||||
@proceed="deleteProfile"
|
||||
/>
|
||||
<div class="content">
|
||||
<div ref="rowContainer" class="flex flex-col gap-4">
|
||||
<div v-for="row in actualInstances" ref="rows" :key="row.label" class="row">
|
||||
<div class="header">
|
||||
<router-link :to="row.route">{{ row.label }}</router-link>
|
||||
<ChevronRightIcon />
|
||||
</div>
|
||||
<section v-if="row.instances[0].metadata" ref="modsRow" class="instances">
|
||||
<HeadingLink class="mt-1" :to="row.route">
|
||||
{{ row.label }}
|
||||
</HeadingLink>
|
||||
<section
|
||||
v-if="row.instance"
|
||||
ref="modsRow"
|
||||
class="instances"
|
||||
:class="{ compact: row.compact }"
|
||||
>
|
||||
<Instance
|
||||
v-for="instance in row.instances.slice(0, maxInstancesPerRow)"
|
||||
:key="(instance?.project_id || instance?.id) + instance.install_stage"
|
||||
v-for="(instance, instanceIndex) in row.instances.slice(
|
||||
0,
|
||||
row.compact ? maxInstancesPerCompactRow : maxInstancesPerRow,
|
||||
)"
|
||||
:key="row.label + instance.path"
|
||||
:instance="instance"
|
||||
:compact="row.compact"
|
||||
:first="instanceIndex === 0"
|
||||
@contextmenu.prevent.stop="(event) => handleInstanceRightClick(event, instance)"
|
||||
/>
|
||||
</section>
|
||||
@ -257,8 +267,6 @@ onUnmounted(() => {
|
||||
ref="instanceComponents"
|
||||
class="item"
|
||||
:project="project"
|
||||
:confirm-modal="confirmModal"
|
||||
:mod-install-modal="modInstallModal"
|
||||
@contextmenu.prevent.stop="(event) => handleProjectClick(event, project)"
|
||||
/>
|
||||
</section>
|
||||
@ -277,8 +285,6 @@ onUnmounted(() => {
|
||||
<template #open_link> <GlobeIcon /> Open in Modrinth <ExternalIcon /> </template>
|
||||
<template #copy_link> <ClipboardCopyIcon /> Copy link </template>
|
||||
</ContextMenu>
|
||||
<InstallConfirmModal ref="confirmModal" />
|
||||
<ModInstallModal ref="modInstallModal" />
|
||||
</template>
|
||||
<style lang="scss" scoped>
|
||||
.content {
|
||||
@ -287,7 +293,6 @@ onUnmounted(() => {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
padding: 1rem;
|
||||
gap: 1rem;
|
||||
|
||||
-ms-overflow-style: none;
|
||||
@ -321,31 +326,36 @@ onUnmounted(() => {
|
||||
|
||||
a {
|
||||
margin: 0;
|
||||
font-size: var(--font-size-lg);
|
||||
font-size: var(--font-size-md);
|
||||
font-weight: bolder;
|
||||
white-space: nowrap;
|
||||
color: var(--color-contrast);
|
||||
color: var(--color-base);
|
||||
}
|
||||
|
||||
svg {
|
||||
height: 1.5rem;
|
||||
width: 1.5rem;
|
||||
color: var(--color-contrast);
|
||||
height: 1.25rem;
|
||||
width: 1.25rem;
|
||||
color: var(--color-base);
|
||||
}
|
||||
}
|
||||
|
||||
.instances {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
|
||||
grid-gap: 1rem;
|
||||
grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
|
||||
grid-gap: 0.75rem;
|
||||
width: 100%;
|
||||
|
||||
&.compact {
|
||||
grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
|
||||
gap: 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
.projects {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
|
||||
grid-gap: 1rem;
|
||||
grid-gap: 0.75rem;
|
||||
|
||||
.item {
|
||||
width: 100%;
|
||||
@ -2,19 +2,21 @@
|
||||
<div
|
||||
v-if="mode !== 'isolated'"
|
||||
ref="button"
|
||||
v-tooltip.right="'Minecraft accounts'"
|
||||
class="button-base avatar-button"
|
||||
class="button-base mt-2 px-3 py-2 bg-button-bg rounded-xl flex items-center gap-2"
|
||||
:class="{ expanded: mode === 'expanded' }"
|
||||
@click="showCard = !showCard"
|
||||
@click="toggleMenu"
|
||||
>
|
||||
<Avatar
|
||||
:size="mode === 'expanded' ? 'xs' : 'sm'"
|
||||
size="36px"
|
||||
:src="
|
||||
selectedAccount
|
||||
? `https://mc-heads.net/avatar/${selectedAccount.id}/128`
|
||||
: 'https://launcher-files.modrinth.com/assets/steve_head.png'
|
||||
selectedAccount ? avatarUrl : 'https://launcher-files.modrinth.com/assets/steve_head.png'
|
||||
"
|
||||
/>
|
||||
<div class="flex flex-col w-full">
|
||||
<span>{{ selectedAccount ? selectedAccount.profile.name : 'Select account' }}</span>
|
||||
<span class="text-secondary text-xs">Minecraft account</span>
|
||||
</div>
|
||||
<DropdownIcon class="w-5 h-5 shrink-0" />
|
||||
</div>
|
||||
<transition name="fade">
|
||||
<Card
|
||||
@ -24,28 +26,40 @@
|
||||
:class="{ expanded: mode === 'expanded', isolated: mode === 'isolated' }"
|
||||
>
|
||||
<div v-if="selectedAccount" class="selected account">
|
||||
<Avatar size="xs" :src="`https://mc-heads.net/avatar/${selectedAccount.id}/128`" />
|
||||
<Avatar size="xs" :src="avatarUrl" />
|
||||
<div>
|
||||
<h4>{{ selectedAccount.username }}</h4>
|
||||
<h4>{{ selectedAccount.profile.name }}</h4>
|
||||
<p>Selected</p>
|
||||
</div>
|
||||
<Button v-tooltip="'Log out'" icon-only color="raised" @click="logout(selectedAccount.id)">
|
||||
<Button
|
||||
v-tooltip="'Log out'"
|
||||
icon-only
|
||||
color="raised"
|
||||
@click="logout(selectedAccount.profile.id)"
|
||||
>
|
||||
<TrashIcon />
|
||||
</Button>
|
||||
</div>
|
||||
<div v-else class="logged-out account">
|
||||
<h4>Not signed in</h4>
|
||||
<Button v-tooltip="'Log in'" icon-only color="primary" @click="login()">
|
||||
<LogInIcon />
|
||||
<Button
|
||||
v-tooltip="'Log in'"
|
||||
:disabled="loginDisabled"
|
||||
icon-only
|
||||
color="primary"
|
||||
@click="login()"
|
||||
>
|
||||
<LogInIcon v-if="!loginDisabled" />
|
||||
<SpinnerIcon v-else class="animate-spin" />
|
||||
</Button>
|
||||
</div>
|
||||
<div v-if="displayAccounts.length > 0" class="account-group">
|
||||
<div v-for="account in displayAccounts" :key="account.id" class="account-row">
|
||||
<div v-for="account in displayAccounts" :key="account.profile.id" class="account-row">
|
||||
<Button class="option account" @click="setAccount(account)">
|
||||
<Avatar :src="`https://mc-heads.net/avatar/${account.id}/128`" class="icon" />
|
||||
<p>{{ account.username }}</p>
|
||||
<Avatar :src="getAccountAvatarUrl(account)" class="icon" />
|
||||
<p>{{ account.profile.name }}</p>
|
||||
</Button>
|
||||
<Button v-tooltip="'Log out'" icon-only @click="logout(account.id)">
|
||||
<Button v-tooltip="'Log out'" icon-only @click="logout(account.profile.id)">
|
||||
<TrashIcon />
|
||||
</Button>
|
||||
</div>
|
||||
@ -56,68 +70,25 @@
|
||||
</Button>
|
||||
</Card>
|
||||
</transition>
|
||||
<Modal ref="loginModal" class="modal" header="Signing in" :noblur="!themeStore.advancedRendering">
|
||||
<div class="modal-body">
|
||||
<QrcodeVue :value="loginUrl" class="qr-code" margin="3" size="160" />
|
||||
<div class="modal-text">
|
||||
<div class="label">Copy this code</div>
|
||||
<div class="code-text">
|
||||
<div class="code">
|
||||
{{ loginCode }}
|
||||
</div>
|
||||
<Button
|
||||
v-tooltip="'Copy code'"
|
||||
icon-only
|
||||
large
|
||||
color="raised"
|
||||
@click="() => clipboardWrite(loginCode)"
|
||||
>
|
||||
<ClipboardCopyIcon />
|
||||
</Button>
|
||||
</div>
|
||||
<div>And enter it on Microsoft's website to sign in.</div>
|
||||
<div class="iconified-input">
|
||||
<LogInIcon />
|
||||
<input type="text" :value="loginUrl" readonly />
|
||||
<Button
|
||||
v-tooltip="'Open link'"
|
||||
icon-only
|
||||
color="raised"
|
||||
@click="() => clipboardWrite(loginUrl)"
|
||||
>
|
||||
<GlobeIcon />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
Avatar,
|
||||
Button,
|
||||
Card,
|
||||
PlusIcon,
|
||||
TrashIcon,
|
||||
LogInIcon,
|
||||
Modal,
|
||||
GlobeIcon,
|
||||
ClipboardCopyIcon,
|
||||
} from 'omorphia'
|
||||
import { DropdownIcon, PlusIcon, TrashIcon, LogInIcon, SpinnerIcon } from '@modrinth/assets'
|
||||
import { Avatar, Button, Card } from '@modrinth/ui'
|
||||
import { ref, computed, onMounted, onBeforeUnmount, onUnmounted } from 'vue'
|
||||
import {
|
||||
users,
|
||||
remove_user,
|
||||
authenticate_begin_flow,
|
||||
authenticate_await_completion,
|
||||
set_default_user,
|
||||
login as login_flow,
|
||||
get_default_user,
|
||||
} from '@/helpers/auth'
|
||||
import { get, set } from '@/helpers/settings'
|
||||
import { handleError } from '@/store/state.js'
|
||||
import { useTheming } from '@/store/theme.js'
|
||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
||||
import QrcodeVue from 'qrcode.vue'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { process_listener } from '@/helpers/events'
|
||||
import { handleSevereError } from '@/store/error.js'
|
||||
import { get_available_skins } from '@/helpers/skins'
|
||||
import { getPlayerHeadUrl } from '@/helpers/rendering/batch-skin-renderer.ts'
|
||||
|
||||
defineProps({
|
||||
mode: {
|
||||
@ -129,65 +100,96 @@ defineProps({
|
||||
|
||||
const emit = defineEmits(['change'])
|
||||
|
||||
const loginCode = ref(null)
|
||||
|
||||
const themeStore = useTheming()
|
||||
const settings = ref({})
|
||||
const accounts = ref([])
|
||||
const loginUrl = ref('')
|
||||
const loginModal = ref(null)
|
||||
const accounts = ref({})
|
||||
const loginDisabled = ref(false)
|
||||
const defaultUser = ref()
|
||||
const equippedSkin = ref(null)
|
||||
const headUrlCache = ref(new Map())
|
||||
|
||||
async function refreshValues() {
|
||||
settings.value = await get().catch(handleError)
|
||||
defaultUser.value = await get_default_user().catch(handleError)
|
||||
accounts.value = await users().catch(handleError)
|
||||
|
||||
try {
|
||||
const skins = await get_available_skins()
|
||||
equippedSkin.value = skins.find((skin) => skin.is_equipped)
|
||||
|
||||
if (equippedSkin.value) {
|
||||
try {
|
||||
const headUrl = await getPlayerHeadUrl(equippedSkin.value)
|
||||
headUrlCache.value.set(equippedSkin.value.texture_key, headUrl)
|
||||
} catch (error) {
|
||||
console.warn('Failed to get head render for equipped skin:', error)
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
equippedSkin.value = null
|
||||
}
|
||||
}
|
||||
|
||||
function setLoginDisabled(value) {
|
||||
loginDisabled.value = value
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
refreshValues,
|
||||
setLoginDisabled,
|
||||
loginDisabled,
|
||||
})
|
||||
await refreshValues()
|
||||
|
||||
const displayAccounts = computed(() =>
|
||||
accounts.value.filter((account) => settings.value.default_user !== account.id)
|
||||
accounts.value.filter((account) => defaultUser.value !== account.profile.id),
|
||||
)
|
||||
|
||||
const avatarUrl = computed(() => {
|
||||
if (equippedSkin.value?.texture_key) {
|
||||
const cachedUrl = headUrlCache.value.get(equippedSkin.value.texture_key)
|
||||
if (cachedUrl) {
|
||||
return cachedUrl
|
||||
}
|
||||
return `https://mc-heads.net/avatar/${equippedSkin.value.texture_key}/128`
|
||||
}
|
||||
if (selectedAccount.value?.profile?.id) {
|
||||
return `https://mc-heads.net/avatar/${selectedAccount.value.profile.id}/128`
|
||||
}
|
||||
return 'https://launcher-files.modrinth.com/assets/steve_head.png'
|
||||
})
|
||||
|
||||
function getAccountAvatarUrl(account) {
|
||||
if (
|
||||
account.profile.id === selectedAccount.value?.profile?.id &&
|
||||
equippedSkin.value?.texture_key
|
||||
) {
|
||||
const cachedUrl = headUrlCache.value.get(equippedSkin.value.texture_key)
|
||||
if (cachedUrl) {
|
||||
return cachedUrl
|
||||
}
|
||||
}
|
||||
return `https://mc-heads.net/avatar/${account.profile.id}/128`
|
||||
}
|
||||
|
||||
const selectedAccount = computed(() =>
|
||||
accounts.value.find((account) => account.id === settings.value.default_user)
|
||||
accounts.value.find((account) => account.profile.id === defaultUser.value),
|
||||
)
|
||||
|
||||
async function setAccount(account) {
|
||||
settings.value.default_user = account.id
|
||||
await set(settings.value).catch(handleError)
|
||||
defaultUser.value = account.profile.id
|
||||
await set_default_user(account.profile.id).catch(handleError)
|
||||
emit('change')
|
||||
}
|
||||
|
||||
const clipboardWrite = async (a) => {
|
||||
navigator.clipboard.writeText(a)
|
||||
}
|
||||
|
||||
async function login() {
|
||||
const loginSuccess = await authenticate_begin_flow().catch(handleError)
|
||||
|
||||
loginModal.value.show()
|
||||
loginCode.value = loginSuccess.user_code
|
||||
loginUrl.value = loginSuccess.verification_uri
|
||||
await window.__TAURI_INVOKE__('tauri', {
|
||||
__tauriModule: 'Shell',
|
||||
message: {
|
||||
cmd: 'open',
|
||||
path: loginSuccess.verification_uri,
|
||||
},
|
||||
})
|
||||
|
||||
const loggedIn = await authenticate_await_completion().catch(handleError)
|
||||
loginModal.value.hide()
|
||||
loginDisabled.value = true
|
||||
const loggedIn = await login_flow().catch(handleSevereError)
|
||||
|
||||
if (loggedIn) {
|
||||
await setAccount(loggedIn)
|
||||
await refreshValues()
|
||||
}
|
||||
|
||||
loginModal.value.hide()
|
||||
mixpanel_track('AccountLogIn')
|
||||
trackEvent('AccountLogIn')
|
||||
loginDisabled.value = false
|
||||
}
|
||||
|
||||
const logout = async (id) => {
|
||||
@ -199,12 +201,12 @@ const logout = async (id) => {
|
||||
} else {
|
||||
emit('change')
|
||||
}
|
||||
mixpanel_track('AccountLogOut')
|
||||
trackEvent('AccountLogOut')
|
||||
}
|
||||
|
||||
let showCard = ref(false)
|
||||
let card = ref(null)
|
||||
let button = ref(null)
|
||||
const showCard = ref(false)
|
||||
const card = ref(null)
|
||||
const button = ref(null)
|
||||
const handleClickOutside = (event) => {
|
||||
const elements = document.elementsFromPoint(event.clientX, event.clientY)
|
||||
if (
|
||||
@ -213,7 +215,15 @@ const handleClickOutside = (event) => {
|
||||
!elements.includes(card.value.$el) &&
|
||||
!button.value.contains(event.target)
|
||||
) {
|
||||
toggleMenu(false)
|
||||
}
|
||||
}
|
||||
|
||||
function toggleMenu(override = true) {
|
||||
if (showCard.value || !override) {
|
||||
showCard.value = false
|
||||
} else {
|
||||
showCard.value = true
|
||||
}
|
||||
}
|
||||
|
||||
@ -264,11 +274,11 @@ onUnmounted(() => {
|
||||
}
|
||||
|
||||
.account-card {
|
||||
position: absolute;
|
||||
position: fixed;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
top: 0.5rem;
|
||||
left: 5.5rem;
|
||||
margin-top: 0.5rem;
|
||||
right: 2rem;
|
||||
z-index: 11;
|
||||
gap: 0.5rem;
|
||||
padding: 1rem;
|
||||
@ -343,12 +353,17 @@ onUnmounted(() => {
|
||||
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.3s ease;
|
||||
transition:
|
||||
opacity 0.25s ease,
|
||||
translate 0.25s ease,
|
||||
scale 0.25s ease;
|
||||
}
|
||||
|
||||
.fade-enter-from,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
translate: 0 -2rem;
|
||||
scale: 0.9;
|
||||
}
|
||||
|
||||
.avatar-button {
|
||||
@ -356,9 +371,10 @@ onUnmounted(() => {
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
color: var(--color-base);
|
||||
background-color: var(--color-raised-bg);
|
||||
background-color: var(--color-button-bg);
|
||||
border-radius: var(--radius-md);
|
||||
width: 100%;
|
||||
padding: 0.5rem 0.75rem;
|
||||
text-align: left;
|
||||
|
||||
&.expanded {
|
||||
60
apps/app-frontend/src/components/ui/AddContentButton.vue
Normal file
@ -0,0 +1,60 @@
|
||||
<script setup lang="ts">
|
||||
import { DropdownIcon, PlusIcon, FolderOpenIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled, OverflowMenu } from '@modrinth/ui'
|
||||
import { open } from '@tauri-apps/plugin-dialog'
|
||||
import { add_project_from_path } from '@/helpers/profile.js'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const props = defineProps({
|
||||
instance: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const handleAddContentFromFile = async () => {
|
||||
const newProject = await open({ multiple: true })
|
||||
if (!newProject) return
|
||||
|
||||
for (const project of newProject) {
|
||||
await add_project_from_path(props.instance.path, project.path ?? project).catch(handleError)
|
||||
}
|
||||
}
|
||||
|
||||
const handleSearchContent = async () => {
|
||||
await router.push({
|
||||
path: `/browse/${props.instance.loader === 'vanilla' ? 'resourcepack' : 'mod'}`,
|
||||
query: { i: props.instance.path },
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="joined-buttons">
|
||||
<ButtonStyled>
|
||||
<button @click="handleSearchContent">
|
||||
<PlusIcon />
|
||||
Install content
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled>
|
||||
<OverflowMenu
|
||||
:options="[
|
||||
{
|
||||
id: 'from_file',
|
||||
action: handleAddContentFromFile,
|
||||
},
|
||||
]"
|
||||
>
|
||||
<DropdownIcon />
|
||||
<template #from_file>
|
||||
<FolderOpenIcon />
|
||||
<span class="no-wrap"> Add from file </span>
|
||||
</template>
|
||||
</OverflowMenu>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</template>
|
||||
63
apps/app-frontend/src/components/ui/Breadcrumbs.vue
Normal file
@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<div data-tauri-drag-region class="flex items-center gap-1 pl-3">
|
||||
<Button v-if="false" class="breadcrumbs__back transparent" icon-only @click="$router.back()">
|
||||
<ChevronLeftIcon />
|
||||
</Button>
|
||||
<Button
|
||||
v-if="false"
|
||||
class="breadcrumbs__forward transparent"
|
||||
icon-only
|
||||
@click="$router.forward()"
|
||||
>
|
||||
<ChevronRightIcon />
|
||||
</Button>
|
||||
{{ breadcrumbData.resetToNames(breadcrumbs) }}
|
||||
<template v-for="breadcrumb in breadcrumbs" :key="breadcrumb.name">
|
||||
<router-link
|
||||
v-if="breadcrumb.link"
|
||||
:to="{
|
||||
path: breadcrumb.link.replace('{id}', encodeURIComponent($route.params.id)),
|
||||
query: breadcrumb.query,
|
||||
}"
|
||||
class="text-primary"
|
||||
>{{
|
||||
breadcrumb.name.charAt(0) === '?'
|
||||
? breadcrumbData.getName(breadcrumb.name.slice(1))
|
||||
: breadcrumb.name
|
||||
}}
|
||||
</router-link>
|
||||
<span
|
||||
v-else
|
||||
data-tauri-drag-region
|
||||
class="text-contrast font-semibold cursor-default select-none"
|
||||
>{{
|
||||
breadcrumb.name.charAt(0) === '?'
|
||||
? breadcrumbData.getName(breadcrumb.name.slice(1))
|
||||
: breadcrumb.name
|
||||
}}</span
|
||||
>
|
||||
<ChevronRightIcon v-if="breadcrumb.link" data-tauri-drag-region class="w-5 h-5" />
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ChevronRightIcon, ChevronLeftIcon } from '@modrinth/assets'
|
||||
import { Button } from '@modrinth/ui'
|
||||
import { useBreadcrumbs } from '@/store/breadcrumbs'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
const breadcrumbData = useBreadcrumbs()
|
||||
const breadcrumbs = computed(() => {
|
||||
const additionalContext =
|
||||
route.meta.useContext === true
|
||||
? breadcrumbData.context
|
||||
: route.meta.useRootContext === true
|
||||
? breadcrumbData.rootContext
|
||||
: null
|
||||
return additionalContext ? [additionalContext, ...route.meta.breadcrumb] : route.meta.breadcrumb
|
||||
})
|
||||
</script>
|
||||
@ -60,9 +60,9 @@ defineExpose({
|
||||
})
|
||||
|
||||
const isLinkedData = (item) => {
|
||||
if (item.instance != undefined && item.instance.metadata.linked_data) {
|
||||
if (item.instance != undefined && item.instance.linked_data) {
|
||||
return true
|
||||
} else if (item.metadata != undefined && item.metadata.linked_data) {
|
||||
} else if (item != undefined && item.linked_data) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
377
apps/app-frontend/src/components/ui/ErrorModal.vue
Normal file
@ -0,0 +1,377 @@
|
||||
<script setup>
|
||||
import {
|
||||
CheckIcon,
|
||||
DropdownIcon,
|
||||
XIcon,
|
||||
HammerIcon,
|
||||
LogInIcon,
|
||||
UpdatedIcon,
|
||||
CopyIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { ChatIcon } from '@/assets/icons'
|
||||
import { ButtonStyled, Collapsible } from '@modrinth/ui'
|
||||
import { ref, computed } from 'vue'
|
||||
import { login as login_flow, set_default_user } from '@/helpers/auth.js'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import { handleSevereError } from '@/store/error.js'
|
||||
import { cancel_directory_change } from '@/helpers/settings.ts'
|
||||
import { install } from '@/helpers/profile.js'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
|
||||
const errorModal = ref()
|
||||
const error = ref()
|
||||
const closable = ref(true)
|
||||
const errorCollapsed = ref(false)
|
||||
|
||||
const title = ref('An error occurred')
|
||||
const errorType = ref('unknown')
|
||||
const supportLink = ref('https://support.modrinth.com')
|
||||
const metadata = ref({})
|
||||
|
||||
defineExpose({
|
||||
async show(errorVal, context, canClose = true, source = null) {
|
||||
closable.value = canClose
|
||||
|
||||
if (errorVal.message && errorVal.message.includes('Minecraft authentication error:')) {
|
||||
title.value = 'Unable to sign in to Minecraft'
|
||||
errorType.value = 'minecraft_auth'
|
||||
supportLink.value =
|
||||
'https://support.modrinth.com/en/articles/9038231-minecraft-sign-in-issues'
|
||||
|
||||
if (
|
||||
errorVal.message.includes('existing connection was forcibly closed') ||
|
||||
errorVal.message.includes('error sending request for url')
|
||||
) {
|
||||
metadata.value.network = true
|
||||
}
|
||||
if (errorVal.message.includes('because the target machine actively refused it')) {
|
||||
metadata.value.hostsFile = true
|
||||
}
|
||||
} else if (errorVal.message && errorVal.message.includes('User is not logged in')) {
|
||||
title.value = 'Sign in to Minecraft'
|
||||
errorType.value = 'minecraft_sign_in'
|
||||
supportLink.value = 'https://support.modrinth.com'
|
||||
} else if (errorVal.message && errorVal.message.includes('Move directory error:')) {
|
||||
title.value = 'Could not change app directory'
|
||||
errorType.value = 'directory_move'
|
||||
supportLink.value = 'https://support.modrinth.com'
|
||||
|
||||
if (errorVal.message.includes('directory is not writeable')) {
|
||||
metadata.value.readOnly = true
|
||||
}
|
||||
|
||||
if (errorVal.message.includes('Not enough space')) {
|
||||
metadata.value.notEnoughSpace = true
|
||||
}
|
||||
} else if (errorVal.message && errorVal.message.includes('No loader version selected for')) {
|
||||
title.value = 'No loader selected'
|
||||
errorType.value = 'no_loader_version'
|
||||
supportLink.value = 'https://support.modrinth.com'
|
||||
metadata.value.profilePath = context.profilePath
|
||||
} else if (source === 'state_init') {
|
||||
title.value = 'Error initializing Modrinth App'
|
||||
errorType.value = 'state_init'
|
||||
supportLink.value = 'https://support.modrinth.com'
|
||||
} else {
|
||||
title.value = 'An error occurred'
|
||||
errorType.value = 'unknown'
|
||||
supportLink.value = 'https://support.modrinth.com'
|
||||
metadata.value = {}
|
||||
}
|
||||
|
||||
error.value = errorVal
|
||||
errorModal.value.show()
|
||||
},
|
||||
})
|
||||
|
||||
const loadingMinecraft = ref(false)
|
||||
async function loginMinecraft() {
|
||||
try {
|
||||
loadingMinecraft.value = true
|
||||
const loggedIn = await login_flow()
|
||||
|
||||
if (loggedIn) {
|
||||
await set_default_user(loggedIn.profile.id).catch(handleError)
|
||||
}
|
||||
|
||||
await trackEvent('AccountLogIn', { source: 'ErrorModal' })
|
||||
loadingMinecraft.value = false
|
||||
errorModal.value.hide()
|
||||
} catch (err) {
|
||||
loadingMinecraft.value = false
|
||||
handleSevereError(err)
|
||||
}
|
||||
}
|
||||
|
||||
async function cancelDirectoryChange() {
|
||||
try {
|
||||
await cancel_directory_change()
|
||||
window.location.reload()
|
||||
} catch (err) {
|
||||
handleError(err)
|
||||
}
|
||||
}
|
||||
|
||||
function retryDirectoryChange() {
|
||||
window.location.reload()
|
||||
}
|
||||
|
||||
const loadingRepair = ref(false)
|
||||
async function repairInstance() {
|
||||
loadingRepair.value = true
|
||||
try {
|
||||
await install(metadata.value.profilePath, false)
|
||||
errorModal.value.hide()
|
||||
} catch (err) {
|
||||
handleSevereError(err)
|
||||
}
|
||||
loadingRepair.value = false
|
||||
}
|
||||
|
||||
const hasDebugInfo = computed(
|
||||
() =>
|
||||
errorType.value === 'directory_move' ||
|
||||
errorType.value === 'minecraft_auth' ||
|
||||
errorType.value === 'state_init' ||
|
||||
errorType.value === 'no_loader_version',
|
||||
)
|
||||
|
||||
const debugInfo = computed(() => error.value.message ?? error.value ?? 'No error message.')
|
||||
|
||||
const copied = ref(false)
|
||||
|
||||
async function copyToClipboard(text) {
|
||||
await navigator.clipboard.writeText(text)
|
||||
copied.value = true
|
||||
setTimeout(() => {
|
||||
copied.value = false
|
||||
}, 3000)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ModalWrapper ref="errorModal" :header="title" :closable="closable">
|
||||
<div class="modal-body">
|
||||
<div class="markdown-body">
|
||||
<template v-if="errorType === 'minecraft_auth'">
|
||||
<template v-if="metadata.network">
|
||||
<h3>Network issues</h3>
|
||||
<p>
|
||||
It looks like there were issues with the Modrinth App connecting to Microsoft's
|
||||
servers. This is often the result of a poor connection, so we recommend trying again
|
||||
to see if it works. If issues continue to persist, follow the steps in
|
||||
<a
|
||||
href="https://support.modrinth.com/en/articles/9038231-minecraft-sign-in-issues#h_e71a5f805f"
|
||||
>
|
||||
our support article
|
||||
</a>
|
||||
to troubleshoot.
|
||||
</p>
|
||||
</template>
|
||||
<template v-else-if="metadata.hostsFile">
|
||||
<h3>Network issues</h3>
|
||||
<p>
|
||||
The Modrinth App tried to connect to Microsoft / Xbox / Minecraft services, but the
|
||||
remote server rejected the connection. This may indicate that these services are
|
||||
blocked by the hosts file. Please visit
|
||||
<a
|
||||
href="https://support.modrinth.com/en/articles/9038231-minecraft-sign-in-issues#h_d694a29256"
|
||||
>
|
||||
our support article
|
||||
</a>
|
||||
for steps on how to fix the issue.
|
||||
</p>
|
||||
</template>
|
||||
<template v-else>
|
||||
<h3>Try another Microsoft account</h3>
|
||||
<p>
|
||||
Double check you've signed in with the right account. You may own Minecraft on a
|
||||
different Microsoft account.
|
||||
</p>
|
||||
<div class="cta-button">
|
||||
<button class="btn btn-primary" :disabled="loadingMinecraft" @click="loginMinecraft">
|
||||
<LogInIcon /> Try another account
|
||||
</button>
|
||||
</div>
|
||||
<h3>Using PC Game Pass, coming from Bedrock, or just bought the game?</h3>
|
||||
<p>
|
||||
Try signing in with the
|
||||
<a href="https://www.minecraft.net/en-us/download">official Minecraft Launcher</a>
|
||||
first. Once you're done, come back here and sign in!
|
||||
</p>
|
||||
</template>
|
||||
<div class="cta-button">
|
||||
<button class="btn btn-primary" :disabled="loadingMinecraft" @click="loginMinecraft">
|
||||
<LogInIcon /> Try signing in again
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="errorType === 'directory_move'">
|
||||
<template v-if="metadata.readOnly">
|
||||
<h3>Change directory permissions</h3>
|
||||
<p>
|
||||
It looks like the Modrinth App is unable to write to the directory you selected.
|
||||
Please adjust the permissions of the directory and try again or cancel the directory
|
||||
change.
|
||||
</p>
|
||||
</template>
|
||||
<template v-else-if="metadata.notEnoughSpace">
|
||||
<h3>Not enough space</h3>
|
||||
<p>
|
||||
It looks like there is not enough space on the disk containing the directory you
|
||||
selected. Please free up some space and try again or cancel the directory change.
|
||||
</p>
|
||||
</template>
|
||||
<template v-else>
|
||||
<p>
|
||||
The Modrinth App is unable to migrate to the new directory you selected. Please
|
||||
contact support for help or cancel the directory change.
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<div class="cta-button">
|
||||
<button class="btn" @click="retryDirectoryChange">
|
||||
<UpdatedIcon /> Retry directory change
|
||||
</button>
|
||||
<button class="btn btn-danger" @click="cancelDirectoryChange">
|
||||
<XIcon /> Cancel directory change
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
<div v-else-if="errorType === 'minecraft_sign_in'">
|
||||
<p>
|
||||
To play this instance, you must sign in through Microsoft below. If you don't have a
|
||||
Minecraft account, you can purchase the game on the
|
||||
<a href="https://www.minecraft.net/en-us/store/minecraft-java-bedrock-edition-pc"
|
||||
>Minecraft website</a
|
||||
>.
|
||||
</p>
|
||||
<div class="cta-button">
|
||||
<button class="btn btn-primary" :disabled="loadingMinecraft" @click="loginMinecraft">
|
||||
<LogInIcon /> Sign in to Minecraft
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<template v-else-if="errorType === 'state_init'">
|
||||
<p>
|
||||
Modrinth App failed to load correctly. This may be because of a corrupted file, or
|
||||
because the app is missing crucial files.
|
||||
</p>
|
||||
<p>You may be able to fix it through one of the following ways:</p>
|
||||
<ul>
|
||||
<li>Ensuring you are connected to the internet, then try restarting the app.</li>
|
||||
<li>Redownloading the app.</li>
|
||||
</ul>
|
||||
</template>
|
||||
<template v-else-if="errorType === 'no_loader_version'">
|
||||
<p>The Modrinth App failed to find the loader version for this instance.</p>
|
||||
<p>To resolve this, you need to repair the instance. Click the button below to do so.</p>
|
||||
<div class="cta-button">
|
||||
<button class="btn btn-primary" :disabled="loadingRepair" @click="repairInstance">
|
||||
<HammerIcon /> Repair instance
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ debugInfo }}
|
||||
</template>
|
||||
<template v-if="hasDebugInfo">
|
||||
<hr />
|
||||
<p>
|
||||
If nothing is working and you need help, visit
|
||||
<a :href="supportLink">our support page</a>
|
||||
and start a chat using the widget in the bottom right and we will be more than happy to
|
||||
assist! Make sure to provide the following debug information to the agent:
|
||||
</p>
|
||||
</template>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<ButtonStyled>
|
||||
<a :href="supportLink" @click="errorModal.hide()"><ChatIcon /> Get support</a>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled v-if="closable">
|
||||
<button @click="errorModal.hide()"><XIcon /> Close</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled v-if="hasDebugInfo">
|
||||
<button :disabled="copied" @click="copyToClipboard(debugInfo)">
|
||||
<template v-if="copied"> <CheckIcon class="text-green" /> Copied! </template>
|
||||
<template v-else> <CopyIcon /> Copy debug info </template>
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
<template v-if="hasDebugInfo">
|
||||
<div class="bg-button-bg rounded-xl mt-2 overflow-clip">
|
||||
<button
|
||||
class="flex items-center justify-between w-full bg-transparent border-0 px-4 py-3 cursor-pointer"
|
||||
@click="errorCollapsed = !errorCollapsed"
|
||||
>
|
||||
<span class="text-contrast font-extrabold m-0">Debug information:</span>
|
||||
<DropdownIcon
|
||||
class="h-5 w-5 text-secondary transition-transform"
|
||||
:class="{ 'rotate-180': !errorCollapsed }"
|
||||
/>
|
||||
</button>
|
||||
<Collapsible :collapsed="errorCollapsed">
|
||||
<pre class="m-0 px-4 py-3 bg-bg rounded-none">{{ debugInfo }}</pre>
|
||||
</Collapsible>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</ModalWrapper>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.light-mode {
|
||||
--color-orange-bg: rgba(255, 163, 71, 0.2);
|
||||
}
|
||||
|
||||
.dark-mode,
|
||||
.oled-mode {
|
||||
--color-orange-bg: rgba(224, 131, 37, 0.2);
|
||||
}
|
||||
</style>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.cta-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.5rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.warning-banner {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
padding: var(--gap-lg);
|
||||
background-color: var(--color-orange-bg);
|
||||
border: 2px solid var(--color-orange);
|
||||
border-radius: var(--radius-md);
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.warning-banner__title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
font-weight: 700;
|
||||
|
||||
svg {
|
||||
color: var(--color-orange);
|
||||
height: 1.5rem;
|
||||
width: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--gap-md);
|
||||
}
|
||||
|
||||
.markdown-body {
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
@ -1,11 +1,12 @@
|
||||
<script setup>
|
||||
import { Button, Checkbox, Modal, XIcon, PlusIcon } from 'omorphia'
|
||||
import { XIcon, PlusIcon } from '@modrinth/assets'
|
||||
import { Button, Checkbox } from '@modrinth/ui'
|
||||
import { PackageIcon, VersionIcon } from '@/assets/icons'
|
||||
import { ref } from 'vue'
|
||||
import { export_profile_mrpack, get_pack_export_candidates } from '@/helpers/profile.js'
|
||||
import { open } from '@tauri-apps/api/dialog'
|
||||
import { open } from '@tauri-apps/plugin-dialog'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import { useTheming } from '@/store/theme'
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
|
||||
const props = defineProps({
|
||||
instance: {
|
||||
@ -22,15 +23,13 @@ defineExpose({
|
||||
})
|
||||
|
||||
const exportModal = ref(null)
|
||||
const nameInput = ref(props.instance.metadata.name)
|
||||
const nameInput = ref(props.instance.name)
|
||||
const exportDescription = ref('')
|
||||
const versionInput = ref('1.0.0')
|
||||
const files = ref([])
|
||||
const folders = ref([])
|
||||
const showingFiles = ref(false)
|
||||
|
||||
const themeStore = useTheming()
|
||||
|
||||
const initFiles = async () => {
|
||||
const newFolders = new Map()
|
||||
const sep = '/'
|
||||
@ -49,9 +48,9 @@ const initFiles = async () => {
|
||||
disabled:
|
||||
folder === 'profile.json' ||
|
||||
folder.startsWith('modrinth_logs') ||
|
||||
folder.startsWith('.fabric') ||
|
||||
folder.includes('.DS_Store'),
|
||||
folder.startsWith('.fabric'),
|
||||
}))
|
||||
.filter((pathData) => !pathData.path.includes('.DS_Store'))
|
||||
.forEach((pathData) => {
|
||||
const parent = pathData.path.split(sep).slice(0, -1).join(sep)
|
||||
if (parent !== '') {
|
||||
@ -63,7 +62,7 @@ const initFiles = async () => {
|
||||
} else {
|
||||
files.value.push(pathData)
|
||||
}
|
||||
})
|
||||
}),
|
||||
)
|
||||
folders.value = [...newFolders.entries()].map(([name, value]) => [
|
||||
{
|
||||
@ -97,7 +96,7 @@ const exportPack = async () => {
|
||||
filesToExport,
|
||||
versionInput.value,
|
||||
exportDescription.value,
|
||||
nameInput.value
|
||||
nameInput.value,
|
||||
).catch((err) => handleError(err))
|
||||
exportModal.value.hide()
|
||||
}
|
||||
@ -105,14 +104,14 @@ const exportPack = async () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal ref="exportModal" header="Export modpack" :noblur="!themeStore.advancedRendering">
|
||||
<ModalWrapper ref="exportModal" header="Export modpack">
|
||||
<div class="modal-body">
|
||||
<div class="labeled_input">
|
||||
<p>Modpack Name</p>
|
||||
<div class="iconified-input">
|
||||
<PackageIcon />
|
||||
<input v-model="nameInput" type="text" placeholder="Modpack name" class="input" />
|
||||
<Button @click="nameInput = ''">
|
||||
<Button class="r-btn" @click="nameInput = ''">
|
||||
<XIcon />
|
||||
</Button>
|
||||
</div>
|
||||
@ -122,7 +121,7 @@ const exportPack = async () => {
|
||||
<div class="iconified-input">
|
||||
<VersionIcon />
|
||||
<input v-model="versionInput" type="text" placeholder="1.0.0" class="input" />
|
||||
<Button @click="versionInput = ''">
|
||||
<Button class="r-btn" @click="versionInput = ''">
|
||||
<XIcon />
|
||||
</Button>
|
||||
</div>
|
||||
@ -152,7 +151,7 @@ const exportPack = async () => {
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="showingFiles" class="table-content">
|
||||
<div v-for="[path, children] of folders" :key="path.name" class="table-row">
|
||||
<div v-for="[path, children] in folders" :key="path.name" class="table-row">
|
||||
<div class="table-cell file-entry">
|
||||
<div class="file-primary">
|
||||
<Checkbox
|
||||
@ -207,12 +206,11 @@ const exportPack = async () => {
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</ModalWrapper>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.modal-body {
|
||||
padding: var(--gap-xl);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--gap-md);
|
||||
@ -287,6 +285,7 @@ const exportPack = async () => {
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.textarea-wrapper {
|
||||
249
apps/app-frontend/src/components/ui/Instance.vue
Normal file
@ -0,0 +1,249 @@
|
||||
<script setup>
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import {
|
||||
DownloadIcon,
|
||||
GameIcon,
|
||||
PlayIcon,
|
||||
SpinnerIcon,
|
||||
StopCircleIcon,
|
||||
TimerIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { Avatar, ButtonStyled, useRelativeTime } from '@modrinth/ui'
|
||||
import { convertFileSrc } from '@tauri-apps/api/core'
|
||||
import { finish_install, kill, run } from '@/helpers/profile'
|
||||
import { get_by_profile_path } from '@/helpers/process'
|
||||
import { process_listener } from '@/helpers/events'
|
||||
import { handleError } from '@/store/state.js'
|
||||
import { showProfileInFolder } from '@/helpers/utils.js'
|
||||
import { handleSevereError } from '@/store/error.js'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
const formatRelativeTime = useRelativeTime()
|
||||
|
||||
const props = defineProps({
|
||||
instance: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {}
|
||||
},
|
||||
},
|
||||
compact: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
first: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
})
|
||||
|
||||
const playing = ref(false)
|
||||
const loading = ref(false)
|
||||
const modLoading = computed(
|
||||
() =>
|
||||
loading.value ||
|
||||
currentEvent.value === 'installing' ||
|
||||
(currentEvent.value === 'launched' && !playing.value),
|
||||
)
|
||||
const installing = computed(() => props.instance.install_stage.includes('installing'))
|
||||
const installed = computed(() => props.instance.install_stage === 'installed')
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const seeInstance = async () => {
|
||||
await router.push(`/instance/${encodeURIComponent(props.instance.path)}`)
|
||||
}
|
||||
|
||||
const checkProcess = async () => {
|
||||
const runningProcesses = await get_by_profile_path(props.instance.path).catch(handleError)
|
||||
|
||||
playing.value = runningProcesses.length > 0
|
||||
}
|
||||
|
||||
const play = async (e, context) => {
|
||||
e?.stopPropagation()
|
||||
loading.value = true
|
||||
await run(props.instance.path)
|
||||
.catch((err) => handleSevereError(err, { profilePath: props.instance.path }))
|
||||
.finally(() => {
|
||||
trackEvent('InstancePlay', {
|
||||
loader: props.instance.loader,
|
||||
game_version: props.instance.game_version,
|
||||
source: context,
|
||||
})
|
||||
})
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
const stop = async (e, context) => {
|
||||
e?.stopPropagation()
|
||||
playing.value = false
|
||||
|
||||
await kill(props.instance.path).catch(handleError)
|
||||
|
||||
trackEvent('InstanceStop', {
|
||||
loader: props.instance.loader,
|
||||
game_version: props.instance.game_version,
|
||||
source: context,
|
||||
})
|
||||
}
|
||||
|
||||
const repair = async (e) => {
|
||||
e?.stopPropagation()
|
||||
|
||||
await finish_install(props.instance)
|
||||
}
|
||||
|
||||
const openFolder = async () => {
|
||||
await showProfileInFolder(props.instance.path)
|
||||
}
|
||||
|
||||
const addContent = async () => {
|
||||
await router.push({
|
||||
path: `/browse/${props.instance.loader === 'vanilla' ? 'datapack' : 'mod'}`,
|
||||
query: { i: props.instance.path },
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
play,
|
||||
stop,
|
||||
seeInstance,
|
||||
openFolder,
|
||||
addContent,
|
||||
instance: props.instance,
|
||||
})
|
||||
|
||||
const currentEvent = ref(null)
|
||||
|
||||
const unlisten = await process_listener((e) => {
|
||||
if (e.profile_path_id === props.instance.path) {
|
||||
currentEvent.value = e.event
|
||||
if (e.event === 'finished') {
|
||||
playing.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => checkProcess())
|
||||
onUnmounted(() => unlisten())
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<template v-if="compact">
|
||||
<div
|
||||
class="card-shadow grid grid-cols-[auto_1fr_auto] bg-bg-raised rounded-xl p-3 pl-4 gap-2 cursor-pointer hover:brightness-90 transition-all"
|
||||
@click="seeInstance"
|
||||
@mouseenter="checkProcess"
|
||||
>
|
||||
<Avatar
|
||||
size="48px"
|
||||
:src="instance.icon_path ? convertFileSrc(instance.icon_path) : null"
|
||||
:tint-by="instance.path"
|
||||
alt="Mod card"
|
||||
/>
|
||||
<div class="h-full flex items-center font-bold text-contrast leading-normal">
|
||||
<span class="line-clamp-2">{{ instance.name }}</span>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<ButtonStyled v-if="playing" color="red" circular @mousehover="checkProcess">
|
||||
<button v-tooltip="'Stop'" @click="(e) => stop(e, 'InstanceCard')">
|
||||
<StopCircleIcon />
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled v-else-if="modLoading" color="standard" circular>
|
||||
<button v-tooltip="'Instance is loading...'" disabled>
|
||||
<SpinnerIcon class="animate-spin" />
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled v-else :color="first ? 'brand' : 'standard'" circular>
|
||||
<button
|
||||
v-tooltip="'Play'"
|
||||
@click="(e) => play(e, 'InstanceCard')"
|
||||
@mousehover="checkProcess"
|
||||
>
|
||||
<!-- Translate for optical centering -->
|
||||
<PlayIcon class="translate-x-[1px]" />
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
<div class="flex items-center col-span-3 gap-1 text-secondary font-semibold">
|
||||
<TimerIcon />
|
||||
<span class="text-sm">
|
||||
<template v-if="instance.last_played">
|
||||
Played {{ formatRelativeTime(dayjs(instance.last_played).toISOString()) }}
|
||||
</template>
|
||||
<template v-else> Never played </template>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div v-else>
|
||||
<div
|
||||
class="button-base bg-bg-raised p-4 rounded-xl flex gap-3 group"
|
||||
@click="seeInstance"
|
||||
@mouseenter="checkProcess"
|
||||
>
|
||||
<div class="relative flex items-center justify-center">
|
||||
<Avatar
|
||||
size="48px"
|
||||
:src="instance.icon_path ? convertFileSrc(instance.icon_path) : null"
|
||||
:tint-by="instance.path"
|
||||
alt="Mod card"
|
||||
:class="`transition-all ${modLoading || installing ? `brightness-[0.25] scale-[0.85]` : `group-hover:brightness-75`}`"
|
||||
/>
|
||||
<div class="absolute inset-0 flex items-center justify-center">
|
||||
<ButtonStyled v-if="playing" size="large" color="red" circular>
|
||||
<button
|
||||
v-tooltip="'Stop'"
|
||||
:class="{ 'scale-100 opacity-100': playing }"
|
||||
class="transition-all scale-75 origin-bottom opacity-0 card-shadow"
|
||||
@click="(e) => stop(e, 'InstanceCard')"
|
||||
@mousehover="checkProcess"
|
||||
>
|
||||
<StopCircleIcon />
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<SpinnerIcon
|
||||
v-else-if="modLoading || installing"
|
||||
v-tooltip="modLoading ? 'Instance is loading...' : 'Installing...'"
|
||||
class="animate-spin w-8 h-8"
|
||||
tabindex="-1"
|
||||
/>
|
||||
<ButtonStyled v-else-if="!installed" size="large" color="brand" circular>
|
||||
<button
|
||||
v-tooltip="'Repair'"
|
||||
class="transition-all scale-75 group-hover:scale-100 group-focus-within:scale-100 origin-bottom opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 card-shadow"
|
||||
@click="(e) => repair(e)"
|
||||
>
|
||||
<DownloadIcon />
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled v-else size="large" color="brand" circular>
|
||||
<button
|
||||
v-tooltip="'Play'"
|
||||
class="transition-all scale-75 group-hover:scale-100 group-focus-within:scale-100 origin-bottom opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 card-shadow"
|
||||
@click="(e) => play(e, 'InstanceCard')"
|
||||
@mousehover="checkProcess"
|
||||
>
|
||||
<PlayIcon class="translate-x-[2px]" />
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1">
|
||||
<p class="m-0 text-md font-bold text-contrast leading-tight line-clamp-1">
|
||||
{{ instance.name }}
|
||||
</p>
|
||||
<div class="flex items-center col-span-3 gap-1 text-secondary font-semibold mt-auto">
|
||||
<GameIcon class="shrink-0" />
|
||||
<span class="text-sm capitalize">
|
||||
{{ instance.loader }} {{ instance.game_version }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<Modal ref="modal" header="Create instance" :noblur="!themeStore.advancedRendering">
|
||||
<ModalWrapper ref="modal" header="Creating an instance">
|
||||
<div class="modal-header">
|
||||
<Chips v-model="creationType" :items="['custom', 'from file', 'import from launcher']" />
|
||||
</div>
|
||||
@ -110,7 +110,7 @@
|
||||
placeholder="Path to launcher"
|
||||
@change="setPath"
|
||||
/>
|
||||
<Button @click="() => (selectedLauncherPath = '')">
|
||||
<Button class="r-btn" @click="() => (selectedLauncherPath = '')">
|
||||
<XIcon />
|
||||
</Button>
|
||||
</div>
|
||||
@ -177,14 +177,14 @@
|
||||
loading
|
||||
? 'Importing...'
|
||||
: Array.from(profiles.values())
|
||||
.flatMap((e) => e)
|
||||
.some((e) => e.selected)
|
||||
? `Import ${
|
||||
Array.from(profiles.values())
|
||||
.flatMap((e) => e)
|
||||
.filter((e) => e.selected).length
|
||||
} profiles`
|
||||
: 'Select profiles to import'
|
||||
.some((e) => e.selected)
|
||||
? `Import ${
|
||||
Array.from(profiles.values())
|
||||
.flatMap((e) => e)
|
||||
.filter((e) => e.selected).length
|
||||
} profiles`
|
||||
: 'Select profiles to import'
|
||||
}}
|
||||
</Button>
|
||||
<ProgressBar
|
||||
@ -193,51 +193,39 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</ModalWrapper>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import {
|
||||
Avatar,
|
||||
Button,
|
||||
Chips,
|
||||
Modal,
|
||||
CodeIcon,
|
||||
FolderOpenIcon,
|
||||
FolderSearchIcon,
|
||||
InfoIcon,
|
||||
PlusIcon,
|
||||
UpdatedIcon,
|
||||
UploadIcon,
|
||||
XIcon,
|
||||
CodeIcon,
|
||||
Checkbox,
|
||||
FolderOpenIcon,
|
||||
InfoIcon,
|
||||
FolderSearchIcon,
|
||||
UpdatedIcon,
|
||||
} from 'omorphia'
|
||||
} from '@modrinth/assets'
|
||||
import { Avatar, Button, Checkbox, Chips } from '@modrinth/ui'
|
||||
import { computed, onUnmounted, ref, shallowRef } from 'vue'
|
||||
import { get_loaders } from '@/helpers/tags'
|
||||
import { create } from '@/helpers/profile'
|
||||
import { open } from '@tauri-apps/api/dialog'
|
||||
import { tauri } from '@tauri-apps/api'
|
||||
import {
|
||||
get_game_versions,
|
||||
get_fabric_versions,
|
||||
get_forge_versions,
|
||||
get_quilt_versions,
|
||||
get_neoforge_versions,
|
||||
} from '@/helpers/metadata'
|
||||
import { open } from '@tauri-apps/plugin-dialog'
|
||||
import { convertFileSrc } from '@tauri-apps/api/core'
|
||||
import { get_game_versions, get_loader_versions } from '@/helpers/metadata'
|
||||
import { handleError } from '@/store/notifications.js'
|
||||
import Multiselect from 'vue-multiselect'
|
||||
import { mixpanel_track } from '@/helpers/mixpanel'
|
||||
import { useTheming } from '@/store/state.js'
|
||||
import { listen } from '@tauri-apps/api/event'
|
||||
import { install_from_file } from '@/helpers/pack.js'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { create_profile_and_install_from_file } from '@/helpers/pack.js'
|
||||
import {
|
||||
get_default_launcher_path,
|
||||
get_importable_instances,
|
||||
import_instance,
|
||||
} from '@/helpers/import.js'
|
||||
import ProgressBar from '@/components/ui/ProgressBar.vue'
|
||||
|
||||
const themeStore = useTheming()
|
||||
import { getCurrentWebview } from '@tauri-apps/api/webview'
|
||||
|
||||
const profile_name = ref('')
|
||||
const game_version = ref('')
|
||||
@ -249,7 +237,7 @@ const display_icon = ref(null)
|
||||
const showAdvanced = ref(false)
|
||||
const creating = ref(false)
|
||||
const showSnapshots = ref(false)
|
||||
const creationType = ref('from file')
|
||||
const creationType = ref('custom')
|
||||
const isShowing = ref(false)
|
||||
|
||||
defineExpose({
|
||||
@ -267,20 +255,22 @@ defineExpose({
|
||||
isShowing.value = true
|
||||
modal.value.show()
|
||||
|
||||
unlistener.value = await listen('tauri://file-drop', async (event) => {
|
||||
unlistener.value = await getCurrentWebview().onDragDropEvent(async (event) => {
|
||||
// Only if modal is showing
|
||||
if (!isShowing.value) return
|
||||
if (event.payload.type !== 'drop') return
|
||||
if (creationType.value !== 'from file') return
|
||||
hide()
|
||||
if (event.payload && event.payload.length > 0 && event.payload[0].endsWith('.mrpack')) {
|
||||
await install_from_file(event.payload[0]).catch(handleError)
|
||||
mixpanel_track('InstanceCreate', {
|
||||
const { paths } = event.payload
|
||||
if (paths && paths.length > 0 && paths[0].endsWith('.mrpack')) {
|
||||
await create_profile_and_install_from_file(paths[0]).catch(handleError)
|
||||
trackEvent('InstanceCreate', {
|
||||
source: 'CreationModalFileDrop',
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
mixpanel_track('InstanceCreateStart', { source: 'CreationModal' })
|
||||
trackEvent('InstanceCreateStart', { source: 'CreationModal' })
|
||||
},
|
||||
})
|
||||
|
||||
@ -308,19 +298,23 @@ const [
|
||||
all_game_versions,
|
||||
loaders,
|
||||
] = await Promise.all([
|
||||
get_fabric_versions().then(shallowRef).catch(handleError),
|
||||
get_forge_versions().then(shallowRef).catch(handleError),
|
||||
get_quilt_versions().then(shallowRef).catch(handleError),
|
||||
get_neoforge_versions().then(shallowRef).catch(handleError),
|
||||
get_loader_versions('fabric').then(shallowRef).catch(handleError),
|
||||
get_loader_versions('forge').then(shallowRef).catch(handleError),
|
||||
get_loader_versions('quilt').then(shallowRef).catch(handleError),
|
||||
get_loader_versions('neo').then(shallowRef).catch(handleError),
|
||||
get_game_versions().then(shallowRef).catch(handleError),
|
||||
get_loaders()
|
||||
.then((value) =>
|
||||
value
|
||||
.filter((item) => item.supported_project_types.includes('modpack'))
|
||||
.map((item) => item.name.toLowerCase())
|
||||
ref(
|
||||
value
|
||||
.filter((item) => item.supported_project_types.includes('modpack'))
|
||||
.map((item) => item.name.toLowerCase()),
|
||||
),
|
||||
)
|
||||
.then(ref)
|
||||
.catch(handleError),
|
||||
.catch((err) => {
|
||||
handleError(err)
|
||||
return ref([])
|
||||
}),
|
||||
])
|
||||
loaders.value.unshift('vanilla')
|
||||
|
||||
@ -367,10 +361,10 @@ const create_instance = async () => {
|
||||
game_version.value,
|
||||
loader.value,
|
||||
loader.value === 'vanilla' ? null : loader_version_value ?? 'stable',
|
||||
icon.value
|
||||
icon.value,
|
||||
).catch(handleError)
|
||||
|
||||
mixpanel_track('InstanceCreate', {
|
||||
trackEvent('InstanceCreate', {
|
||||
profile_name: profile_name.value,
|
||||
game_version: game_version.value,
|
||||
loader: loader.value,
|
||||
@ -381,7 +375,7 @@ const create_instance = async () => {
|
||||
}
|
||||
|
||||
const upload_icon = async () => {
|
||||
icon.value = await open({
|
||||
const res = await open({
|
||||
multiple: false,
|
||||
filters: [
|
||||
{
|
||||
@ -391,8 +385,10 @@ const upload_icon = async () => {
|
||||
],
|
||||
})
|
||||
|
||||
icon.value = res.path ?? res
|
||||
|
||||
if (!icon.value) return
|
||||
display_icon.value = tauri.convertFileSrc(icon.value)
|
||||
display_icon.value = convertFileSrc(icon.value)
|
||||
}
|
||||
|
||||
const reset_icon = () => {
|
||||
@ -427,9 +423,9 @@ const openFile = async () => {
|
||||
const newProject = await open({ multiple: false })
|
||||
if (!newProject) return
|
||||
hide()
|
||||
await install_from_file(newProject).catch(handleError)
|
||||
await create_profile_and_install_from_file(newProject.path ?? newProject).catch(handleError)
|
||||
|
||||
mixpanel_track('InstanceCreate', {
|
||||
trackEvent('InstanceCreate', {
|
||||
source: 'CreationModalFileOpen',
|
||||
})
|
||||
}
|
||||
@ -441,7 +437,7 @@ const profiles = ref(
|
||||
['ATLauncher', []],
|
||||
['Curseforge', []],
|
||||
['PrismLauncher', []],
|
||||
])
|
||||
]),
|
||||
)
|
||||
|
||||
const loading = ref(false)
|
||||
@ -470,9 +466,9 @@ const promises = profileOptions.value.map(async (option) => {
|
||||
profileOptions.value.find((profile) => profile.name === option.name).path = path
|
||||
profiles.value.set(
|
||||
option.name,
|
||||
instances.map((name) => ({ name, selected: false }))
|
||||
instances.map((name) => ({ name, selected: false })),
|
||||
)
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Allow failure silently
|
||||
}
|
||||
})
|
||||
@ -489,12 +485,12 @@ const selectLauncherPath = async () => {
|
||||
const reload = async () => {
|
||||
const instances = await get_importable_instances(
|
||||
selectedProfileType.value.name,
|
||||
selectedProfileType.value.path
|
||||
selectedProfileType.value.path,
|
||||
).catch(handleError)
|
||||
if (instances) {
|
||||
profiles.value.set(
|
||||
selectedProfileType.value.name,
|
||||
instances.map((name) => ({ name, selected: false }))
|
||||
instances.map((name) => ({ name, selected: false })),
|
||||
)
|
||||
} else {
|
||||
profiles.value.set(selectedProfileType.value.name, [])
|
||||
@ -533,8 +529,8 @@ const next = async () => {
|
||||
.modal-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: var(--gap-lg);
|
||||
gap: var(--gap-md);
|
||||
margin-top: var(--gap-lg);
|
||||
}
|
||||
|
||||
.input-label {
|
||||
@ -603,7 +599,6 @@ const next = async () => {
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: var(--gap-lg);
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||